Finding the instance reference of an object

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Aaron Brady

    Re: Finding the instance reference of an object

    On Nov 4, 5:02 pm, Joe Strout <j...@strout.ne twrote:
    On Nov 4, 2008, at 3:42 PM, Steven D'Aprano wrote:
    When we're talking about the value of a variable in Python, why on  
    earth
    would you drag entities that do not exist in Python into the  
    discussion?
    >
    I don't, but others do, for example bringing up C structs or C++  
    objects on the stack, which don't exist in Python (Python objects live  
    on the heap, and all you have on the stack are references to them; the  
    I actually saw an implementation of Python once that did not have
    references-to-objects on its stack. It kept them on the heap, and
    kept references to those containers in another container. The second
    container was a global variable, so that was on the stack at least.
    This strongly seems to interfere with your analogy to C++'s c-b-v
    mode.

    On the other hand, you could say that VB.NET's c-b-v mode is not true
    to C++'s c-b-v mode, in which case lots of people will just side with C
    ++.

    Comment

    • Marc 'BlackJack' Rintsch

      Re: Finding the instance reference of an object

      On Tue, 04 Nov 2008 16:02:29 -0700, Joe Strout wrote:
      On Nov 4, 2008, at 3:42 PM, Steven D'Aprano wrote:
      >
      >>This example is also call-by-value, but the value in this case is a
      >>type
      >>that has no analog in Python.
      >>
      >I'm disappointed to see that my prediction that Joe would, yet again,
      >utterly ignore all the arguments against his pet theory was correct.
      >
      I'm not doing that, but the folks on the other side are. (Well, I don't
      know if you are in particular, as I've been deleting your messages to
      save my blood pressure... this one caught my eye though, alas.)
      Yeah, we are all wrong and you are right. Because you say so and ignore
      messages that might have facts that are not good for your blood
      pressure. Very convincing.
      For example: we have arguments that you can "modify" a parameter passed
      to a function in Python. These ignore the fact that you can only use
      (dereference) that parameter to modify something else, no different from
      a pointer passed by-value in C/C++.
      But we have no pointers in Python. "Pointer" is a data type in C and C++
      but Python, the language, has no such type.
      It boils down to this: Python's behavior is demonstrably the same as any
      other modern OOP language, INCLUDING those that have both by- reference
      and by-value parameter modes, except that in Python (as well as Java),
      only the by-value mode is available.
      Guess what, I find call-by-value in Java for objects the wrong term too.
      Same reason: Java has no pointer or reference as data type.
      >When we're talking about the value of a variable in Python, why on
      >earth would you drag entities that do not exist in Python into the
      >discussion?
      >
      I don't, but others do, […]
      You have said the value that is copied is a pointer to the object. So
      the value in your call-by-value is something that doesn't exist in the
      Python language.
      I know you really want Python to be unique and special -- and it is, in
      many ways, but this isn't one of them. Python is an OOP language whose
      variables contain references to objects, and where such references are
      passed (by value) to methods, just like Java, and like the default
      parameter mode in VB.NET, REALbasic, and C++ (though those languages
      also offer a by-reference mode that Python and Java do not).
      That's just because you seem to insist that a "variable" is a name for a
      memory location. A variable brings together name, type, memory location,
      and a value, and in Python type and memory location are attached to the
      value and not the name, like in C++ for example.
      Your continued attempts to obfuscate this simple behavior does no credit
      to you or Python.
      I think explaining that the object is shared, or given another name
      locally, is much simpler than to explain the underlying machinery two
      levels below (because the CPython-VM doesn't know pointers either).
      Maybe not for people who know that low levels from older languages and
      insist on explaining everything in the terms of those. Maybe that's the
      reason for the Java folks to call their strategy call-by-value, because
      they were afraid to confuse C++ programmers with "new" concepts.

      Ciao,
      Marc 'BlackJack' Rintsch

      Comment

      • George Sakkis

        Re: Finding the instance reference of an object

        On Nov 4, 6:02 pm, Joe Strout <j...@strout.ne twrote:
        I know you really want Python to be unique and special -- and it is,  
        in many ways, but this isn't one of them.  Python is an OOP language  
        whose variables contain references to objects, and where such  
        references are passed (by value) to methods, just likeJava, and like  
        the default parameter mode in VB.NET, REALbasic, and C++ (though those  
        languages also offer a by-reference mode that Python andJavado not).
        To Steve's defense, he doesn't claim that Python is special; in one
        reply he also disputed the claim that even Java is call-by-value. Of
        course most Java programmers would have a hard time taking this claim
        seriously, but at least you both agree that Python and Java have the
        same call semantics, you just disagree on the name. Googling for 'java
        "call by sharing"' brings back only a few results with almost half of
        them being Python-related discussions. Steve is definitely in the
        minority but he's not completely alone: from


        """
        Like most pure object-oriented languages, Java only supports by "call-
        by-sharing". At the implementation level, this is the same as call-by-
        value. I.e., the actual parameter value is copied into the formal
        parameter before executing the body. At the end of the execution of
        the body, the formal parameter just goes away - no copy back occurs. I
        prefer to describe it as call-by-sharing because, while you may not
        replace the value via an assignment in the method body, you may change
        the state of an object value. In particular, if a parameter evaluates
        to an object, one can send messages to it which can change its state.
        """

        I believe the main source of confusion is wrt C/C++. The following
        definition has different semantics in C++ and Java, although they are
        both considered call by value:

        void foo(Person who) {
        who.zipcode = 12345;
        }

        In C++ a Person object itself is copied while in Java (and Python)
        only the reference ("handler") is copied. By the way, passing a
        (copied) reference is *not* equivalent to call by reference: in the
        former case, the assignment of the reference to a different object has
        only a local effect, i.e. it is not reflected to the caller's frame,
        whine in call by ref it does.

        George

        Comment

        • Steven D'Aprano

          Re: Finding the instance reference of an object

          On Tue, 04 Nov 2008 18:00:35 -0800, George Sakkis wrote:
          On Nov 4, 6:02 pm, Joe Strout <j...@strout.ne twrote:
          >
          >I know you really want Python to be unique and special -- and it is, in
          >many ways, but this isn't one of them.  Python is an OOP language whose
          >variables contain references to objects, and where such references are
          >passed (by value) to methods, just likeJava, and like the default
          >parameter mode in VB.NET, REALbasic, and C++ (though those languages
          >also offer a by-reference mode that Python andJavado not).
          >
          To Steve's defense, he doesn't claim that Python is special; in one
          reply he also disputed the claim that even Java is call-by-value.

          Python is as special as CLU, Lisp, Emerald, Iota and others.


          "As in Java, the calling semantics are call-by-sharing: the formal
          argument variable and the actual argument share the same value, at least
          until the argument variable is assigned to. Assignments to the argument
          variable do not affect the value passed; however, if the value passed was
          an array, assignments to elements of that array will be visible from the
          calling context as well, since it shares the same array object."



          Of
          course most Java programmers would have a hard time taking this claim
          seriously,
          That's their problem, not mine. If the Java community wishes to redefine
          "value" to mean an arbitrary, implementation-dependent reference instead
          of the actual value of the variable, that's their loss.


          --
          Steven

          Comment

          • Hendrik van Rooyen

            Re: Finding the instance reference of an object

            "Joe Strout" <joe@strout.net wrote:

            4. You now see how a mutating an object within a function tells you
            NOTHING about how the reference to that object was passed.
            5. You see that the first three languages above are passing a
            reference by value and using that to mutate and object, yet for
            reasons still mysterious, the Python example (which has exactly the
            same behavior) must be doing something different.
            This is dialectic nit picking - WTF makes "passing a reference by value"
            different from "passing a reference" - the salient point is that its a reference
            that is passed - would you expect another level of indirection - a reference to
            the
            reference, or what, before you admit that the thing that is passed is a
            reference
            and not a copied value of the OBJECT that is of interest.

            Looks to me that even if there were ten levels of indirection you would still
            insist that its a "pass by value" because in the end, its the actual memory
            address of the first pointer in the queue that is passed. If that is what you
            mean,
            it is obviously trivially true - but then ALL calling can only be described as
            "call by value" - which makes nonsense of what the CS people have been
            doing all these years.

            "Calling by value" is not a useful definition of Pythons behaviour.

            - Hendrik



            Comment

            • Terry Reedy

              Re: Finding the instance reference of an object

              Dennis Lee Bieber wrote:
              I'm sure all the programmers using FORTRAN for the last 50 years
              will be very surprised to hear that it uses call-by-value!
              That should be 'last 31 years'. Fortran IV *was* call-by-value, as
              least for scalars. I remember spending a couple of hours tracking down
              an obscure 'bug' in a once-working program when I ran it with F77. (I
              had not noticed the call-by-reference switch.) The reason was, as I
              remember, 'x = -x' in a function. I never forgot the difference.
              I've used it for 30 years
              Then you apparently missed the switch ;-).

              tjr


              Comment

              • Lie

                Re: Finding the instance reference of an object

                On Nov 4, 9:33 am, Joe Strout <j...@strout.ne twrote:
                On Nov 3, 2008, at 5:27 PM, Marc 'BlackJack' Rintsch wrote:
                >
                Maybe this is a surprise for you, because we haven't discussed this in
                much detail in this group lately, but it applies to Python which does
                call-by-object or call-by-sharing.  ;-)
                >
                There's no such thing.  Those are just terms made up by the Python  
                community to in place of the more standard "call-by-value" terminology  
                to make Python seem more mysterious than it really is.  I guess you  
                can call it "purple bananas" if you want, but the behavior is exactly  
                the same as what every other language calls call-by-value.
                >
                But I really am trying not to continue this debate.  So that's my last  
                reply about it for tonight, I promise.  :)
                >
                Cheers,
                - Joe
                <http://www.strout.net/info/coding/valref/>
                I'm fed up with you.

                In Von Neumann Architecture computers, only pass-by-value is natively
                supported. Other idioms are made on top of pass-by-value.

                That's why exclusively pass-by-value languages like C is most flexible
                than other exclusively pass-by-<insertanything here>.

                BUT the difference is clear, if you want to do pass-by-reference in C
                (I prefer to call it faux pass-by-reference), you'd have to manually
                find a variable's address, pass it by-value, then dereference the
                address. Compare with VB's ByRef or C++'s &, which does all that
                _automatically_ for you behind the scene.

                Another example: pass-by-object. I disagree with the term pass-by-
                object-reference, since the notion of object reference is unnecessary
                in a true pass-by-object mechanism (i.e. we should travel outside VNA
                realm for a true pass-by-object mechanism). Problem is: I'm not aware
                of any computer architecture that can accommodate pass-by-object
                natively or whether such architecture is feasible to be made.
                Solution: Emulate such architecture on a VNA computer. Limitations:
                pass-by-object implementation on a VNA computer requires the notion of
                object reference/pointer because VNA computers cannot pass object, it
                can only pass numbers.

                In pass-by-object, the whole object is passed around, not a copy of
                the object like in pass-by-value or a copy of the pointer to the
                object like in faux pass-by-reference. This makes pass-by-object
                actually closer to pass-by-reference than to pass-by-value, since the
                notion of VNA's requirement for Object Reference means passing
                pointers around. But don't let it confuse you, the pass-by-object
                mechanism itself does not recognize Object Reference, unlike pass-by-
                reference recognition of reference/pointer.

                Now that I have clearly defined the line between pass-by-object and
                pass-by-value, I'm left with you thinking what's the difference
                between pass-by-object and pass-by-reference. In pass-by-reference,
                names are _mnemonic to location in memory_. In pass-by-object, names
                are _mnemonic to objects_. In pass-by-reference, when we assign a
                value to the name, we'd assign a value _to the location in memory_. In
                pass-by-object, when we assign a value to the name, we assign an
                object _to the name_. When passing parameters, pass-by-reference
                systems passed the memory address and alias that memory address to a
                local name. In pass-by-object system, since the object itself has no
                idea of its own name, so it is rebound to a local name. You can say
                that pass-by-reference system is memory-location-centered, while pass-
                by-object system is name-centered.

                To summarize, the key bit you're missing is built-in _automatic_
                abstraction from pass-by-value. All pass-by-<insertanything except
                pass-by-value is an emulation over an architecture that can only
                natively pass-by-value. pass-by-reference is emulated in C, C++, and
                VB by passing memory address/pointer but C isn't a by-ref system
                because C doesn't provide the automatization. What makes python's
                parameter passing called as pass-by-object is because python provides
                the automatization to make it seems that you can do true pass-by-
                object.

                Comment

                • Joe Strout

                  Re: Finding the instance reference of an object

                  On Nov 5, 2008, at 12:29 AM, Dennis Lee Bieber wrote:
                  >C++:
                  >void foo(PersonPtr who) {
                  > who->zipcode = 12345;
                  >}
                  >>
                  Please show us the type definition of "PersonPtr"
                  Sorry, that'd be obvious to anyone experienced in C++, but I shouldn't
                  assume. It would be:

                  typedef Person* PersonPtr;

                  It's a pretty standard idiom, precisely because it is so much more
                  common to need a variable of the pointer type than of the class type
                  itself.
                  >Java:
                  >void foo(Person who) {
                  > who.zipcode = 12345;
                  >}
                  >>
                  Please show us the type definition of "Person"
                  No. It's a class, and you can see that it defines a "zipcode" member;
                  nothing more is needed for the sake of this example. (The Java
                  designers realized that needing object reference variables is so
                  overwhelmingly more common than needing non-pointer variables, that
                  they eliminated the pointer syntax and made every variable of object
                  type actually a pointer to the object data, just as in RB, .NET, and
                  Python.)
                  >REALbasic/VB.Net:
                  >Sub foo(ByVal who as Person)
                  > who.zipcode = 12345
                  >End Sub
                  >>
                  Note they YOU, as the programmer, explicitly told the language to
                  use a call-by-value
                  Correct; these languages support both call-by-value and call-by-
                  reference. "ByVal" is the default, but you can still specify it (as
                  I've done here) if you want to be explicit.
                  -- and you still have not shown us the definition of "Person"
                  Right, again, there is nothing you need to know about it not already
                  evident from the example.
                  >Python:
                  >def foo(who):
                  > who.zipcode = 12345
                  >>
                  Note that there is NO PROGRAMMER CONTROL over the passing mechanism.
                  Quite right. (Same too in Java.) Some languages offer both call-by-
                  value and call-by-reference; but Java and Python offer only call-by-
                  value.
                  >5. You see that the first three languages above are passing a
                  >reference by value and using that to mutate and object, yet for
                  >reasons still mysterious, the Python example (which has exactly the
                  >same behavior) must be doing something different.
                  >>
                  I do not... I see the programmer telling the language that a
                  reference is to be taken of some object and that this reference is
                  /then/ to be passed.
                  Quite right (and that's what I said). The reference is being passed.
                  By value. And then that reference is used to mutate an object.
                  AND the programmer is also (C++) explicitly dereferencing (by use of
                  ->)!
                  Yep, "->" is the dereference operator in C++; in Java, RB, .NET, and
                  Python, it's ".". Different characters, same meaning.
                  The syntax, in C/C++ is different for
                  accessing the parameter by value vs by reference (pointer -- C++ is
                  smarter in that it allows declaring the parameter as a &ref and the
                  language automatically takes the address on the caller's side, and
                  dereferences on the called side -- but that notation is STILL a
                  programmer responsibility) .
                  Careful here -- a &ref parameter really is passed by reference; that's
                  not the same as passing a pointer by value, which is what's shown
                  above. It's the C++ equivalent of the "ByRef" keyword in RB/VB.NET.
                  Java passes /objects/ by reference, but passes "native" types (base
                  numerics) by value
                  No, it passes everything by value. "who" in the Java example is not
                  an object; it is an object reference. It was passed by value. If it
                  were passed by reference, you'd be able to make a "swap" function that
                  exchanges the objects referred to by two variables, but you can't.
                  This is explained more fully here:

                  <http://javadude.com/articles/passbyvalue.htm >
                  -- can you create a Java example where you pass a base numeric by
                  reference?
                  No, because Java (like Python) has only call-by-value.
                  By your argument, even FORTRAN is call-by-value.
                  No, FORTRAN's an oddball: it passes everything by reference.
                  You obfuscate the mechanics used at the machine language level with
                  the semantics of the
                  language itself.
                  No, I haven't said anything at all about what's happening at the
                  machine language level, and I frankly don't care. This is about how
                  the language behaves.
                  FORTRAN is the language commonly used to explain call-by-reference!
                  Quite right. So, please try to convert any of those FORTRAN
                  explanations into Python or Java. Can't be done. In C++ or RB/
                  VB.NET, it can be done only by using the special by-reference syntax
                  (& or ByRef).

                  I'm not sure where you got the idea that I thought FORTRAN is call-by-
                  value. I never said or implied any such thing. And the examples
                  above aren't meant to prove that those languages are using by-value;
                  they're meant to show that mutating an object via a reference passed
                  in proves NOTHING about how that reference was passed. This is to
                  invalidate the argument (frequently heard around here) that Python
                  must use call-by-reference since you can mutate an object passed to a
                  function.

                  As should be painfully clear by now, that argument is total bunk. You
                  can pass an object reference by value, and use it to mutate the object
                  it refers to just fine. To test whether you're passing by reference
                  or by value, you need to instead assign a new value to the formal
                  parameter, and see whether that affects the actual parameter.
                  >
                  Cheers,
                  - Joe

                  Comment

                  • Joe Strout

                    Re: Finding the instance reference of an object

                    On Nov 4, 2008, at 12:57 PM, Hendrik van Rooyen wrote:
                    >4. You now see how a mutating an object within a function tells you
                    >NOTHING about how the reference to that object was passed.
                    >
                    >5. You see that the first three languages above are passing a
                    >reference by value and using that to mutate and object, yet for
                    >reasons still mysterious, the Python example (which has exactly the
                    >same behavior) must be doing something different.
                    >
                    This is dialectic nit picking - WTF makes "passing a reference by
                    value"
                    different from "passing a reference" - the salient point is that its
                    a reference
                    that is passed
                    I know it seems nit-picky on the surface, but it is important. It is
                    the distinction that lets you answer whether:

                    def foo(x):
                    x = Foo()

                    x = Bar()
                    foo(x)

                    ....results in x (after the call) now referring to a Foo, or still
                    referring to a Bar.

                    If x is a reference passed by value, then the assignment within the
                    foo method can't affect the x that was passed in. But if it is passed
                    by reference, then it does. (Also, if it is passed by reference, then
                    you probably wouldn't be able to pass in a literal or computed value,
                    but only a simple variable.)
                    - would you expect another level of indirection - a reference to
                    the reference, or what, before you admit that the thing that is
                    passed is a
                    reference and not a copied value of the OBJECT that is of interest.
                    Um, no, I've admitted that it's a reference all along. Indeed, that's
                    pretty much the whole point: that variables in Python don't contain
                    objects, but merely contain references to objects that are actually
                    stored somewhere else (i.e. on the heap). This is explicitly stated
                    in the Python docs [1], yet many here seem to want to deny it.
                    Looks to me that even if there were ten levels of indirection you
                    would still
                    insist that its a "pass by value" because in the end, its the actual
                    memory
                    address of the first pointer in the queue that is passed.
                    No, it's entirely possible for an OOP language to have pass by
                    reference, and, to put it your way, this adds one more level of
                    indirection. Look at the C++ and RB/VB.NET examples at [2]. But
                    Python and Java do not offer this option.
                    If that is what you mean, it is obviously trivially true - but then
                    ALL
                    calling can only be described as "call by value" - which makes
                    nonsense
                    of what the CS people have been doing all these years.
                    That would indeed be nonsense. But it's also not what I'm saying.
                    See [2] again for a detailed discussion and examples. Call-by-value
                    and call-by-reference are quite distinct.
                    "Calling by value" is not a useful definition of Pythons behaviour.
                    It really is, though. You have to know how the formal parameter
                    relates to the actual parameter. Is it a copy of it, or an alias of
                    it? Without knowing that, you don't know what assignments to the
                    formal parameter will do, or even what sort of arguments are valid.
                    Answer: it's a copy of it. Assignments don't affect the actual
                    parameter at all. This is exactly what "call by value" means.

                    Best,
                    - Joe

                    [1] http://www.python.org/doc/2.5.2/ext/refcounts.html
                    [2] http://www.strout.net/info/coding/valref/

                    Comment

                    • Arnaud Delobelle

                      Re: Finding the instance reference of an object


                      I know this thread has grown quite personal for some of its
                      participants. I am posting in a spirit of peace and understanding :)

                      Joe Strout <joe@strout.net writes:
                      [...]
                      Um, no, I've admitted that it's a reference all along. Indeed, that's
                      pretty much the whole point: that variables in Python don't contain
                      objects, but merely contain references to objects that are actually
                      stored somewhere else (i.e. on the heap). This is explicitly stated
                      in the Python docs [1], yet many here seem to want to deny it.
                      You refer to docs about the *implementation * of Python in C. This is
                      irrelevant.

                      Also, you talk about variables 'containing' something. In Python,
                      variables don't contain anything, they're simply names for objects.
                      'Pass by value' is not relevant to Python as variables do not contain
                      anything. 'Pass by reference' is not relevant to Python as the language
                      doesn't have the concept of object reference (in the sense of e.g. C++
                      reference).

                      [...]
                      >"Calling by value" is not a useful definition of Pythons behaviour.
                      >
                      It really is, though. You have to know how the formal parameter
                      relates to the actual parameter. Is it a copy of it, or an alias of
                      it? Without knowing that, you don't know what assignments to the
                      formal parameter will do, or even what sort of arguments are valid.
                      Answer: it's a copy of it. Assignments don't affect the actual
                      parameter at all. This is exactly what "call by value" means.
                      Here lies, IMHO, the reason why you think you need Python to 'pass by
                      value'. As you believe that variables must contain something, you think
                      that assignment is about copying the content of a variable. Assignment
                      in Python is simply giving a new name to an object.

                      To understand variables (which I prefer to call 'names') and function
                      calls in Python you need simply to understand that:

                      - a variable is a name for an object
                      - assignment is naming an object
                      - the parameters of a function are local names for the call arguments
                      (I guess 'pass by object' is a good name).

                      Now quoting the start of your post:
                      On Nov 4, 2008, at 12:57 PM, Hendrik van Rooyen wrote:
                      >>5. You see that the first three languages above are passing a
                      >>reference by value and using that to mutate and object, yet for
                      >>reasons still mysterious, the Python example (which has exactly the
                      >>same behavior) must be doing something different.
                      >>
                      >This is dialectic nit picking - WTF makes "passing a reference by
                      >value"
                      >different from "passing a reference" - the salient point is that its
                      >a reference
                      >that is passed
                      I would say that an oject is passed, not a reference.
                      I know it seems nit-picky on the surface, but it is important. It is
                      the distinction that lets you answer whether:
                      >
                      def foo(x):
                      x = Foo()
                      >
                      x = Bar()
                      foo(x)
                      >
                      ...results in x (after the call) now referring to a Foo, or still
                      referring to a Bar.
                      You don't need this to decide. This is what happens:

                      x = Bar() # Call this new Bar object 'x'
                      foo(x) # call function foo with argument the object known as 'x'

                      # Now, in foo:
                      def foo(x): # Call 'x' locally the object passed to foo
                      x = Foo() # Call 'x' locally this new Foo object.

                      Obviously after all this, 'x' is still the name of the Bar object
                      created at the start.


                      To sum up: for 'pass by value' to make sense in Python you need to
                      create an unnecessarily complex model of how Python works. By letting
                      go of 'pass by value' you can simplify your model of the language
                      (keeping it correct of course) and it fits in your brain more easily.

                      Of course your own model is valid but there is a better one which is
                      easier to grasp for people without a background in C/C++ - like
                      languages.

                      --
                      Arnaud

                      Comment

                      • Aaron Brady

                        Re: Finding the instance reference of an object

                        On Nov 6, 1:44 pm, Arnaud Delobelle <arno...@google mail.comwrote:
                        I know this thread has grown quite personal for some of its
                        participants.  I am posting in a spirit of peace and understanding :)
                        Hear, hear.
                        You refer to docs about the *implementation * of Python in C.  This is
                        irrelevant.
                        >
                        Also, you talk about variables 'containing' something.  In Python,
                        variables don't contain anything, they're simply names for objects.
                        'Pass by value' is not relevant to Python as variables do not contain
                        anything.  'Pass by reference' is not relevant to Python as the language
                        doesn't have the concept of object reference (in the sense of e.g. C++
                        reference).
                        ....
                        I would say that an oject is passed, not a reference.
                        ....
                        To sum up: for 'pass by value' to make sense in Python you need to
                        create an unnecessarily complex model of how Python works.  By letting
                        go of 'pass by value' you can simplify your model of the language
                        (keeping it correct of course) and it fits in your brain more easily.
                        >
                        Of course your own model is valid but there is a better one which is
                        easier to grasp for people without a background in C/C++ - like
                        languages.
                        I agree, and I don't think we're giving Joe the proper credit for what
                        he knows and has worked on. Furthermore, his understanding of the
                        implementation of languages is thorough, and you can't have languages
                        without implementations . Though, you do not need to understand the
                        implementation to understand the language.

                        I haven't thought it through completely, but now that Joe mentions it,
                        it appears Python behaves the same as C++, if variables can't be
                        anything but pointers, parameters are all c-b-v, and you can't
                        dereference the l-h-s of an assignment ( '*a= SomeClass()' ).

                        When you're explaining Python to a beginner, you have to introduce a
                        new term either way. You'll either have to explain pointers, which
                        there are chapters and chapters on in introductory textbooks; or,
                        you'll have to explain a new calling mechanism, and give it a name.

                        I think pointer-by-value would be accurate, but by-value wouldn't be.
                        I would say that an oject is passed, not a reference.
                        I agree, and anything else would be overcomplicated .

                        Comment

                        • Joe Strout

                          Re: Finding the instance reference of an object

                          On Nov 5, 2008, at 2:06 PM, Lie wrote:
                          ><http://www.strout.net/info/coding/valref/>
                          >
                          I'm fed up with you.
                          I'm sorry -- I'm really not trying to be difficult. And it's odd that
                          you're fed up with me, yet you seem to be agreeing with me on at least
                          most points.
                          In Von Neumann Architecture computers, only pass-by-value is natively
                          supported. Other idioms are made on top of pass-by-value.
                          Well, sure. But a language may or may not naturally support the others.
                          That's why exclusively pass-by-value languages like C is most flexible
                          than other exclusively pass-by-<insertanything here>.
                          >
                          BUT the difference is clear, if you want to do pass-by-reference in C
                          (I prefer to call it faux pass-by-reference), you'd have to manually
                          find a variable's address, pass it by-value, then dereference the
                          address.
                          Agreed.
                          Compare with VB's ByRef or C++'s &, which does all that
                          _automatically_ for you behind the scene.
                          Agreed again.
                          Another example: pass-by-object.
                          Here's where we depart, I guess. I think there's no such thing (see <http://en.wikipedia.org/wiki/Evaluation_strategy
                          for example, and the dead-tree references I have on hand agree).
                          I disagree with the term pass-by-object-reference, since the notion
                          of object reference is unnecessary
                          in a true pass-by-object mechanism (i.e. we should travel outside VNA
                          realm for a true pass-by-object mechanism). Problem is: I'm not aware
                          of any computer architecture that can accommodate pass-by-object
                          natively or whether such architecture is feasible to be made.
                          I don't think it's necessary (or helpful) to reach down into the
                          architecture or implementation details. What matters is the behavior
                          as seen by the language user. Variables in a language could hold
                          actual object data (in which case "a = b" would copy the data from b
                          into a), or they could hold just references to object data that lives
                          elsewhere (in which case "a = b" would copy that reference, giving you
                          two references to the same object). In Python, they are of course
                          just references.

                          Then, and completely independent of that, variables could be passed
                          into a method by value or by reference (or by several other more
                          esoteric evaluation strategies that are rarely used, but "call by
                          object" isn't one of them). Again, it's easy to tell these apart with
                          a simple behavioral test. Python passes its object references by
                          value; changes to the formal parameter have no effect on the actual
                          parameter.
                          In pass-by-object, the whole object is passed around, not a copy of
                          the object like in pass-by-value or a copy of the pointer to the
                          object like in faux pass-by-reference.
                          I can't understand what that would mean, unless we imagine the
                          variable actually containing the object data; but it doesn't, or "a =
                          b" would copy that data, which clearly it does not.

                          Understanding that a name in Python is merely a reference to the
                          object, and not the object itself, seems to me to be one of the
                          fundamental truths that any beginning Python programmer must know.
                          This makes pass-by-object
                          actually closer to pass-by-reference than to pass-by-value, since the
                          notion of VNA's requirement for Object Reference means passing
                          pointers around. But don't let it confuse you, the pass-by-object
                          mechanism itself does not recognize Object Reference, unlike pass-by-
                          reference recognition of reference/pointer.
                          Sorry, it's confusing me whether I want it to or not.

                          And here's what I don't understand: object references are so simple,
                          why do people go to such great lengths to pretend that Python doesn't
                          have them, resulting in a far more complex and convoluted explanation
                          that is much harder to understand?
                          Now that I have clearly defined the line between pass-by-object and
                          pass-by-value, I'm left with you thinking what's the difference
                          between pass-by-object and pass-by-reference.
                          If they're that hard to tell apart, then Python doesn't have either,
                          since it is very clear and obvious that Python does not have pass-by-
                          reference (since you can't write a function to swap two parameters,
                          for example).
                          In pass-by-reference, names are _mnemonic to location in memory_.
                          In pass-by-object, names are _mnemonic to objects_.
                          These would be equivalent if objects live at some location in memory,
                          wouldn't they?
                          In pass-by-reference, when we assign a
                          value to the name, we'd assign a value _to the location in memory_. In
                          pass-by-object, when we assign a value to the name, we assign an
                          object _to the name_. When passing parameters, pass-by-reference
                          systems passed the memory address and alias that memory address to a
                          local name. In pass-by-object system, since the object itself has no
                          idea of its own name, so it is rebound to a local name. You can say
                          that pass-by-reference system is memory-location-centered, while pass-
                          by-object system is name-centered.
                          Hmm. I can only interpret "the object is rebound to a local name"
                          sounds the same to me as "a local variable is assigned a reference to
                          the object." Can you explain how they're different?

                          I see how what you're describing is different from pass by reference;
                          I just don't see how it's any different from pass by value.
                          To summarize, the key bit you're missing is built-in _automatic_
                          abstraction from pass-by-value. All pass-by-<insertanything except
                          pass-by-value is an emulation over an architecture that can only
                          natively pass-by-value.
                          Yes, OK, that's great. But there are several standard pass-by-
                          somethings that are defined by the CS community, and which are simple
                          and clear and apply to a wide variety of languages. "Pass by object"
                          isn't one of them. I guess if you want to campaign for it as a
                          shorthand for "object reference passed by value," you could do that,
                          and it's not outrageous. But to anybody new to the term, you should
                          explain it as exactly that, rather than try to claim that Python is
                          somehow different from other OOP languages where everybody calls it
                          simply pass by value.
                          pass-by-reference is emulated in C, C++, and
                          VB by passing memory address/pointer but C isn't a by-ref system
                          because C doesn't provide the automatization.
                          Yes, that's true of C. I never argued that C had a by-ref mode. C++,
                          VB, and REALbasic all do, however. Python and Java do not.
                          What makes python's parameter passing called as pass-by-object is
                          because python provides
                          the automatization to make it seems that you can do true pass-by-
                          object.
                          OK, if there were such a thing as "pass-by-object" in the standard
                          lexicon of evaluation strategies, I would be perfectly happy saying
                          that a system has it if it behaves as though it has it, regardless of
                          the underpinnings.

                          My objection to this term is simply that it is made up and
                          nonstandard, and adds no new value to the discussion. To me, "object
                          references passed by value" is simple and clear, where as "pass by
                          object" means nothing (until you explain that it means the former).

                          However, if you really think the term is that handy, and we want to
                          agree to say "Python uses pass by object" and answer the inevitable
                          "huh?" question with "that's shorthand for object references passed by
                          value," then I'd be OK with that.

                          Best,
                          - Joe

                          Comment

                          • Joe Strout

                            Re: Finding the instance reference of an object

                            On Nov 6, 2008, at 12:44 PM, Arnaud Delobelle wrote:
                            I know this thread has grown quite personal for some of its
                            participants. I am posting in a spirit of peace and understanding :)
                            Thanks, I'll do the same.
                            >Um, no, I've admitted that it's a reference all along. Indeed,
                            >that's
                            >pretty much the whole point: that variables in Python don't contain
                            >objects, but merely contain references to objects that are actually
                            >stored somewhere else (i.e. on the heap). This is explicitly stated
                            >in the Python docs [1], yet many here seem to want to deny it.
                            >
                            You refer to docs about the *implementation * of Python in C. This is
                            irrelevant.
                            It's supportive. I don't understand how/why anybody would deny that
                            Python names are references -- it's all over the place, from any
                            discussion of "reference counting" (necessary to understand the life
                            cycle of Python object) to understanding the basics of what "a = b"
                            does. It seems absurd to argue that Python does NOT use references.
                            So the official documentation calmly discussing Python references,
                            with no caveats about it being internal implementation detail, seemed
                            relevant.
                            Also, you talk about variables 'containing' something. In Python,
                            variables don't contain anything, they're simply names for objects.
                            You say "names for", I say "references to". We're saying the same
                            thing (though I'm saying it with terminology that is more standard, at
                            least in the wider OOP world).
                            'Pass by value' is not relevant to Python as variables do not contain
                            anything. 'Pass by reference' is not relevant to Python as the
                            language
                            doesn't have the concept of object reference (in the sense of e.g. C++
                            reference).
                            Both are relevant to answering simple questions, like what happens to
                            x in this case:

                            def foo(spam):
                            spam = 5
                            foo(x)

                            This is a basic and fundamental thing that a programmer of a language
                            should know. If it's call-by-reference, then x becomes 5. If it's
                            call-by-value, it does not.

                            Why the resistance to these simple and basic terms that apply to any
                            OOP language?
                            Here lies, IMHO, the reason why you think you need Python to 'pass by
                            value'. As you believe that variables must contain something, you
                            think
                            that assignment is about copying the content of a variable.
                            Assignment
                            in Python is simply giving a new name to an object.
                            What does "give a new name to an object" mean? I submit that it means
                            exactly the same thing as "assigns the name to refer to the object".
                            There certainly is no difference in behavior that anyone has been able
                            to point out between what assignment does in Python, and what
                            assignment does in RB, VB.NET, Java, or C++ (in the context of object
                            pointers, of course). If the behavior is the same, why should we make
                            up our own unique and different terminology for it?
                            To understand variables (which I prefer to call 'names') and function
                            calls in Python you need simply to understand that:
                            >
                            - a variable is a name for an object
                            A reference to an object, got it.
                            - assignment is naming an object
                            Assigning the reference to the object, yes.
                            - the parameters of a function are local names for the call arguments
                            Agreed; they're not aliases of the call arguments.
                            (I guess 'pass by object' is a good name).
                            Well, I'm not sure why that would be. What you've just described is
                            called "pass by value" in every other language.
                            I would say that an oject is passed, not a reference.
                            That seems to contradict the actual behavior, as well as what you said
                            yourself above. The only way I know how to interpret "an object is
                            passed" is "the data of that object is copied onto the stack". But of
                            course that's not what happens. What actually happens is what you
                            said above: a name (reference) is assigned to the object. The name is
                            a reference; it is made to refer to the same thing that the argument
                            (actual parameter) referred to. This is exactly what "the reference
                            is passed" means, nothing more or less.
                            >I know it seems nit-picky on the surface, but it is important. It is
                            >the distinction that lets you answer whether:
                            >>
                            >def foo(x):
                            > x = Foo()
                            >>
                            >x = Bar()
                            >foo(x)
                            >>
                            >...results in x (after the call) now referring to a Foo, or still
                            >referring to a Bar.
                            >
                            You don't need this to decide. This is what happens:
                            >
                            x = Bar() # Call this new Bar object 'x'
                            In other words, make 'x' refer to this new object.
                            foo(x) # call function foo with argument the object known as 'x'
                            Yes. But what does that mean? Does the parameter within 'foo' become
                            an alias of x, or a copy of it? That's what we DO need to decide.
                            # Now, in foo:
                            def foo(x): # Call 'x' locally the object passed to foo
                            I think you mean here that local 'x' is made to refer to the object
                            passed to foo. Agreed. It is NOT an alias of the actual parameter.
                            And that's what we need to know. So it's not call-by-reference, it's
                            call-by-value; the value of x (a reference to whatever object Bar()
                            returned) is copied from the value of the parameter (a reference to
                            that same object, of course).
                            x = Foo() # Call 'x' locally this new Foo object.
                            Make 'x' refer to the new Foo() result, yes.
                            Obviously after all this, 'x' is still the name of the Bar object
                            created at the start.
                            Obvious only once you've determined that Python is call-by-value. If
                            it were like FORTRAN, where everything is call-by-reference, then that
                            wouldn't be the case at all; the assignment within the function would
                            affect the variable (or name, if you prefer) passed in.
                            To sum up: for 'pass by value' to make sense in Python you need to
                            create an unnecessarily complex model of how Python works.
                            I have to disagree. The model is simple, self-consistent, and
                            consistent with all other languages. It's making up terms and trying
                            to justify them and get out of the logical knots (such as your claim
                            above that the object itself is passed to a method) that is
                            unnecessarily complex.
                            By letting go of 'pass by value' you can simplify your model of the
                            language
                            (keeping it correct of course) and it fits in your brain more easily.
                            I'm afraid I don't see that.
                            Of course your own model is valid but there is a better one which is
                            easier to grasp for people without a background in C/C++ - like
                            languages.
                            Well, if by C/C++-like languages, you mean also Java, VB.NET, and so
                            on, then maybe you're right -- perhaps my view is colored by my
                            experience with those. But alternatively, perhaps there are enough
                            Python users without experience in other OOP languages, that the
                            standard terminology was unfamiliar to them, and they made up their
                            own, resulting in the current linguistic mess.

                            Best,
                            - Joe

                            Comment

                            • Terry Reedy

                              Re: Finding the instance reference of an object

                              Aaron Brady wrote:
                              and you can't have languages without implementations .
                              This is either a claim that languages are their own implementations , or
                              an admission that human brains are the implementation of all languages
                              thought of by human brains, coupled with a claim that there cannot be
                              languages not thought of by humans, or just wrong in terms of the common
                              meaning of algorithmic implementation of an interpreter. There are many
                              algorithm languages without such implementations . They were once called
                              'pseudocode'. (I don't know if that term is still used much.) Hence my
                              oxymoronic definition, a decade ago, of Python as 'executable pseudocode'.
                              Though, you do not need to understand the
                              implementation to understand the language.
                              Languages are typically defined before there is any implementation.
                              They are implemented if they are understood as being worth the effort.
                              I haven't thought it through completely, but now that Joe mentions it,
                              it appears Python behaves the same as C++,
                              Python and C/C++ have completely different object and data models. You
                              and Joe are completely welcome to understand/model Python in terms of
                              the C implementation, if you wish, but it not necessary and, I believe,
                              a disservice to push such a model on beginners as *the* way to model Python.
                              if variables can't be
                              anything but pointers, parameters are all c-b-v, and you can't
                              dereference the l-h-s of an assignment ( '*a= SomeClass()' ).
                              I don't understand this.
                              When you're explaining Python to a beginner, you have to introduce a
                              new term either way. You'll either have to explain pointers, which
                              Python has no concept of pointers.
                              there are chapters and chapters on in introductory textbooks; or,
                              you'll have to explain a new calling mechanism, and give it a name.
                              I disagree. In everyday life, we have multiple names for objects and
                              classes of objects. We nearly always define procedures in terms of
                              generic object classes (common nouns) rather than particular objects.
                              We apply procedures by binding generic names to particular objects, by
                              associating them with objects, by filling in the named blanks. This is
                              what Python does. Except for the particular formalized syntax, there is
                              nothing new, not even the idea of a specialized procedure language.

                              def make_cookies(fl our, oil, sugar, egg, bowl, spoon, cookie_pan, oven):
                              "flour, oil, and sugar are containers with respectively at least 2
                              cups, 1 tablespoon, and 1/4 cup of the indicated material"
                              mix(bowl, spoon, measure(flour, '2 cups'), measure(sugar, '1/4 cup'))
                              <etc>

                              OK, there is one important difference. The concrete referents for the
                              parameters are non-physical information objects rather than physical
                              objects.
                              >I would say that an oject is passed, not a reference.
                              I agree, and anything else would be overcomplicated .
                              To me, 'pass' implies movement, but in Python, objects don't really have
                              a position and hence cannot move. So I would say that an object is
                              associated (with a parameter). 'Associating' is a primitive operation
                              for Python interpreters. If and when all parameters get associated with
                              something, the function code is activated. Then the return object gets
                              associated with the call expression in the computation graph.

                              Terry Jan Reedy

                              Comment

                              • Aaron Brady

                                Re: Finding the instance reference of an object

                                On Nov 6, 6:00 pm, Terry Reedy <tjre...@udel.e duwrote:
                                Aaron Brady wrote:
                                and you can't have languages without implementations .
                                >
                                This is either a claim that languages are their own implementations , or
                                an admission that human brains are the implementation of all languages
                                thought of by human brains, coupled with a claim that there cannot be
                                languages not thought of by humans, or just wrong in terms of the common
                                meaning of algorithmic implementation of an interpreter.  There are many
                                algorithm languages without such implementations .  They were once called
                                'pseudocode'. (I don't know if that term is still used much.)  Hence my
                                oxymoronic definition, a decade ago, of Python as 'executable pseudocode'..
                                I was just saying that Joe has a good idea for one way to implement
                                Python.
                                Python and C/C++ have completely different object and data models.  You
                                and Joe are completely welcome to understand/model Python in terms of
                                the C implementation, if you wish, but it not necessary and, I believe,
                                a disservice to push such a model on beginners as *the* way to model Python.
                                You're asking about people's thought processes when they write a
                                program. In chess, I sometimes think, "If I move here, he moves
                                there," etc., but not always; sometimes I just visualize pieces in
                                places. In Python, if I want a function that, say, duplicates the
                                first and last elements of a sequence type, I visualize one parameter,
                                and some code that operates on it.

                                def duper( a ):
                                a.insert( 0, a[ 0 ] )
                                a.append( a[ -1 ] )

                                Someone else with no experience, or certain incompatible experience,
                                might visualize this:

                                def duper( a ):
                                a= a[ 0 ] + a + a[ -1 ]

                                As you can see, they know a lot of Python already. What are they
                                missing?
                                if variables can't be
                                anything but pointers, parameters are all c-b-v, and you can't
                                dereference the l-h-s of an assignment ( '*a= SomeClass()' ).
                                >
                                I don't understand this.
                                If you restricted a C program as follows:
                                - variables can only be pointers
                                - no pointers to pointers
                                - no dereferencing l-h-s of assignment statements

                                It would look at the very least a lot like Python, or as Joe holds,
                                exactly like Python.

                                snip.
                                I disagree.  In everyday life, we have multiple names for objects and
                                classes of objects. We nearly always define procedures in terms of
                                generic object classes (common nouns) rather than particular objects.
                                We apply procedures by binding generic names to particular objects, by
                                associating them with objects, by filling in the named blanks.  This is
                                what Python does.  Except for the particular formalized syntax, there is
                                nothing new, not even the idea of a specialized procedure language.
                                To examine the natural language (NL) equivalents of these issues a
                                little.

                                Here's a question I posed to Joe:

                                a) 'Fido' is a reference to a dog
                                b) Fido is a reference to a dog
                                c) 'Fido' is the name of a dog
                                d) Fido is the name of a dog
                                e) 'Fido' is a dog
                                f) Fido is a dog

                                Which are true?

                                I have no problems with (c) and (f), and many natural languages
                                (possibly being strictly spoken) do not distinguish (c) from (d).
                                Similarly,

                                Old McDonald had a dog and Bingo was it's name.
                                (*) Old McDonald had a dog and Bingo was it. (* marks non-standard)
                                (*) Old McDonald had a dog and it was Bingo.

                                I want to give a code name to Fido: Rex. What language do I use to
                                inform my audience ("spies"), and what statements are subsequently
                                true? Then, I want to write instructions to friends on how to walk
                                dogs in my neighborhood, still in natural language.

                                _How to walk a dog_
                                Take the dog out the door
                                Turn right at the end of the drive
                                etc.

                                Nothing mysterious. Same thing with instructions for vaccinating
                                them. However, if I want to model dogs, simulate them, etc., I'll
                                keep some running state information about them: think its chart at the
                                vet.

                                Dog:
                                Fido:
                                Last walked: 10 a.m.
                                Needs to be walked: False

                                At 4 p.m., I'm going through the charts, and I notice Fido hasn't been
                                walked, so I change the 'Needs to be walked' entry to true.

                                Then some members of "spies" walks into the vet, and ask if Rex needs
                                to be walked.

                                What things in this story are names, variables, dogs, references,
                                objects, pointers, types, classes, procedures, functions, arguments,
                                parameters, formal parameters, by-value parameters, by-reference
                                parameters, by-share parameters, etc.? How many names does Fido have,
                                what are they, what is Fido, what is Rex, etc.? Keep in mind there
                                are seldom quotes in spoken language; people have to make gestures or
                                be explicit in such cases as they need to indicate their presence.

                                "Quote Fido quote is the name of a dog, but Fido is not." (Actual
                                transcription.)

                                Keep answers to less than 500 words. Also, reevaluate the uses of
                                'the' and 'a' in the multiple choice question: Is 'Fido' the name of a
                                dog, a name of a dog, or a name of the dog?
                                def make_cookies(fl our, oil, sugar, egg, bowl, spoon, cookie_pan, oven):
                                     "flour, oil, and sugar are containers with respectively at least 2
                                cups, 1 tablespoon, and 1/4 cup of the indicated material"
                                     mix(bowl, spoon, measure(flour, '2 cups'), measure(sugar, '1/4cup'))
                                yield cookies #yum
                                OK, there is one important difference.  The concrete referents for the
                                parameters are non-physical information objects rather than physical
                                objects.
                                This is actually underestimated. Equality and identity as defined on
                                mathematical ("ideal") / logical objects isn't the same as our "real"
                                notions of them. Words are sort of in between, giving rise to e.g.
                                the difference between numbers and numerals.
                                I would say that an oject is passed, not a reference.
                                I agree, and anything else would be overcomplicated .
                                >
                                To me, 'pass' implies movement, but in Python, objects don't really have
                                a position and hence cannot move.  So I would say that an object is
                                associated (with a parameter).
                                Further complicating matters, is the function, its parameters,
                                variables, code, etc. remain in existence between calls to it. Argh!
                                'Associating' is a primitive operation for Python interpreters.
                                Interesting. If I may be so bold as to ask, is it for C code, C
                                compilers, and/or C programs?

                                snip.

                                All due respect.

                                Comment

                                Working...