RE: anything like C++ references?

Discussion in 'Python' started by Tim Peters, Jul 13, 2003.

  1. Tim Peters

    Tim Peters Guest

    [Stephen Horne]
    > ...
    > The fact is that 'assignment' has a common meaning separate from the
    > choice of programming language,


    Well, that's not a fact, although there may be much commonality among the
    (necessarily few, if you believe this) programming languages you've used.
    Python's assignment semantics are in fact common among languages
    higher-level than those of the Fortran/COBOL/Algol/C ilk. For examples,
    Lisp, SNOBOL4, Scheme, Smalltalk and Icon are (very) much like Python in
    this respect. So is Java in the end, although the underlying machinery is
    more complicated there.

    > and that the way Python handles name binding means that meaning is not
    > respected by Python for mutable objects.


    Python's assignment semantics don't vary according to object type.

    > ...
    > Python, however, does not respect this meaning.


    This doesn't say more than that Python works differently than the languages
    you've used. It really isn't a question of respect <wink>.

    > It uses an arbitrary distinction based on whether or not the object
    > has internals that can be usefully in-place modified, and uses that
    > distinction to vary the effect of assignment in an arbitrary,
    > inconsistent and error-prone way.


    It's deliberate and thoroughly consistent. Any assignment semantics are
    error-prone in some contexts, though (Python's included -- side effects are
    like that). The simplicity and absolute consistency of Python-style
    assignment semantics are probably easiest for first-time programmers to pick
    up, and certainly dead easy for people coming from Lisp (etc) to pick up --
    people coming from C (etc) often struggle with inappropriate expectations at
    first.

    > The need for a distinct tuple type is a symptom of the arbitrary
    > nature of this.


    Python's assignment semantics have nothing to do with mutability versus
    immutability. The latter is a type-dependent distinction; assignment
    semantics in Python don't depend on object type in any way.

    > ...
    > I've already posted too much on this, so this is going to be the end
    > to it. But Pythons semantics with regard to mutable and immutable
    > objects are simply bizarre.


    Hmm. Mutable objects can be mutated, and immutable objects cannot be
    mutated. That doesn't seem bizarre.

    > A historic justification may be plausible and backward compatibility
    > is then an important issue, but I really cannot accept claims that
    > Python is doing the right thing here.


    Well, I can assure you Guido wouldn't change anything about Python's
    assignment semantics if were able to do it all over from scratch. That's a
    puzzle for you to work out, then: is Guido unique, or are all Dutch people
    that stupid <wink>?
    Tim Peters, Jul 13, 2003
    #1
    1. Advertising

  2. Stephen Horne <> writes:

    > 1. Why are dictionarys called dictionaries (rather than references to
    > dictionarys or whatever)? Similar for lists and class instances.


    Because they are the values themselves, instead of being references to
    values. These values (like all other values) are objects, though,
    which means they have identity, state, and behaviour.

    You might be thinking of values which only have state and
    behaviour. Such values are not supported in Python - objects always
    have an identity.

    > 2. Why are the values of mutable objects always forced to be accessed
    > via a pointer (or reference or whatever)?


    Because all variables are references to objects. In Python, you cannot
    have a variable that *is* a value - variables are always *bound* to
    values, and accessing the variable yields the associated value. The
    values exist independently from the variables they are bound to, and a
    single value may be bound to different variables.

    > 3. Why is there no way to reference an immutable object via a
    > pointer, other than stuffing it into a mutable object designed for
    > some purpose other than simple pointer behaviour?


    But there is: If I do

    a = 1
    b = a

    then b *refers* the same value that a refers to. That is, the values
    associated with a and b have the same identity.

    > This excuse is, as I already said, invalid.


    Which excuse? You have only listed questions in this message, not
    excuses.

    Regards,
    Martin
    Martin v. =?iso-8859-15?q?L=F6wis?=, Jul 13, 2003
    #2
    1. Advertising

  3. Tim Peters

    Bryan Guest


    > 3. Why is there no way to reference an immutable object via a
    > pointer, other than stuffing it into a mutable object designed for
    > some purpose other than simple pointer behaviour?
    >


    >>> a = (1, 2, 3)
    >>> b = a
    >>> id(a)

    15471760
    >>> id(b)

    15471760
    >>> print b[1]

    2
    >>>



    i just referenced an immutable object via a "pointer" and i __did_not__
    stuff it into a mutable object as you say.
    a and b "point" to the same object.

    bryan
    Bryan, Jul 13, 2003
    #3
  4. Tim Peters

    Ian Bicking Guest

    I don't know why I'm participating, but it's feels hard to stay out of
    this one...

    On Sun, 2003-07-13 at 17:17, Martin v. Löwis wrote
    > > 3. Why is there no way to reference an immutable object via a
    > > pointer, other than stuffing it into a mutable object designed for
    > > some purpose other than simple pointer behaviour?

    >
    > But there is: If I do
    >
    > a = 1
    > b = a
    >
    > then b *refers* the same value that a refers to. That is, the values
    > associated with a and b have the same identity.


    I think, then, that Stephen maybe wants to do something like:

    >>> a = ref(1)
    >>> b = a
    >>> b is a

    True
    >>> a + 2

    3
    >>> a = 5
    >>> b

    5

    And so on. This is all quite doable in Python (implementation of ref
    left to the reader), except for the "a = 5" part. Instead you'd have to
    do something like "a.set(5)". Even though it is doable, of course, it's
    by way of clever hacks.

    The problem that Stephen is not appreciating is that this sort of
    reference implies that "a" is a typed variable -- of type "pointer",
    somehow implicitly declared when it was initially assigned a ref
    object. (He's not alone, because just a little while ago someone
    proposed a way to overload the meaning of "=", to achieve largely the
    same functionality)

    It might not be quite as ugly-seeming if we explicitly declared "a" as a
    pointer. Besides the disinclination of people to add variable
    declarations (though "global" already is one), it's more difficult
    because there's now a new type that has to be usable everywhere, the
    pointer type. All Python's code that expected, say, integers would have
    to also be ready to dereference the argument and then use it. It could
    probably be made seamless at the Python level fairly easily, but the C
    would be annoying, no doubt.

    One might think you could just use the references that already exists
    (since variables are references, and everything is passed by
    reference). But that's messed up, because that'd mean:

    >>> b = 2
    >>> pointer a
    >>> a = 2
    >>> a is b

    True
    >>> a = 5
    >>> b

    5

    The ability to redefine the integers is obviously not a good feature
    (though I remember someone saying you can accidentally do some stuff
    like this in C extensions).

    Anyway, that's my attempt at empathy with Stephen, if not agreement. If
    he is wanting something other than what I've described, he should give
    other examples, because code examples are better than words.

    Ian
    Ian Bicking, Jul 14, 2003
    #4
  5. Qualified appology (was Re: anything like C++ references?)

    Appols for changing the subject while still staying in the same topic
    - I just wanted to highlight this over my earlier boneheaded posts.

    This is a post of heavily qualified appologies. In summary, I've been
    thick-headed but I still believe that Python is doing the wrong thing.

    I hope I've actually achieved a degree of sanity on this attempt ;-)


    On 14 Jul 2003 00:17:19 +0200, (Martin v. Löwis)
    wrote:

    >Stephen Horne <> writes:
    >
    >> 1. Why are dictionarys called dictionaries (rather than references to
    >> dictionarys or whatever)? Similar for lists and class instances.

    >
    >Because they are the values themselves, instead of being references to
    >values. These values (like all other values) are objects, though,
    >which means they have identity, state, and behaviour.


    I've said my piece on meanings derived from computer science (and in
    turn from mathematics, as it happens - variables as placeholders for
    values predate electronic computers by quite some time.

    People have tried to point out that copy-on-write is redundant for
    immutable objects, but I've been too thick-headed. Sorry for that.

    Even so, you can think of immutable objects as achieving 'expected'
    assignment semantics simply because they are immutable. That does not
    apply to mutable objects. So you can claim that Python behaviour is
    consistent within itself, but only by claiming that it is consistently
    different from this 'expected' behaviour.

    Some people have already said that the word 'expected' is a fallacy -
    that computer science doesn't have fixed definitions for these things.
    Some have already named various languages which deviate in similar
    ways in either some or all cases. But these languages are actually
    deviating, either by convention or (in older cases) due to the
    limitations of past machines. That's not the same thing as saying they
    are doing 'the right thing' or that the computer science definitions
    don't exist - all it means is that a lot of programmers who are
    experienced in certain languages are familiar with this error-prone
    system and used to compensating for its problems. But a modern
    high-level language should do 'the right thing' - it should not be the
    programmers job to make allowances for an outdated workaround designed
    to give maximum performance by default on old machines irrespective of
    reliability.

    >> 2. Why are the values of mutable objects always forced to be accessed
    >> via a pointer (or reference or whatever)?

    >
    >Because all variables are references to objects.


    All variables are implemented as references, but that is not the same
    as saying that all values are references. As Guidos own words reveal
    (I already posted the link twice) the purpose of using immutables
    tuples is performance optimisation to save copying while still
    defending against against accidental mutation (ie it provides the
    computer theory standard assignment semantics efficiently).

    The same rationale should equally apply to all types, including the
    mutable types.

    In particular, it should apply to class instances. I shouldn't need to
    create separate mutable and immutable variants of classes to get this
    as the mutability of content should be the decision of the container
    rather than the content. I shouldn't need to force copying of class
    instances in the container for the exact same reason that Guido
    highlights for tuples.

    Guidos own example is actually quite bug prone in its own way. It
    behaves differently depending on whether you pass in the point values
    as tuples or lists. That is potentially a subtle, intermittent,
    hard-to-trace error waiting to happen. You can say 'validation' all
    you want. I did that back in the PEP238 days, and didn't get much
    support. What's good for the goose is good for the gander.

    >> This excuse is, as I already said, invalid.

    >
    >Which excuse? You have only listed questions in this message, not
    >excuses.


    Looking back, I was unfair to Tim Peters. The 'excuse' was percieved
    (mainly because I'm frustrated trying to get my point across, and
    because a circularity that arose (unless I was thick-headed about that
    too) in another post. I said 'if a then b', someone said 'no - a is
    wrong because c', I said 'ah, but if c then d' and the reply to that
    was 'no - c is wrong because a' - or at least I think that's what
    happened. Possibly I just need some sleep.

    I thought Tim was also guilty of this, but looking back I was wrong.
    Sorry, Tim.

    However, revisiting his post I still disagree with it...

    """
    It's deliberate and thoroughly consistent. Any assignment semantics
    are
    error-prone in some contexts, though (Python's included -- side
    effects are
    like that). The simplicity and absolute consistency of Python-style
    assignment semantics are probably easiest for first-time programmers
    to pick
    up, and certainly dead easy for people coming from Lisp (etc) to pick
    up --
    people coming from C (etc) often struggle with inappropriate
    expectations at
    first.
    """

    At first glance it looked like Tim was saying 'its all assignment
    semantics rather than type semantics', hence my misjudging him. But
    one way or the other, there is an inconsistency between the behaviour
    of mutable objects and the computer science definitions of 'variable',
    'value' and 'assignment' which does not arise for immutable objects
    (note careful wording - see earlier apology). Having copy-on-write for
    all objects (obviously the actual copying never happening for
    immutables) would be both fully self-consistent and consistent with
    the computer science definitions. The lack of this definitely does
    cause both confusion and errors.

    I also disagree with Tims statement that "Any assignment semantics are
    error-prone in some contexts". OK, mistakes can be made with any
    syntax for anything, but in the context of this discussion it is
    perfectly possible to get the best of both worlds.

    Make pointers/references explicit and make all assignments
    'copy-on-write', and as I said earlier you get both mutability
    protection by default for all types and the ability to reference any
    type indirectly. Avoid the problems that make pointers in C, C++,
    Pascal etc so unreliable and, while perceptions of pointers as being
    inherently bug prone may persist they would be irrational - having
    pointers explicitly for all types would at worst be as bug prone as
    the existing situation where implicit references exist, and in
    particular where mutable types get abused to fake pointer/reference
    capabilities. It needs extra notation, but when mutables are used to
    fake pointers there is extra notation anyway - misleading notation.

    I'm not an anti-side-effect fanatic. I just don't want them to happen
    by default, and I don't have to worry about this every time I use a
    mutable type. And there really is no need for that to happen.
    Stephen Horne, Jul 14, 2003
    #5
  6. On 13 Jul 2003 20:18:25 -0500, Ian Bicking <>
    wrote:

    >I think, then, that Stephen maybe wants to do something like:
    >
    >>>> a = ref(1)
    >>>> b = a
    >>>> b is a

    >True
    >>>> a + 2

    >3
    >>>> a = 5
    >>>> b

    >5
    >
    >And so on. This is all quite doable in Python (implementation of ref
    >left to the reader), except for the "a = 5" part. Instead you'd have to
    >do something like "a.set(5)". Even though it is doable, of course, it's
    >by way of clever hacks.


    Well, during the 'debate', that's the basic idea that involved -
    except that I'd use explicit pointer-dereferencing syntax.

    Imagine, for instance, changing all assignments and other 'copying' to
    use a copy-on-write system. Then add a pointer type and a 'newcopyof'
    operator. And nick the C-style prefix '*' for dereferencing and add
    '&' as a 'make a pointer to this object' operator (absolutely NOT a
    physical memory address).

    >>> a = 5
    >>> b = a
    >>> b is a

    False

    >>> a = &5
    >>> b = a
    >>> *b is *a

    True

    >>> a = &5
    >>> b = newcopyof a # could be "b = &(*a)" in principle
    >>> *b is *a

    False

    >>> a = BadPtr
    >>> b = *a

    Traceback (most recent call last):
    File "<stdin>", line 11, in ?
    BadDeref: pointer does not reference a valid object

    >>> a = *1

    Traceback (most recent call last):
    File "<stdin>", line 12, in ?
    TypeError: object doesn't support dereference operator


    No need for a 'delete' equivalent because of garbage collection. No
    possibility of referencing a bad pointer as there is no way to create
    a bad pointer - except, of course, for the explicit BadPtr (or
    whatever) which throws an exception if dereferenced.

    >The problem that Stephen is not appreciating is that this sort of
    >reference implies that "a" is a typed variable -- of type "pointer",
    >somehow implicitly declared when it was initially assigned a ref
    >object. (He's not alone, because just a little while ago someone
    >proposed a way to overload the meaning of "=", to achieve largely the
    >same functionality)


    No - I'm aware of the issue. When people use lists to fake pointers,
    they already need explicit notation to tell Python what they are
    doing. I'd just rather go back to having explicit pointers, though
    implemented in a way which is appropriate to scripting languages and
    which eliminates the major reliability issues of C-like pointer
    mechanisms.

    Using this approach, I don't need to declare variable types but I do
    need to be explicit about when I'm using pointed-to-values and when
    I'm using the pointers themselves.

    Self-dereferencing pointers might also be nice in some ways, but with
    serious problems. In C++, binding to the referenced object is done in
    the declaration. That can't happen in Python, so a different method
    would be needed - a special assignment operator, probably.

    That then leads to the fundamental flaw. This couldn't be used to do
    what, in C++, it does best - mimicking what Pascal calls 'var'
    parameters.

    If there were a 'procedure' abstraction, distinct from 'function', I
    might be happy for all parameters to be implicitly dereferenced
    pointers - I'd be happy being unable to change the pointer in this
    case (in fact I'd like it enforced) - to get var parameter like
    behaviour. There are nasty subtleties, though (what if someone creates
    a pointer to the parameter, for instance - can it be used to change
    the supposedly fixed pointer?). The C-like approach of just passing a
    pointer as the expected parameter type has the advantage of simplicity
    if nothing else.

    >Anyway, that's my attempt at empathy with Stephen, if not agreement. If
    >he is wanting something other than what I've described, he should give
    >other examples, because code examples are better than words.


    I hope I've explained, now. It wasn't in my mind when I started out,
    but it would certainly be a way to solve what I see as serious
    problems.

    A realistic change for Python? - I doubt it. It could be technically
    feasable, perhaps (a 'from future' thing adding copy-on-write and the
    new operators etc) but interaction with past modules would create
    problems. And with my very limited understanding of Python internals,
    I'm sure I'm missing much bigger problems. Not to mention that at this
    point, the change would probably be so fundamental as to actually
    create a new language.

    This does, however, give an alternative that *could* have been
    plausible (in a parallel universe, perhaps), and which would not have
    resulted in certain common problems that do occur now.
    Stephen Horne, Jul 14, 2003
    #6
  7. On Sun, 13 Jul 2003 22:42:21 GMT, "Bryan" <> wrote:

    >
    >> 3. Why is there no way to reference an immutable object via a
    >> pointer, other than stuffing it into a mutable object designed for
    >> some purpose other than simple pointer behaviour?
    >>

    >
    >>>> a = (1, 2, 3)
    >>>> b = a
    >>>> id(a)

    >15471760
    >>>> id(b)

    >15471760
    >>>> print b[1]

    >2
    >>>>

    >
    >
    >i just referenced an immutable object via a "pointer" and i __did_not__
    >stuff it into a mutable object as you say.
    >a and b "point" to the same object.


    Technically, but what is the point? You can't do pointer-style things
    with it. You can't change the object in any way without changing the
    id, and you can't use the mechanism to, for instance, allow 'var'
    parameters.

    In short, you are showing evidence of the use of pointers internally
    within Python, but that is not the same as providing pointer-like
    semantics.
    Stephen Horne, Jul 14, 2003
    #7
  8. Stephen Horne <> writes:

    > >>>> a = ref(1)
    > >>>> b = a

    [...]
    > >>>> a = 5
    > >>>> b

    > >5

    [...]
    > Well, during the 'debate', that's the basic idea that involved -
    > except that I'd use explicit pointer-dereferencing syntax.


    This is a very bad idea. You want to create a reference to the object
    1? Then I assume that assigning to "a" would *change* the value of 1?
    But 1 is an immutable object, it cannot change!

    > Imagine, for instance, changing all assignments and other 'copying' to
    > use a copy-on-write system.


    That assumes that there is the notion of copying values in the first
    place. Objects, in general, don't support copying - and assignment has
    nothing to do with copying.

    > >>> a = &5
    > >>> b = newcopyof a # could be "b = &(*a)" in principle
    > >>> *b is *a

    > False


    Again, objects don't support copying. For immutable objects (like
    numbers), copying is also a pointless operation: If there where a
    standard .copy method on objects, numbers would return themselves.

    There is no way, in the language, to express that you want different
    copies of the value 5. This is completely different from the notion of
    values in C or C++, where each occurrence of the literal 5 creates a
    new value whose state is 5.

    Regards,
    Martin
    Martin v. =?iso-8859-15?q?L=F6wis?=, Jul 14, 2003
    #8
  9. Tim Peters

    Bryan Guest

    "Stephen Horne" <> wrote in message
    news:...
    > On Sun, 13 Jul 2003 22:42:21 GMT, "Bryan" <> wrote:
    >
    > >
    > >> 3. Why is there no way to reference an immutable object via a
    > >> pointer, other than stuffing it into a mutable object designed for
    > >> some purpose other than simple pointer behaviour?
    > >>

    > >
    > >>>> a = (1, 2, 3)
    > >>>> b = a
    > >>>> id(a)

    > >15471760
    > >>>> id(b)

    > >15471760
    > >>>> print b[1]

    > >2
    > >>>>

    > >
    > >
    > >i just referenced an immutable object via a "pointer" and i __did_not__
    > >stuff it into a mutable object as you say.
    > >a and b "point" to the same object.

    >
    > Technically, but what is the point? You can't do pointer-style things
    > with it. You can't change the object in any way without changing the
    > id, and you can't use the mechanism to, for instance, allow 'var'
    > parameters.
    >


    can you show what functionality is missing by not being able to do
    "pointer-style things"? here are two variables:

    a = (1, 2, 3)
    b = [1, 2, 3]

    one immutable, one mutable. please show an example of what "pointer-style
    things" you would like to do.

    i've read this entire thread so far, and from a practical point of view
    (because that's all i really care about and what pays the bills), i really
    don't understand what the problem is. personally, i don't care about the
    strict definitions of computer science terms and what "variable" or
    "pointer" means. i do care about how fast problems can be solved, how much
    resources must be involved in solving that problem, and how much money can
    be made/saved. for me, python is a winner in all this area. not having
    pointers like c/c++ is such a blessing. i can't believe anyone would even
    suggest that pointers and/or doing things with pointers be brought into
    python. ok... one more time... let's bring this conversation down to
    something practical. please show an example of pointer-style functionality
    in any language that is missing/awkward/complicated in python. i'm not an
    expert in python, i'm just very curious to understand what the true
    practical issue is.

    thanks,

    bryan

    > In short, you are showing evidence of the use of pointers internally
    > within Python, but that is not the same as providing pointer-like
    > semantics.
    >
    Bryan, Jul 14, 2003
    #9
  10. Re: Qualified appology (was Re: anything like C++ references?)

    Stephen Horne wrote:

    > All variables are implemented as references, but that is not the same
    > as saying that all values are references.


    Right. And this is an extremely important point in Python. Variables
    are bindings of names to objects. Objects are entities in and of
    themselves. The object is what is mutable or immutable, not the name.
    Names are transitory.

    --
    Erik Max Francis && && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ The little I know, I owe to my ignorance.
    \__/ Sacha Guitry
    Erik Max Francis, Jul 14, 2003
    #10
  11. Tim Peters

    Adam Ruth Guest

    Re: Qualified appology (was Re: anything like C++ references?)

    Stephen Horne <> wrote in message news:<>...
    > I've said my piece on meanings derived from computer science (and in
    > turn from mathematics, as it happens - variables as placeholders for
    > values predate electronic computers by quite some time.


    The mathematics I'm used to has a very different concept of assignment
    than does a static language like C. Here's why.

    In math there are global unchanging objects called numbers, 1, 2, 3,
    etc. If I have 2 variables, x and y and they both equal 500, then
    they both are names bound to the value 500. They are not each copies
    of the value 500, math has no such concept, there is only one 500.

    C, and most static languages, have the concept of memory location,
    which doesn't exist in math. In C a variable is bound to a memory
    location which contains a value, not like math where the variable
    itself contains the value. Therefore I can have two variables, x and
    y, that point to their own distinct copy of 500 and when I assign a
    value, it copies the 500 into the memory location bound to x.

    Now, what if I have x and y bound the the same memory location? If I
    change X I also change Y. That's not how mathematics works. If X and
    Y are to have to same value, they do so because of some relation to
    their meaning, and they are both bound to 500, not simply because I
    changed the value of X. This is a concept that simply doesn't exist
    in mathematics.

    Python is more like the math form. There is only one instance of the
    number 500 and a name (variable) is bound to it or it isn't. To
    change the value of 500, then I must rebind the name, exactly in
    mathematics. However, Python differs from math in that math doesn't
    have mutable values (well it may when you get into real complex
    calculus, I don't know, never been there).

    Adam Ruth
    Adam Ruth, Jul 14, 2003
    #11
  12. Re: Qualified appology (was Re: anything like C++ references?)

    On 14 Jul 2003 11:44:02 -0700, (Adam Ruth) wrote:

    >Stephen Horne <> wrote in message news:<>...
    >> I've said my piece on meanings derived from computer science (and in
    >> turn from mathematics, as it happens - variables as placeholders for
    >> values predate electronic computers by quite some time.

    >
    >The mathematics I'm used to has a very different concept of assignment
    >than does a static language like C. Here's why.
    >
    >In math there are global unchanging objects called numbers, 1, 2, 3,
    >etc. If I have 2 variables, x and y and they both equal 500, then
    >they both are names bound to the value 500. They are not each copies
    >of the value 500, math has no such concept, there is only one 500.


    Yes.

    Mathematics does have assignment - it had assignment long before
    electronic computers existed because algorithms were a concept studied
    in mathematics long before computers existed.

    If in mathematics, if I have one variable a defined as representing
    the set {1, 2, 3} and a variable y also defined as representing the
    set {1, 2, 3} and I decide to change y to {1, 2, 4} then that
    redefinition process does not change the value {1, 2, 3} to {1, 2, 4}.
    It only changes what the variable y is currently taken to represent.

    Values cannot be mutable in mathematics.

    In Python, *objects* can be mutable. Values cannot be mutable because
    they are values - something defined in mathematics. 1 cannot become 2.
    But a variable can be reassigned to represent something else. In-place
    modification of part of an object is a practical way of replacing one
    value with another.

    Thus, if I write...

    >>> a=[1,2,3]
    >>> a[2]=4
    >>> a

    [1, 2, 4]

    Nothing is wrong. The in-place modification of part of the object that
    a is bound to is basically a convenient shorthand for reassigning the
    whole value of a. The value now bound to a is [1, 2, 4] rather than
    [1, 2, 3]. No value has mutated. Nothing is wrong in mathematical
    terms. The fact that we are using something called an object (or a
    pointer to an object or whatever) to implement the binding to a value
    is unimportant.

    >>> a=[1,2,3]
    >>> b=a
    >>> b[2]=4
    >>> b

    [1, 2, 4]
    >>> a

    [1, 2, 4]

    Because the variable b has been bound to an object (*NOT* a value),
    the mutation has a side-effect. Changing the value bound to the
    variable b also changes the value bound to a. This does *NOT* happen
    in mathematics, because there is no such thing as an object.

    Reassigning one variable in mathematics never implicitly redefines
    another.

    In short, this no longer implements a binding of values to variables
    because of the side-effect of changing the value bound to a when you
    change the value bound to b. The implementation detail of how the
    binding from variables to values is achieved (by binding to objects)
    has changed the results of running the algorithm.

    In a true functional language, variables are not mutable. It doesn't
    matter in the slightest if binding of variables is handled by copying
    pointers to objects instead of copying objects - it is irrelevant
    because copying pointers to objects achieves exactly the same thing as
    copy the objects themselves - it implements a binding of value to
    variable.

    The object bound to a variable in Python is a low-level implementation
    concept. From Guidos own words, we can see that he (at least at one
    point) recognised that binding to objects in a context where those
    objects can be mutable is confusing and error-prone.

    The value bound to a function in mathematics is a high-level concept.

    I thought Python was *supposed* to be an very high-level language?

    Even C++ is higher level that this. The C++ standard libraries I've
    used will optimise assignment of strings by merely copying pointers.
    The sequence of events you get is something like this...

    std::string x ("Hello");
    // x bound to object containing value "Hello"

    std::string y (x);
    // y bound to same object as x, but with an indication that
    // sharing is happening.

    y [4] = '!';
    // A write to y, with the purpose of changing the value that y
    // is bound to but not changing the value that x is changed to.
    // Thus a copy of the object containing "Hello" is made and
    // bound to y before applying the change. This is called
    // copy-on-write.

    In short, C++ can and often does use the pointer-copying optimisation
    in the standard library. But it does so in such a way that the low
    level binding of variables to objects implements the high level
    binding of variables to values correctly.


    It is clear now that many people are highly committed in the binding
    of variables to objects done in a way that does not implement binding
    of variables to values - though there seems to be fuzzy thinking used
    against me just as much as my own fuzzy thinking earlier. For
    instance...

    On 14 Jul 2003 07:39:57 +0200, (Martin v. Löwis)
    wrote:
    : And so does mine: Variables are *not* containers of values, in
    : traditional mathematics. They are bound to values instead.

    Python does not bind values to variables. It binds objects to
    variables. Objects are how values are implemented, but they are not
    the same thing.

    In computer science and mathematics, the whole point of variables is
    to bind a variable to a *value*. Terms such as 'store location' and
    'object' are about *implementing* that binding from variable to value.

    In mathematics, it doesn't matter whether you talk of variables being
    placeholders for values or whether you talk of them being bound to
    values. The two are equivalent, because mathematics has no concept of
    objects as an implementation detail. Both terms are in common use.

    In support of this, I quote someone arguing against me...

    On 14 Jul 2003 11:44:02 -0700, (Adam Ruth) wrote:

    """
    C, and most static languages, have the concept of memory location,
    which doesn't exist in math. In C a variable is bound to a memory
    location which contains a value, not like math where the variable
    itself contains the value. Therefore I can have two variables, x and
    y, that point to their own distinct copy of 500 and when I assign a
    value, it copies the 500 into the memory location bound to x.
    """

    "not like math where the variable itself CONTAINS the value"

    In addition, note that C++ does not copy the value. It copies a
    representation of the value. Thus when you say two variables contain
    "their own distinct copy of 500" what you are really saying is that
    two variables contain "their own distinct copy of a representation of
    the value 500". That is why you can use the operator '==' to test if
    two variables contain the same value - or rather in-store
    representations that represent the same value.


    """
    In math there are global unchanging objects called numbers, 1, 2, 3,
    etc. If I have 2 variables, x and y and they both equal 500, then
    they both are names bound to the value 500. They are not each copies
    """

    No - they are not objects, or store locations. They are global
    unchanging values. And yes, variables *are* bound to values - *not*
    objects.

    """
    Python is more like the math form. There is only one instance of the
    number 500 and a name (variable) is bound to it or it isn't. To
    change the value of 500, then I must rebind the name, exactly in
    mathematics. However, Python differs from math in that math doesn't
    have mutable values (well it may when you get into real complex
    calculus, I don't know, never been there).
    """

    Mutable values don't exist at all. Mutable objects do. When you mutate
    a part of an object, that object now represents a new value.

    Its a shorthand in Python for something that is perfectly valid in
    mathematics - but not if the binding of other variables to values is
    affected.

    BTW - "real complex" is a contradiction in terms ;-)


    Anyway, if you so love your variables binding to objects done in a way
    that does not correctly implement variables binding to values for
    mutable objects, fine. It simply means that Pythons users have to fuss
    about the implementation of Python instead of getting on with their
    applications logic, and that it will continue to cause confusion and
    errors on an ongoing basis.
    Stephen Horne, Jul 14, 2003
    #12
  13. Mon, 14 Jul 2003 04:51:10 +0100, Stephen Horne <>:
    > On Sun, 13 Jul 2003 22:42:21 GMT, "Bryan" <> wrote:
    >>i just referenced an immutable object via a "pointer" and i __did_not__
    >>stuff it into a mutable object as you say.
    >>a and b "point" to the same object.

    > Technically, but what is the point? You can't do pointer-style things
    > with it. You can't change the object in any way without changing the
    > id, and you can't use the mechanism to, for instance, allow 'var'
    > parameters.
    > In short, you are showing evidence of the use of pointers internally
    > within Python, but that is not the same as providing pointer-like
    > semantics.


    It looks like you've almost reached understanding, though you've been
    given a bad start with a very idiosyncratic and monolingual
    understanding of what "computer science" teaches--that was certainly not
    in the classes I took, but apparently yours were different.

    Python variables are directly equivalent to pointers in C, with some
    crippling limitations by C standards. They only ever point to valid
    objects that are dynamically allocated on the heap, never to anything
    else. Even None is an object. Those objects include what Python calls
    "integers", which are really object wrappers around a C int variable.
    Assignment only allows you to change a variable to point to some other
    valid object.

    At no point in Python do you ever have direct access to a C value
    variable, or to a reference to a variable. They just don't exist. So
    there are some things you can do in C that you can't do the same way in
    Python. And that's *by intention*. It isn't a bad thing, it was done
    for good design reasons, reasons well-tested by previous languages like
    Lisp.

    If you really must do a "pointer-style thing" in Python, you can do
    this, which is semantically equivalent to the C version:
    >>> def incr(pointerToVar):

    .... pointerToVar[0] += 1
    ....
    >>> a = [0]
    >>> b = a
    >>> incr(a)
    >>> a[0]

    1
    >>> b[0]

    1
    >>> incr(a)
    >>> a[0]

    2
    >>> b[0]

    2

    I hope no Pythonista would actually *do* that, but it's working code,
    and the foo[0] is similar to explicit referencing and dereferencing of
    pointers.

    Since every operation in Python operates on pointers, there's no use
    in having a special syntax for it. You don't need all the * and & and
    -> line noise.

    Stop trying to make Python into C/C++, and you'll be happier with it.
    Or stop using Python, if you really don't like the design philosophy.
    There are plenty of Algol-derived languages out there. PHP and
    especially Perl are more C-like in their internal logic, and you might
    find them more pleasant.

    --
    <a href="http://kuoi.asui.uidaho.edu/~kamikaze/"> Mark Hughes </a>
    "The computer is incredibly fast, accurate, and stupid.
    Man is unbelievably slow, inaccurate, and brilliant.
    The marriage of the two is a force beyond calculation." -Leo Cherne
    Mark 'Kamikaze' Hughes, Jul 15, 2003
    #13
  14. On Mon, 14 Jul 2003 00:07:44 -0700, Erik Max Francis <>
    wrote:

    >Stephen Horne wrote:
    >
    >> Imagine, for instance, changing all assignments and other 'copying' to
    >> use a copy-on-write system. Then add a pointer type and a 'newcopyof'
    >> operator. And nick the C-style prefix '*' for dereferencing and add
    >> '&' as a 'make a pointer to this object' operator (absolutely NOT a
    >> physical memory address).

    >
    >The problem is that this misses the point that Python is not C++. You
    >shouldn't try grafting syntaxes and approaches that make Python look
    >more like C++, you should be learning to use Python on its own merits.


    Not true.

    If you eliminate all violations of the idea of variables bound to
    values (basically the whole point of my thread), then mutable
    containers cannot achieve the same thing.

    If a copy-on-write scheme is added to Python, you'd get the following
    results from using mutable containers...

    >>> a = [1, 2, 3]
    >>> b = a
    >>> b[2] = 4
    >>> a

    [1, 2, 3]
    >>> b

    [1, 2, 4]

    That is, mutability of the list object could be used to conveniently
    and efficiently rebind the variable b (in this case to the value [1,
    2, 4]) but that doesn't implicitly rebind the variable a which has
    nothing to do with this assignment. In the implementation, Python
    would create a copy of the object bound to [1, 2, 3] just in time to
    apply the change that object, without affecting the object that a is
    bound to.

    Efficient, and it implements the variable-bound-to-value concept.

    Having done this, there would be a need for a way of indirectly
    referencing objects. You wouldn't be able to abuse containers for this
    goal. Pointers are the logical way to achieve the goal of indirect
    referencing - they don't need to be associated with a type of
    container which may have nothing to do with the problem, and they can
    be used to reference *any* type of object.

    >Or, to put it another way, if you want to program in C++, why not use
    >C++?


    I don't want to program in C++ (though sadly I have to).

    The concept of a pointer as an indirect way of referencing an object,
    however, is useful. It isn't just a C++ concept. It is a widely used
    concept from many languages which has gone out of fashion, mainly
    because of the low level detail of how pointers are implemented in
    languages such as C++ (ie simple store addresses).

    I don't want the C++ bug-prone implementation of pointers. I want
    something which allows indirect referencing of objects in a logical
    and safe, high level way - and something which doesn't require the
    language to break the principle of variables bound to values.

    The fact that pointers are generally useful can be seen in the regular
    abuse of single item lists to fake the functionality of pointers.

    If people are routinely faking the abstraction, maybe that is because
    it is a useful abstraction to have. Maybe it would be better to
    support it explicitly instead of forcing people to use tricks and
    hacks.
    Stephen Horne, Jul 15, 2003
    #14
  15. On Mon, 14 Jul 2003 06:28:09 GMT, "Bryan" <> wrote:

    >
    >"Stephen Horne" <> wrote in message
    >news:...
    >> On Sun, 13 Jul 2003 22:42:21 GMT, "Bryan" <> wrote:
    >>
    >> >
    >> >> 3. Why is there no way to reference an immutable object via a
    >> >> pointer, other than stuffing it into a mutable object designed for
    >> >> some purpose other than simple pointer behaviour?
    >> >>
    >> >
    >> >>>> a = (1, 2, 3)
    >> >>>> b = a
    >> >>>> id(a)
    >> >15471760
    >> >>>> id(b)
    >> >15471760
    >> >>>> print b[1]
    >> >2
    >> >>>>
    >> >
    >> >
    >> >i just referenced an immutable object via a "pointer" and i __did_not__
    >> >stuff it into a mutable object as you say.
    >> >a and b "point" to the same object.

    >>
    >> Technically, but what is the point? You can't do pointer-style things
    >> with it. You can't change the object in any way without changing the
    >> id, and you can't use the mechanism to, for instance, allow 'var'
    >> parameters.
    >>

    >
    >can you show what functionality is missing by not being able to do
    >"pointer-style things"? here are two variables:
    >
    >a = (1, 2, 3)
    >b = [1, 2, 3]
    >
    >one immutable, one mutable. please show an example of what "pointer-style
    >things" you would like to do.


    In my view, mutability should be a property of *objects* - not the
    same as values, in the pedantic language that has become necessary in
    this thread. The existence of mutability shouldn't break the principle
    of variables being bound to values.

    This is my point. Pointer types are a side issue - something that
    becomes necessary (or rather more obviously important) if the
    principle of variables being bound to values is respected. This
    doesn't mean that Python can't use binding of variables to objects as
    an implementation, but that implementation shouldn't be visible
    (except for performance, and for operations that explicitly deal with
    objects rather than values) in the results.

    Starting from your example, I'd want to see results like this...

    >>> a = [1, 2, 3]
    >>> b = a
    >>> c = (1, 2, 3)
    >>> d = c
    >>> b[2] = 4
    >>> a

    [1, 2, 3]
    >>> b

    [1, 2, 4]
    >>> d[2] = 4

    Traceback (most recent call last):
    File "<stdin>", line 8, in ?
    TypeError: object doesn't support item assignment


    Having done this, mutable objects could not be abused to give
    pointer-style functionality (a fact of life at the moment) so the need
    for real explicit pointers should become obvious.

    >i've read this entire thread so far, and from a practical point of view
    >(because that's all i really care about and what pays the bills), i really
    >don't understand what the problem is. personally, i don't care about the
    >strict definitions of computer science terms and what "variable" or
    >"pointer" means. i do care about how fast problems can be solved, how much
    >resources must be involved in solving that problem, and how much money can
    >be made/saved. for me, python is a winner in all this area. not having
    >pointers like c/c++ is such a blessing. i can't believe anyone would even
    >suggest that pointers and/or doing things with pointers be brought into
    >python. ok... one more time... let's bring this conversation down to
    >something practical. please show an example of pointer-style functionality
    >in any language that is missing/awkward/complicated in python. i'm not an
    >expert in python, i'm just very curious to understand what the true
    >practical issue is.


    There is none that is currently missing because mutable objects can be
    abused to create the required effect. If Python respected the concept
    of variables being bound to values, though, that wouldn't be true.

    You wouldn't be able to write...

    >>> def f(x) :

    .... x[0] += 1
    ....
    >>> a = [1]
    >>> f(a)


    Or rather you could, but you'd get...

    >>> a

    [1]

    ....and not...

    >>> a

    [2]

    So instead of abusing lists, you'd have to use an explicit pointer
    type...

    >>> def f(x) :

    .... *x += 1
    ....
    >>> a = 1
    >>> f(&a)
    >>> a

    2

    Note - in many cases, you could return multiple values and avoid the
    need for pointers. That wouldn't be the case, however, for objects
    which don't support copying.

    It *might* be possible to pass such an object directly into a function
    (depending on how the variable-to-value binding is implemented) but
    modifying the parameter would require that it binds to a new object -
    a copy of the original object - to prevent the mutation of the callers
    variables. Passing the parameter and returning it *might* be
    acceptable, but modifying it within the function would require copying
    of the object.

    As there are a number of important object types that don't (and
    shouldn't) support copying, this wouldn't be a trivial concern.
    Stephen Horne, Jul 15, 2003
    #15
  16. On 14 Jul 2003 23:31:56 GMT, (Mark
    'Kamikaze' Hughes) wrote:

    > It looks like you've almost reached understanding, though you've been
    >given a bad start with a very idiosyncratic and monolingual
    >understanding of what "computer science" teaches--that was certainly not
    >in the classes I took, but apparently yours were different.


    Really. My computer science lessons were taught in a way that
    respected the source of most of the theory in mathematics -
    algorithms, Church's lambda calculus and that kind of stuff.

    What did your lessons teach?

    > Since every operation in Python operates on pointers, there's no use
    >in having a special syntax for it. You don't need all the * and & and
    >-> line noise.


    The point of the thread is not pointers - they are a side issue.

    When you use variables, you are using a concept from mathematics. In
    mathematics, variables bind to values. All values are immutable.

    Python binds variables to objects, not values. For immutable objects
    this is an unimportant implementation detail. For mutable objects, it
    breaks the mathematical principle of variables being bound to values.

    > Stop trying to make Python into C/C++, and you'll be happier with it.
    >Or stop using Python, if you really don't like the design philosophy.
    >There are plenty of Algol-derived languages out there. PHP and
    >especially Perl are more C-like in their internal logic, and you might
    >find them more pleasant.


    This is bogus.

    I don't want Python to become C or C++. I want Python to respect
    principles that come from mathematics and computer science. Not for
    reasons of theory pedanticism, but because the current system can and
    does regularly cause confusion and errors.

    The fact that Python claims to be a very high level language, and yet
    you have to worry about the binding of variables to objects -
    something that should be a low level implementation detail - has very
    real everyday implications.

    Respect the idea of variables binding to values and suddenly the need
    for pointers becomes more obvious. You cannot abuse mutable objects to
    fake pointer functionality (another everyday fact of Python
    programming) if the binding of variables to values (rather than just
    objects) is respected.
    Stephen Horne, Jul 15, 2003
    #16
  17. Re: Qualified appology (was Re: anything like C++ references?)

    On Mon, 14 Jul 2003 23:22:18 +0000 (UTC), Adam Ruth
    <> wrote:

    ><snip buncha stuff>
    >
    >I started to write a response, and then I realized that it would be
    >pointless. We're just gonna have to be happy in each other's ignorance.
    >Our skulls are too thick for each other's arguments.
    >
    >I'm gonna stick with the idea that we're both wrong.
    >
    >Even-though-your-more-wrong-erly yours,


    Whatever. I've admitted the mistakes that I recognise I've made. If
    you think there are other mistakes that I haven't recognised, its up
    to you whether you explain them or not.

    Just 'cause I can't sleep the last few nights, doesn't mean anyone has
    to read my rantings, much less reply. Even if they *are* accurate
    rantings ;-)
    Stephen Horne, Jul 15, 2003
    #17
  18. Stephen Horne <> writes:

    > Write...
    >
    > x = classname()
    > y = x
    >
    > ... and that would be an error.

    [...]
    > However...
    >
    > x = &classname()
    > y = x
    >
    > ... and everything is fine.


    If any kind of implicit reference assignment would be an error, then I
    assume

    x = classname()
    x.foo()

    would also be an error? because that assigns a reference of the object
    to the implicit 'self' parameter of the method?

    > > This is completely different from the notion of
    > >values in C or C++, where each occurrence of the literal 5 creates a
    > >new value whose state is 5.

    >
    > Not true. Each occurence of the literal 5 creates a new 'symbol' which
    > represents the value 5. The immutability of values is preserved in
    > C++.


    That is not true. There are no "symbols" in C beyond those that you
    use to name functions and global variables. Every occurrence of an
    integer literal *does* create a temporary object, every time the
    literal is *executed*.

    Regards,
    Martin
    Martin v. =?iso-8859-15?q?L=F6wis?=, Jul 15, 2003
    #18
  19. Stephen Horne wrote:

    > If people are routinely faking the abstraction, maybe that is because
    > it is a useful abstraction to have. Maybe it would be better to
    > support it explicitly instead of forcing people to use tricks and
    > hacks.


    But the issue I'd raise is why you think that modification of an object
    in a mutable container is "faking the abstraction." C and C++ have the
    concept of a pointer, and that's well and good for those languages.
    Python doesn't, and doesn't need it. If you want the effect of a C or
    C++ pointer in Python, you can get it through very simple means. The
    reason why it's not necessary is that, as has been pointed out,
    essentially _all_ "variables" in Python are references/pointers -- they
    refer, perhaps non-uniquely, to objects which have identity beyond the
    references that have them. This isn't the best way to explain how
    Python's variable system works to newbies, because it introduces
    confusion (it's not quite call by value and it's not quite call by
    reference; it's call by value where the values are references), but any
    variable "points" to a reference.

    The equivalent concept to what you're getting at is one of mutability,
    and that is handled utterly distinctly than it is in C or C++. Someone
    familiar with Python might argue that it's C++ that's "faking the
    abstraction," not the other way around.

    They're very different ways of doing things; insisting that the square
    peg should be rounded worries people who liked the square hole just
    fine.

    --
    Erik Max Francis && && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ The actor is not quite a human being -- but then, who is?
    \__/ George Sanders
    Erik Max Francis, Jul 15, 2003
    #19
  20. Tim Peters

    Tim Roberts Guest

    Re: Qualified appology (was Re: anything like C++ references?)

    Stephen Horne <> wrote:
    >
    >Whatever. I've admitted the mistakes that I recognise I've made. If
    >you think there are other mistakes that I haven't recognised, its up
    >to you whether you explain them or not.
    >
    >Just 'cause I can't sleep the last few nights, doesn't mean anyone has
    >to read my rantings, much less reply. Even if they *are* accurate
    >rantings ;-)


    By the way, I would like to state for the record my amazement at how civil
    and intellectual this debate remained, even though there are some very
    strongly felt and completely contradictory opinions on both sides. It is
    quite rare that one finds a netnews newsgroup where this kind of debate can
    go on without collapsing into valueless flame wars.

    Whether or not I agree with you, you have made me think. That's worth the
    price of my Internet connection this month.
    --
    - Tim Roberts,
    Providenza & Boekelheide, Inc.
    Tim Roberts, Jul 15, 2003
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ian Bicking

    RE: anything like C++ references?

    Ian Bicking, Jul 12, 2003, in forum: Python
    Replies:
    54
    Views:
    1,057
    Christos TZOTZIOY Georgiou
    Jul 22, 2003
  2. Dave Brueck

    Re: anything like C++ references?

    Dave Brueck, Jul 13, 2003, in forum: Python
    Replies:
    4
    Views:
    346
    =?ISO-8859-1?Q?Hannu_Kankaanp=E4=E4?=
    Jul 14, 2003
  3. David McNab

    Re: anything like C++ references?

    David McNab, Jul 13, 2003, in forum: Python
    Replies:
    19
    Views:
    487
    Christos TZOTZIOY Georgiou
    Jul 18, 2003
  4. Michael Chermside

    RE: anything like C++ references?

    Michael Chermside, Jul 14, 2003, in forum: Python
    Replies:
    2
    Views:
    257
    Michael Hudson
    Jul 15, 2003
  5. Replies:
    5
    Views:
    305
    Stephen Horne
    Jul 17, 2003
Loading...

Share This Page