Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

why cannot assign to function call

93 views
Skip to first unread message

scsoce

unread,
Dec 29, 2008, 1:01:38 AM12/29/08
to pytho...@python.org
I have a function return a reference, and want to assign to the
reference, simply like this:
>>def f(a)
return a
b = 0
* f( b ) = 1*
but the last line will be refused as "can't assign to function call".
In my thought , the assignment is very nature, but why the interpreter
refused to do that ?

thks


James Mills

unread,
Dec 29, 2008, 1:08:22 AM12/29/08
to scsoce, pytho...@python.org

That's exactly right. You _cannot_ assign to a function call.
This is invalid in just about _all_ languages.

Assignments are generally bound to a variable.

>>> def f(a):
... return a
...
>>> b = 0
>>> x = f(b)
>>> x
0
>>>

cheers
James

r

unread,
Dec 29, 2008, 1:14:36 AM12/29/08
to

because all you need to do is
>>> b = 1

trying to change the return value of a function before you even "know
what it is" so to speak, defeats the whole purpose of sending it there
in the first place. just assign the variable to a new value. Thats my
common sense answer, maybe somebody can give a technical one :)

Erik Max Francis

unread,
Dec 29, 2008, 1:56:27 AM12/29/08
to
scsoce wrote:

Because, as in most languages, it's not even clear what you might mean
by this syntax. It doesn't have any meaning; assignments are made to
variables, not the results of function calls.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
Only love is worth the risk
-- Oleta Adams

Bruno Desthuilliers

unread,
Dec 29, 2008, 4:07:00 AM12/29/08
to
scsoce a écrit :

> I have a function return a reference, and want to assign to the
> reference,

You have a function that returns an object. You can't "assign" to an
object - this makes no sense.

I'm afraid you are confusing Python's name/object bindings with C
pointers or C++ references.

John Machin

unread,
Dec 29, 2008, 4:34:15 AM12/29/08
to
On Dec 29, 5:01 pm, scsoce <scs...@gmail.com> wrote:
> I have a function return a reference,

Stop right there. You don't have (and can't have, in Python) a
function which returns a reference that acts like a pointer in C or C+
+. Please tell us what manual, tutorial, book, blog or Usenet posting
gave you that idea, and we'll get the SWAT team sent out straight
away.

> and want to assign to the
> reference, simply like this:
>  >>def f(a)
>           return a

That's not a very useful function, even after you fix the syntax error
in the def statement. Would you care to give us a more realistic
example of what you are trying to achieve?

>      b = 0
>     * f( b ) = 1*

Is the * at the start of the line meant to indicate pointer
dereferencing like in C? If not, what is it? Why is there a * at the
end of the line?

> but the last line will be refused as "can't assign to function call".
> In my thought , the assignment is very nature,

Natural?? Please tell us why you would want to do that instead of:

b = 1

> but  why the interpreter
> refused to do that ?

Because (the BDFL be praised!) it (was not, is not, will not be) in
the language grammar.

anthon...@gmail.com

unread,
Dec 29, 2008, 10:46:26 AM12/29/08
to

Probably the closest thing you are going to get in Python would be the
following:

>>> class C:
... pass
...


>>> def f(a):
... return a
...

>>> b = C()
>>> b.value = 0
>>> b.value
0
>>> f(b).value = 1
>>> b.value
1

But as others have pointed out, Python is not C/C++, and shouldn't be
treated as such.

Aaron Brady

unread,
Dec 29, 2008, 11:03:54 AM12/29/08
to

'Why' is a long question. The syntax has advantages and disadvantages
(pros and cons), which weigh different amounts in different
languages. In Python, the cons weigh more. In C, the pros weigh
more. The short answer is, there is no such thing as assigning to
objects, only to variables.

You are talking like it could save you ten lines of code or something.

Scott David Daniels

unread,
Dec 29, 2008, 2:05:52 PM12/29/08
to
John Machin wrote:
> On Dec 29, 5:01 pm, scsoce <scs...@gmail.com> wrote:
>> I have a function return a reference,
>
> Stop right there. You don't have (and can't have, in Python) a
> function which returns a reference that acts like a pointer in C or C+
> +. Please tell us what manual, tutorial, book, blog or Usenet posting
> gave you that idea, and we'll get the SWAT team sent out straight
> away.

Perhaps we can send the the Pennsylvania State University out after
them. I don't know why, but some fairly substantial people here are
scared of the PSU.

...

Oh, I have just been informed by my captors that the are the Python
Secre....

Aaron Brady

unread,
Dec 29, 2008, 2:18:33 PM12/29/08
to

--Why would he take the time to carve "ARGHHH!"?
--Maybe he was dictating.

Terry Reedy

unread,
Dec 29, 2008, 2:25:27 PM12/29/08
to pytho...@python.org
John Machin wrote:
> On Dec 29, 5:01 pm, scsoce <scs...@gmail.com> wrote:
>> I have a function return a reference,
>
> Stop right there. You don't have (and can't have, in Python) a
> function which returns a reference that acts like a pointer in C or C+
> +. Please tell us what manual, tutorial, book, blog or Usenet posting
> gave you that idea,

Perhaps the ones claiming that Python is 'call by reference' and hence,
by implication, at least, 'return by reference'.

> and we'll get the SWAT team sent out straight away.

I and others have posted many times that such a viewpoints leads to
confusion, such as in this post.

tjr

Miles

unread,
Dec 29, 2008, 7:06:37 PM12/29/08
to scsoce, pytho...@python.org
On Mon, Dec 29, 2008 at 1:01 AM, scsoce <scs...@gmail.com> wrote:
> I have a function return a reference, and want to assign to the reference,
> simply like this:
>>>def f(a)
> return a
> b = 0
> * f( b ) = 1*
> but the last line will be refused as "can't assign to function call".
> In my thought , the assignment is very nature, but why the interpreter
> refused to do that ?

Here's some links to help you better understand Python objects:

http://effbot.org/zone/python-objects.htm
http://effbot.org/zone/call-by-object.htm

The second one is a bit denser reading, but it's important to learn
that Python's approach to objects and "variables" is fundamentally
different from that of C/C++. In the example below, there's no way in
the Python language* that bar() can change the value of b, since
strings and numbers are immutable.

def foo():
b = 0
bar(b)
print b # will always be 0

* There are stupid [ctypes/getframe/etc.] tricks, though I think all
are implementation-specific

-Miles

Aaron Brady

unread,
Dec 29, 2008, 8:46:36 PM12/29/08
to
On Dec 29, 6:06 pm, Miles <semantic...@gmail.com> wrote:
> On Mon, Dec 29, 2008 at 1:01 AM, scsoce <scs...@gmail.com> wrote:
> > I have a function return a reference, and want to assign to the reference,
> > simply like this:
> >>>def f(a)
> >         return a
> >    b = 0
> >   * f( b ) = 1*
> > but the last line will be refused as "can't assign to function call".
> > In my thought , the assignment is very nature,  but  why the interpreter
> > refused to do that ?
>
> Here's some links to help you better understand Python objects:
>
> http://effbot.org/zone/python-objects.htmhttp://effbot.org/zone/call-by-object.htm

>
> The second one is a bit denser reading, but it's important to learn
> that Python's approach to objects and "variables" is fundamentally
> different from that of C/C++.  In the example below, there's no way in
> the Python language* that bar() can change the value of b, since
> strings and numbers are immutable.

On a technicality, to avert a flaming, "change the value of 'b'" is an
ambiguous phrase. There are two interpretations of "change what 'b'
refers to" and "change what 'b' refers to". Even in spoken language,
I don't think that emphasis can resolve them either.

One means, 'make a change in the world, in the actual configuration of
such and such actual matter.' The other means, 'update the axioms the
speaker is using to communicate to the listeners. (Such and such will
no longer refer to such and such; it will refer to such and such;
accept this and reject that.)' To make an observation, reference is a
purely linguistic phenomenon.

I, for one, am at a loss for how to disambiguate it. I'm open to
suggestions.

John O'Hagan

unread,
Dec 30, 2008, 9:21:29 AM12/30/08
to pytho...@python.org
On Tue, 30 Dec 2008, Aaron Brady wrote:
[...]

> On a technicality, to avert a flaming, "change the value of 'b'" is an
> ambiguous phrase. There are two interpretations of "change what 'b'
> refers to" and "change what 'b' refers to". Even in spoken language,
> I don't think that emphasis can resolve them either.
>
> One means, 'make a change in the world, in the actual configuration of
> such and such actual matter.' The other means, 'update the axioms the
> speaker is using to communicate to the listeners. (Such and such will
> no longer refer to such and such; it will refer to such and such;
> accept this and reject that.)' To make an observation, reference is a
> purely linguistic phenomenon.
>
> I, for one, am at a loss for how to disambiguate it. I'm open to
> suggestions.

I think you've already done so quite clearly. But I suspect the ambiguity
centres on the word "change" - in the first interpretation it means "alter"
(the object in place), in the second, it more precisely means "exchange" (one
object for another).

I'd be interested to know to what extent this ambiguity exists in languages
other than English - as a somewhat relevant example, ambiguities in English
around the verb "to be" ("I am Fred", "I am tall", "I am hungry"; i.e.,
identity vs. attributes vs. state) disappear in other languages which use
different verbs in each case.

On a (philosophical) side-note, I wonder if this is a real ambiguity: while
the statement that the name "b" now refers to a different object is
clear-cut, the other interpretation, that the object itself has changed but
is somehow still the same object, is a bit of an ontological minefield.

Fortunately, unlike the murky world of philosophy, Python (AIUI) simplifies
this question by simply declaring that yes, in the case of mutable objects,
we may say that we are still referring to the same object although we've
changed it, and no, in the case of immutable objects, we may not, and must
exchange it if we want a different "value" (a word too fraught with ambiguity
in this context to use unquoted!).

The sometimes useful fuzziness of human languages means we don't need to ask,
for example, "how tall is the object currently referred to by the name
Fred?", but in Python, it helps to understand that this is what's going on.

Regards,

John

Aaron Brady

unread,
Dec 30, 2008, 10:52:26 AM12/30/08
to

There are a few problems going on here. (My ultimate goal is a
unambiguous, non-arbitrary way to talk about Python; it's just that
unambiguous and non-arbitrary are really tall orders.) One is the
dependence (supervenience) of meaning on grammar (semantics on syntax,
function on form). One is the absence of form in computing and math.
Another is the composite identity.

I think the problem goes deeper than just English. In any language
that has a plural, the propositions in question come out as, 'one
thing is two things' or 'two things are one thing'. According to some
rules, these are ungrammatical sentences, due to plurality
disagreement. Ex:

The Morning Star is ...
The Evening Star is ...
*The Morning Star and The Evening Star is...
*The Morning Star and The Evening Star are...

Neither of the latter two is correct. (* marks ungrammatical.) As
such, the listener isn't sure what meaning to take.

Accepting that, I'll adopt the terms John proposed, 'change' vs.
'exchange', the former when the material configuration changes, the
latter when the communication axioms change.

b= [2, 3]
b= [3, 4]

'b' has exchanged. (Somewhat ungrammatical.)

b= [2, 3]
b.append( 4 )

'b' has changed.

According to this, when you replace every floorboard on a porch, one
at a time, it's still the same porch-- it's changed, it's different,
and it's the same. However, if you haul off the porch and put a new
one in its place, it's not. ('porch[:]=' vs. 'porch='.) You can't
just look at the initial and final configurations of matter to
determine so. Therefore, 'id' is an informal function.

Identity isn't defined on math objects, only on Python objects; there
is no notion of 'is' in math. It doesn't make sense to ask if '2 is
2', only if '2=2'. In Python, they are both defined, and not the
same. Unfortunately, in the language involved, 'same' and 'different'
aren't opposites, so the communication is horrendous and belabored.

Lastly, equality is a tolerance concept on the computer, not in math.
The computer looks at voltage thresholds in the underlying gates; the
actual voltages, beyond a certain precision, of two representations of
'0110' aren't the same. Further, the actual voltages of one
representation of '0110' over time aren't equal either.

However, that means, that in order to answer some questions about
equality and identity, we have to address the implementation of the
compiler. You might get the same answers in many or practically all
implementations of Python, but the specification doesn't make the leap
onto a real computer, where the equivalents of continuity of form are
defined in an unspecified way. You could even have continuity of the
contents of a byte (word)-- that is, they (the actual voltages on the
individual wires of the word) don't change at all between times t0 and
t1, but an identity test on it fails. Perhaps composite identity
isn't a common source of problems for language speakers.

P.S. Didn't say 'value'.

Tim Roberts

unread,
Dec 31, 2008, 2:39:59 AM12/31/08
to
Aaron Brady <casti...@gmail.com> wrote:
>
>I think the problem goes deeper than just English. In any language
>that has a plural, the propositions in question come out as, 'one
>thing is two things' or 'two things are one thing'. According to some
>rules, these are ungrammatical sentences, due to plurality
>disagreement. Ex:
>
>The Morning Star is ...
>The Evening Star is ...
>*The Morning Star and The Evening Star is...
>*The Morning Star and The Evening Star are...
>
>Neither of the latter two is correct. (* marks ungrammatical.) As
>such, the listener isn't sure what meaning to take.

This is taking a serious twist into off-topicness, but I need to dispute
this. I will assert that the 4th line is, in fact, grammatically correct,
modulo the capitalization of the second "The". The fragment is clearly of
the form "X and Y are...", and regardless of the substitution of X and Y,
the plurality of the subject agrees with the verb.

The Morning Star and the Evening Star are bright tonight.

Ignoring the fact that we can't see both at the same time, why is the
meaning of that unclear?
--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Aaron Brady

unread,
Dec 31, 2008, 7:22:30 PM12/31/08
to
On Dec 31, 1:39 am, Tim Roberts <t...@probo.com> wrote:

I want to get around to a clear answer to the OP's question, but I'm
frustrated by a month-long argument about it that suffered from some
serious misunderstandings of technical terms. (Therefore, thanks for
entertaining my detour so far, as well as not jumping down my throat
yet.) We didn't do a good job of explaining, and even disputed some
of the terms ourselves. So, I'm trying to look for some clear,
vernacular language that won't confuse lay speakers in an explanation.

I agree that the form of the 4th fragment is 'X and Y are' in
general. However, native speakers don't often use the form 'X and X
are'. This is the source of my protest, because X = the Morning Star
= the Evening Star. We don't say, 'G.H.W. Bush and the President
are...', say, at Camp David. It is not that the meaning is unclear,
it's just that form is never used.

In fact, moreover, there is some exclusion implied. If I said, 'I'm
going to St. Paul's and church,' my listener might think I had two
destinations, or I was being philosophical. The conversational maxim
of quantity [1] even leads him/r to believe that I want to convey more
information that just that I'm going to church.

[1] http://en.wikipedia.org/wiki/Gricean_maxim#Maxim_of_Quantity

In other words, s/he infers that there is a reason I didn't say only,
'I'm going to St. Paul's' or 'I'm going to church', and s/he wants to
know what it is.

How all this relates to Python semantics is, if I say, 'a and b are
the same object', the listener can get confused. I don't say, 'G.H.W.
Bush and the President are the same'; I say, 'G.H.W. Bush is the
President'.

Part of the problem is that Python divorced variables from their
contents; variables and objects are two different things. One is a
key in a namespace lookup; the other is the value there. I want to
conclude that, 'Therefore, there is no such thing as a reference to a
variable; only a namespace and a key'. However, I'm not on firm
footing to explain further, due to the uncommonness of the forms of
speech I would need to use. Maybe I could observe, 'variable
references are a peculiarity of C++, not available in every variable
model'.

Tim Roberts

unread,
Jan 1, 2009, 6:43:00 PM1/1/09
to
Aaron Brady <casti...@gmail.com> wrote:
>
>I agree that the form of the 4th fragment is 'X and Y are' in
>general. However, native speakers don't often use the form 'X and X
>are'. This is the source of my protest, because X = the Morning Star
>= the Evening Star. We don't say, 'G.H.W. Bush and the President
>are...', say, at Camp David.

Only now do I begin to see the point you were trying to make. You chose
that specific example because the Morning Star and the Evening Star happen
to be the same celestial body -- the same object.

However, in grammatical terms, that is absolutely irrelevant. For example,
"The car and the patent are white rabbits" is, grammatically speaking, 100%
correct. Grammatically correct sentences do not have to be logically
consistent.

Here's a counter example:
The Pope and the Head of the Catholic Church are the same person.

I don't think any moderately proficient English speaker would have trouble
parsing that.

By the way, G.H.W. Bush was president from 1988 to 1992. The President
today is G.W. Bush. The current president doesn't have an "H". There has
to be a pun about "getting the H out of there", but I'll leave that to the
reader.

>It is not that the meaning is unclear, it's just that form is never used.

Well, *I* use it. ;)

>How all this relates to Python semantics is, if I say, 'a and b are
>the same object', the listener can get confused.

I'm inclined to disagree, but in contexts where it is important, I always
try to say "a and b are bound to the same object".

Fuzzyman

unread,
Jan 1, 2009, 7:22:15 PM1/1/09
to

Although not being able to do the following has on occasion annoyed
me:

f(x) += 1

If the object returned by f(x) supports in place operations then it is
an entirely logical meaning, but not the interpreter can't know ahead
of time whether that is the case or not.

Michael Foord
--
http://www.ironpythoninaction.com/

MRAB

unread,
Jan 1, 2009, 8:04:55 PM1/1/09
to pytho...@python.org
+= always rebinds, even for in-place operations, so, in a sense, it's
not surprising!

I suppose it's like forbidding assignment within an expression (such as
an if- or while-condition): annoying sometimes, but a reasonable
restriction.

Derek Martin

unread,
Jan 2, 2009, 5:52:21 AM1/2/09
to Aaron Brady, pytho...@python.org
On a mostly not related note:

On Tue, Dec 30, 2008 at 07:52:26AM -0800, Aaron Brady wrote:
> According to some rules, these are ungrammatical sentences, due to
> plurality disagreement. Ex:
>
> The Morning Star is ...
> The Evening Star is ...
> *The Morning Star and The Evening Star is...
> *The Morning Star and The Evening Star are...
>
> Neither of the latter two is correct. (* marks ungrammatical.) As
> such, the listener isn't sure what meaning to take.

This statement is false. The latter of the two is grammatically
correct. The subject is a compound subject joined by the conjunction
"and" which indicates that there are two subjects, and thus the plural
form of the verb is necessary and correct.



> Identity isn't defined on math objects, only on Python objects; there
> is no notion of 'is' in math.

This is also false, it even has its own operator (which requires
Unicode to display): ≡

Still, the point you're trying to make is right: this stuff is hard to
talk about, and the model actually encourages the use of ambiguous or
even contradictory explanations.

--
Derek D. Martin
http://www.pizzashack.org/
GPG Key ID: 0x81CFE75D

Derek Martin

unread,
Jan 2, 2009, 5:39:15 AM1/2/09
to John O'Hagan, pytho...@python.org
On Tue, Dec 30, 2008 at 02:21:29PM +0000, John O'Hagan wrote:
> Fortunately, unlike the murky world of philosophy, Python (AIUI)
> simplifies this question by simply declaring that yes, in the case
> of mutable objects, we may say that we are still referring to the
> same object although we've changed it, and no, in the case of
> immutable objects, we may not, and must exchange it if we want a
> different "value" (a word too fraught with ambiguity in this context
> to use unquoted!).

That's sort of true; it would seem to be more accurate to say that
whenever a name is assigned to an object and subsequently reassigned,
the name no longer is associated with the original object. In the
case of mutable objects, the object can be changed by performing an
assignment of *part* of the object through its original name, i.e.
strings may be mutable, but the following code still produces two
different objects:

a = 'hello'
a = 'goodbye'

The first object so created is orphaned; it's been given the Russian
non-person treatment. It still exists, but the authorities (i.e. the
python interpreter) don't acknowledge it and provide the rest of the
world no way to communicate with it, and eventually it is reaped by
the garbage collector. :)

What the Python community often overlooks, when this discussion again
rears its ugly head (as it seems to every other hour or so), is that
its assignment model is BIZARRE, as in it's conceptually different
from virtually all other languages substantially taught in
undergraduate computer science programs. And for that matter, it's
pretty unintuitive generally.

That is, in what I'll call "normal" computer languages, a variable
name is thought of as the address of a bin where some data is stored,
and the name is inexorably tied to that bin. You can change what's in
the bin, but the name you gave the bin always points to the same bin.
This tends to be conceptually true even if it might technically not be
true in a given implementation of a language.

Python is very different from this. Names are not addresses of bins;
they are instead simply ephemeral labels which are given to bins,
where the bin is a Python object which contains specific data at the
time of assignment. A second assignment of that name doesn't change
what's in the original bin; it actually (probably) first creates a new
bin, then removes the name from the original bin and assigns it to
the new one. Intuitively, it's a bit like saying your kitchen table
is no longer a kitchen table, and now the thing where you wash your
dishes is a kitchen table. It doesn't really make a lot of sense
(whether or not it's so for good reason), and it makes describing the
assignment model necessarily convoluted, whereas the "named bins"
model from the majority of other languages people are likely to have
been exposed to is simple and sensible.

It's small wonder that neophytes try to cram Python behaviors into
terms and computing concepts they already understand from learning
other languages, and that they fail to do so. What's mystifying is
that when Pythonistas reply to their messages, they universally seem
confused at how this could possibly happen, and often enough actually
seem offended (or at least offensive) when it inevitably does happen...

Steve Holden

unread,
Jan 2, 2009, 11:43:30 AM1/2/09
to pytho...@python.org
Derek Martin wrote:
> On Tue, Dec 30, 2008 at 02:21:29PM +0000, John O'Hagan wrote:
[...]

> What the Python community often overlooks, when this discussion again
> rears its ugly head (as it seems to every other hour or so), is that
> its assignment model is BIZARRE, as in it's conceptually different
> from virtually all other languages substantially taught in
> undergraduate computer science programs. And for that matter, it's
> pretty unintuitive generally.
>
I'd definitely argue against bizarre. It's actually very easy to
understand, and Python is by no means the only language to have used it.

> That is, in what I'll call "normal" computer languages, a variable
> name is thought of as the address of a bin where some data is stored,
> and the name is inexorably tied to that bin. You can change what's in
> the bin, but the name you gave the bin always points to the same bin.
> This tends to be conceptually true even if it might technically not be
> true in a given implementation of a language.
>

I'd argue that this approach is out of date and overly-restrictive,
requiring data copying not required by the Python data model and running
the risk, in the absence of such copying, of returning invalid
references (the C++ "dangling pointer" issue being the best-known
manifestation of such problems).

> Python is very different from this. Names are not addresses of bins;
> they are instead simply ephemeral labels which are given to bins,
> where the bin is a Python object which contains specific data at the
> time of assignment. A second assignment of that name doesn't change
> what's in the original bin; it actually (probably) first creates a new
> bin, then removes the name from the original bin and assigns it to
> the new one. Intuitively, it's a bit like saying your kitchen table
> is no longer a kitchen table, and now the thing where you wash your
> dishes is a kitchen table. It doesn't really make a lot of sense
> (whether or not it's so for good reason), and it makes describing the
> assignment model necessarily convoluted, whereas the "named bins"
> model from the majority of other languages people are likely to have
> been exposed to is simple and sensible.
>

I'd instead say that Python uses ephemeral names for long-lived objects,
where other languages use the addresses of ephemeral objects. Your ideas
of "simple" and "sensible" are being conditioned by your experience.

> It's small wonder that neophytes try to cram Python behaviors into
> terms and computing concepts they already understand from learning
> other languages, and that they fail to do so. What's mystifying is
> that when Pythonistas reply to their messages, they universally seem
> confused at how this could possibly happen, and often enough actually
> seem offended (or at least offensive) when it inevitably does happen...
>

Generally speaking we try not to be offensive first on this list.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Derek Martin

unread,
Jan 2, 2009, 3:44:44 PM1/2/09
to Steve Holden, pytho...@python.org
On Fri, Jan 02, 2009 at 11:43:30AM -0500, Steve Holden wrote:
> Derek Martin wrote:
> > What the Python community often overlooks, when this discussion again
> > rears its ugly head (as it seems to every other hour or so), is that
> > its assignment model is BIZARRE, as in it's conceptually different
> > from virtually all other languages substantially taught in
> > undergraduate computer science programs. And for that matter, it's
> > pretty unintuitive generally.
> >
> I'd definitely argue against bizarre. It's actually very easy to
> understand, and Python is by no means the only language to have used it.

Clearly the first and third are true. :) But CS programs still
generally teach primarily C/C++, Java, and (some form of) assembly
AFAICT. A few odd ones pop up here and there along the way (I studied
with scheme, for example), but they vary and are highly
program-dependent. What the average CS grad sees is, AFAICT, still
very much what I described. Those languages also behave similarly to
what students see in mathematics (e.g. algebra etc.). With only that
to go on, Python seems rather weird, and I think from the frequency
with which these discussions occur on this list, clearly it *IS*
difficult for a neophyte Python programmer to understand the
assignment model. And this is, in part, because it's kind of
difficult to explain precisely, as has oft been demonstrated in this
forum.

> I'd argue that this approach is out of date and overly-restrictive,

Sure, I already hinted that it's useful... but it's still uncommon, in
the experience of most CS students -- not even taking into account the
number of people who program who have never studied in a formal CS
program.

> I'd instead say that Python uses ephemeral names for long-lived objects,
> where other languages use the addresses of ephemeral objects. Your ideas
> of "simple" and "sensible" are being conditioned by your experience.

Of course... I'd argue that our experience is a large part of what
makes things simple or sensible. Things that behave like other things
we are very familiar will be simple to understand. Python's
assignment model is probably new to most people when they first start
using it. To look at Python's code, at first glance assignment seems
to be the same as everywhere else you've encountered it... Only once
someone starts to write "real" programs does the difference really
matter.

> > It's small wonder that neophytes try to cram Python behaviors into
> > terms and computing concepts they already understand from learning
> > other languages, and that they fail to do so. What's mystifying is
> > that when Pythonistas reply to their messages, they universally seem
> > confused at how this could possibly happen, and often enough actually
> > seem offended (or at least offensive) when it inevitably does happen...
> >
> Generally speaking we try not to be offensive first on this list.

Perhaps I've misused the term Pythonista... I meant roughly, "people
who frequent this list/news group who seem to consider themselves
experts at programming Python (and for the most part, are)."
I consider myself pretty well informed about Python (though not an
expert by any means), and I still read this list often (I use the
mailing list interface), because I still find that I learn useful
things from the posts to it from time to time. But I often see python
"experts" lambasting people who clearly from their posts are new at
python, because their code is bad, their understanding is bad, or in
this case even accusing the learning materials of being sub-par. I
realize that some of this is meant in jest, but a lot of it isn't, and
it can be quite difficult for someone who doesn't speak your language
natively (or even one who does, given the medium) to tell the
difference. There are better ways to foster understanding... ;-)

Erik Max Francis

unread,
Jan 2, 2009, 3:50:44 PM1/2/09
to
Derek Martin wrote:
> On a mostly not related note:
>
> On Tue, Dec 30, 2008 at 07:52:26AM -0800, Aaron Brady wrote:
>> According to some rules, these are ungrammatical sentences, due to
>> plurality disagreement. Ex:
>>
>> The Morning Star is ...
>> The Evening Star is ...
>> *The Morning Star and The Evening Star is...
>> *The Morning Star and The Evening Star are...
>>
>> Neither of the latter two is correct. (* marks ungrammatical.) As
>> such, the listener isn't sure what meaning to take.
>
> This statement is false. The latter of the two is grammatically
> correct. The subject is a compound subject joined by the conjunction
> "and" which indicates that there are two subjects, and thus the plural
> form of the verb is necessary and correct.
>
>> Identity isn't defined on math objects, only on Python objects; there
>> is no notion of 'is' in math.
>
> This is also false, it even has its own operator (which requires
> Unicode to display): ≡

That can mean a number of things, one of which means "is identically
equal to," but identity means something different in mathematics than it
means here. In mathematics, identity means a relationship that is true
regardless of the value of the variables involved (as opposed to
equality which is only true under more specific circumstances). In
computer science, identity means that two expressions are represented by
the same object, something which not only has no meaning in mathematics,
but which should also be clear since mathematical identities need not
have any individual variables on either side of the triple bar; take,
for instance, the trigonometric identity

cos^2 theta + sin^2 theta = 1.

Even if you write this equation with the triple bar to represent a
mathematical identity (which it is), it obviously doesn't say anything
about which "objects" are the same as each other.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis

Scars are like memories. We do not have them removed.
-- Chmeee

Steve Holden

unread,
Jan 2, 2009, 3:58:55 PM1/2/09
to Derek Martin, pytho...@python.org
Derek Martin wrote:
> On Fri, Jan 02, 2009 at 11:43:30AM -0500, Steve Holden wrote:
>> Derek Martin wrote:
[...]

>>> It's small wonder that neophytes try to cram Python behaviors into
>>> terms and computing concepts they already understand from learning
>>> other languages, and that they fail to do so. What's mystifying is
>>> that when Pythonistas reply to their messages, they universally seem
>>> confused at how this could possibly happen, and often enough actually
>>> seem offended (or at least offensive) when it inevitably does happen...
>>>
>> Generally speaking we try not to be offensive first on this list.
>
> Perhaps I've misused the term Pythonista... I meant roughly, "people
> who frequent this list/news group who seem to consider themselves
> experts at programming Python (and for the most part, are)."
> I consider myself pretty well informed about Python (though not an
> expert by any means), and I still read this list often (I use the
> mailing list interface), because I still find that I learn useful
> things from the posts to it from time to time. But I often see python
> "experts" lambasting people who clearly from their posts are new at
> python, because their code is bad, their understanding is bad, or in
> this case even accusing the learning materials of being sub-par. I
> realize that some of this is meant in jest, but a lot of it isn't, and
> it can be quite difficult for someone who doesn't speak your language
> natively (or even one who does, given the medium) to tell the
> difference. There are better ways to foster understanding... ;-)
>
I don't think you can abuse a term that doesn't have any set meaning -
generally it's used to refer simply to users of Python, or at least
that's the way I use it.

Lambasting is definitely not the way to proceed with learners, and
generally the denizens of this group mostly behave properly. Even when
meant in jest it's not appropriate, not helpful, and not Pythonic. I
have been known to be unnecessarily crabby myself on the odd off-day,
though usually when I catch myself behaving that way I try to apologize
when it's appropriate.

There are a few individuals who pop up from time to time and whose
behavior is incendiary, but we should even ignore those. Not answering a
post is the best way to ensure they don't come back seeking to offend
again. Or, better still, change their ways and become model citizens.

Bruno Desthuilliers

unread,
Jan 2, 2009, 3:05:51 PM1/2/09
to
Derek Martin a écrit :

> On Fri, Jan 02, 2009 at 11:43:30AM -0500, Steve Holden wrote:
>> Derek Martin wrote:
>>> What the Python community often overlooks, when this discussion again
>>> rears its ugly head (as it seems to every other hour or so), is that
>>> its assignment model is BIZARRE, as in it's conceptually different
>>> from virtually all other languages substantially taught in
>>> undergraduate computer science programs. And for that matter, it's
>>> pretty unintuitive generally.
>>>
>> I'd definitely argue against bizarre. It's actually very easy to
>> understand, and Python is by no means the only language to have used it.
>
> Clearly the first and third are true. :) But CS programs still
> generally teach primarily C/C++, Java, and (some form of) assembly
> AFAICT. A few odd ones pop up here and there along the way (I studied
> with scheme, for example), but they vary and are highly
> program-dependent. What the average CS grad sees is, AFAICT, still
> very much what I described. Those languages also behave similarly to
> what students see in mathematics (e.g. algebra etc.). With only that
> to go on, Python seems rather weird, and I think from the frequency
> with which these discussions occur on this list, clearly it *IS*
> difficult for a neophyte Python programmer to understand the
> assignment model.

Took me about half an hour to grasp, not even being "CS grad" (nor
whathever "grad" FWIW). By that time, I had a couple monthes working
experience with VB, and had learned (but never seriously used) bits of
C, C++, Java and Pascal.

Derek Martin

unread,
Jan 2, 2009, 4:28:29 PM1/2/09
to Bruno Desthuilliers, pytho...@python.org
On Fri, Jan 02, 2009 at 09:05:51PM +0100, Bruno Desthuilliers wrote:
>> Python seems rather weird, and I think from the frequency
>> with which these discussions occur on this list, clearly it *IS*
>> difficult for a neophyte Python programmer to understand the
>> assignment model.
>
> Took me about half an hour to grasp, not even being "CS grad" (nor
> whathever "grad" FWIW). By that time, I had a couple monthes working
> experience with VB, and had learned (but never seriously used) bits of
> C, C++, Java and Pascal.

It took me about a half a second to grasp the "named bins" concept --
i.e. as soon as I was finished reading the words that explained it I
understood it, so I'd say that based on your half-hour number,
Python's model is substantially more complicated.

My own experience was kind of similar... When I read about Python's
model I didn't understand it the first time around, had to re-read the
section I read that described it, and then had to play with it to see
for myself how it worked. I'd estimate it took 10 minutes. I'm not a
CS grad either (my degree is in information technology) but I did take
the first two years of CS classes at my local college (as a bridge to
a masters degree in CS, which I never completed), and I've been
programming as a hobbyist, in school, and in my profession for 25
years. I would argue that ideally, it should not take an experienced
programmer 10 minutes to understand variable assignment. :) [Note
that I'm including the semantics for passing arguments to functions as
part of "assignment" for purposes of this discussion.]

Derek Martin

unread,
Jan 2, 2009, 5:16:41 PM1/2/09
to Erik Max Francis, pytho...@python.org
On Fri, Jan 02, 2009 at 12:50:44PM -0800, Erik Max Francis wrote:
>>> Identity isn't defined on math objects, only on Python objects; there
>>> is no notion of 'is' in math.
>>
>> This is also false, it even has its own operator (which requires
>> Unicode to display): ≡
>
> That can mean a number of things, one of which means "is identically
> equal to,"

Quite so.

> but identity means something different in mathematics than it means
> here.

But for non-mutable objects, aren't they essentially the same?
Mathematics has no concept of "objects" in the sense that computer
science does, so of course the best you can really do is draw
parallels.

> In mathematics, identity means a relationship that is true
> regardless of the value of the variables involved (as opposed to
> equality which is only true under more specific circumstances).

Does 2 = 2 not qualify? Isn't it true that 2 ≡ 2 and 2 is 2? :)
Yet there are no variables at all... The "objects" of mathematics are
numbers, which are constants, which as such I would argue always have
the same "identity" as themselves. Other components of mathematics
are "expressions", which may or may not evaluate to constants,
depending on the set conditions. Python has those too, and they are
not the same as objects.

> In computer science, identity means that two expressions are
> represented by the same object, something which not only has no
> meaning in mathematics,

We're getting way off track here, but I would argue this is also
false. Take sets, for example:

A = { 1, 2, 3 }
B = { 1, 2, 3 }

Is it not true that A ≡ B and in fact these two sets are the same,
i.e. they are not actually two different sets at all; the have the
same identity, even considering a definition of "identity" which
reflects that in Python? A and B are in fact simply two different
names we've given to the same mathematical entity. The major
difference between mathematics and Python is that mathematical objects
are essentially unique, i.e. the constant 1 is arguably always the
same 1 wherever it appears, because there is no mathematical need to
have multiple instances of the constant 1: Wherever you see the
symbol '1' OR an expression which evaluates to the constant 1, it
refers to a *concept* of the numerical value representing mathematical
singularity and wholeness. In python, you can have multiple instances
of objects which are identical to each other (though for this simple
case, even python only creates one instance of the object).

> but which should also be clear since
> mathematical identities need not have any individual variables on
> either side of the triple bar; take, for instance, the
> trigonometric identity
>
> cos^2 theta + sin^2 theta = 1.

Is theta not a variable? :) Not that it matters...

> Even if you write this equation with the triple bar to represent a
> mathematical identity (which it is), it obviously doesn't say anything
> about which "objects" are the same as each other.

I don't imagine I would agree, based on what I just said. To elaborate,
each side of the expression contain symbols which always evaluate to
the same constant. The identity of a constant is constant. :) Thus
the objects on both sides are indeed the same identical mathematical
entity... they are just expressed differently. It's just like if you
refered to your kitchen table (assuming you have only one kitchen
table) as "the table" or as "the large table I eat on in the
kitchen..." No matter what you call it, it's still the same table.

In the case where the identity can not be reduced to constants, the
two expressions still evaluate to the same mathematical entity...
except that you need to set the conditions (i.e. give values to the
variables) to find out what that actually is. It seems exactly
analogous to Python to me, except that again, unlike Python, there is
no possibility that there can ever be two instances of the same object
and thus applying the term "identity" to mathematical objects is not
useful. It's not that it is meaningless, it just isn't very interesting.
Clearly though, 2 is not 3, and these two mathematical objects do not
have the same identity. Perhaps there is no concept of identity in
mathematics precisely because it is unnecessary: 1 is always 1, by
definition. But that is the definition of "is"... :)

But the discussion is bordering on philosophy, and I will resign from
it at this point, having previously made the points I intended to.

Erik Max Francis

unread,
Jan 2, 2009, 5:53:46 PM1/2/09
to
Derek Martin wrote:

> On Fri, Jan 02, 2009 at 12:50:44PM -0800, Erik Max Francis wrote:
>>>> Identity isn't defined on math objects, only on Python objects; there
>>>> is no notion of 'is' in math.
>>> This is also false, it even has its own operator (which requires
>>> Unicode to display): ≡
>> That can mean a number of things, one of which means "is identically
>> equal to,"
>
> Quite so.
>
>> but identity means something different in mathematics than it means
>> here.
>
> But for non-mutable objects, aren't they essentially the same?
> Mathematics has no concept of "objects" in the sense that computer
> science does, so of course the best you can really do is draw
> parallels.

That's exactly the point. There is no concept of object identity in
mathematics, so the above statement that you called false is, in fact,
true. The concept does not translate.

>> In computer science, identity means that two expressions are
>> represented by the same object, something which not only has no
>> meaning in mathematics,
>
> We're getting way off track here, but I would argue this is also
> false. Take sets, for example:
>
> A = { 1, 2, 3 }
> B = { 1, 2, 3 }
>
> Is it not true that A ≡ B and in fact these two sets are the same,
> i.e. they are not actually two different sets at all; the have the
> same identity, even considering a definition of "identity" which
> reflects that in Python?

Only if you try to make up a concept of identity that mathematics
doesn't already have. The existing concept, which you invoked, has
nothing to do with _object_ identity, it just has to do with a broader
equality.

> I don't imagine I would agree, based on what I just said. To elaborate,
> each side of the expression contain symbols which always evaluate to
> the same constant. The identity of a constant is constant. :)

Except identities don't have to contain constants at all. They can
contain arbitrary expressions on either side of the "is identically
equal to" symbol. Which clearly indicates that the symbol can't mean
the same thing as the identity operator in computer science, as you were
claiming it did.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis

There's something immoral about abandoning your own judgement.
-- John F. Kennedy

Marc 'BlackJack' Rintsch

unread,
Jan 3, 2009, 5:15:51 AM1/3/09
to
On Fri, 02 Jan 2009 04:39:15 -0600, Derek Martin wrote:

> On Tue, Dec 30, 2008 at 02:21:29PM +0000, John O'Hagan wrote:
> What the Python community often overlooks, when this discussion again
> rears its ugly head (as it seems to every other hour or so), is that its
> assignment model is BIZARRE, as in it's conceptually different from
> virtually all other languages substantially taught in undergraduate
> computer science programs.

What's the difference between Python and Java or C# here!? Or are they
also "BIZARRE"!?

> And for that matter, it's pretty unintuitive generally.

Names and objects are quite "natural" IMHO. There are many real world
objects which we attach one or more names to, or refer to in sequences
like "please give me the third book on that shelve" (``shelve[2]``).

> That is, in what I'll call "normal" computer languages, a variable name
> is thought of as the address of a bin where some data is stored, and the
> name is inexorably tied to that bin.

You just call that "normal" or "intuitive" because that's what you
learned first.

> Python is very different from this. Names are not addresses of bins;
> they are instead simply ephemeral labels which are given to bins, where
> the bin is a Python object which contains specific data at the time of
> assignment. A second assignment of that name doesn't change what's in
> the original bin; it actually (probably) first creates a new bin, then
> removes the name from the original bin and assigns it to the new one.
> Intuitively, it's a bit like saying your kitchen table is no longer a
> kitchen table, and now the thing where you wash your dishes is a kitchen
> table. It doesn't really make a lot of sense (whether or not it's so
> for good reason), and it makes describing the assignment model
> necessarily convoluted, whereas the "named bins" model from the majority
> of other languages people are likely to have been exposed to is simple
> and sensible.

I think the "bin model" is more complex because you don't just have a
name and an object but always that indirection of the "bin".

Ciao,
Marc 'BlackJack' Rintsch

Message has been deleted

Bruno Desthuilliers

unread,
Jan 3, 2009, 10:08:54 AM1/3/09
to
Derek Martin a écrit :

> On Fri, Jan 02, 2009 at 09:05:51PM +0100, Bruno Desthuilliers wrote:
>>> Python seems rather weird, and I think from the frequency
>>> with which these discussions occur on this list, clearly it *IS*
>>> difficult for a neophyte Python programmer to understand the
>>> assignment model.
>> Took me about half an hour to grasp, not even being "CS grad" (nor
>> whathever "grad" FWIW). By that time, I had a couple monthes working
>> experience with VB, and had learned (but never seriously used) bits of
>> C, C++, Java and Pascal.
>
> It took me about a half a second to grasp the "named bins" concept --

Oh yes ? With all it's implications ? Fine, you're way smarter than I'm
- or, as it seems, you were much more experimented and CS-litterate that
I was by that time.

But that was not the point. What I meant is that a concept that takes
less than an hour to grasp for a newbie self-taught programmer with no
previous exposure to the concept should by no mean be a problem for a CS
graduate.

John O'Hagan

unread,
Jan 3, 2009, 12:25:17 PM1/3/09
to pytho...@python.org
On Tue, 30th Dec 2008, Aaron Brady wrote:

>Accepting that, I'll adopt the terms John proposed, 'change' vs.
>'exchange', the former when the material configuration changes, the
>latter when the communication axioms change.
>
>b= [2, 3]
>b= [3, 4]
>
>'b' has exchanged. (Somewhat ungrammatical.)
>
>b= [2, 3]
>b.append( 4 )
>
>'b' has changed.
>
>According to this, when you replace every floorboard on a porch, one
>at a time, it's still the same porch-- it's changed, it's different,
>and it's the same. However, if you haul off the porch and put a new
>one in its place, it's not. ('porch[:]=' vs. 'porch='.) You can't
>just look at the initial and final configurations of matter to
>determine so. Therefore, 'id' is an informal function.

This analogy describes the "ontological minefield" I was referring to in a
previous post in this thread (which has expired in my mail reader, so my
apologies if the threading goes awry): In what sense is a porch (or list, or
string) the same if all (or even some of) its parts have been exchanged?

I think the answer is something to do with the abstraction, the "container",
the instance of the class. Would it be fair to say that perhaps there are no
truly mutable objects, only immutable containers whose contents (also
immutable objects themselves) may be exchanged? Or to pose the question
another way, are objects only mutable insofar as they are composite?

As you argue above, the planks are not the porch; I would add that it's your
_decision_ to build (or tear down) a porch which makes it _that_ particular
porch (or not).

As you imply above (I think), you have to keep looking (or someone does,
presumably the interpreter) to know whether an object is the same as or just
equal to another (which starts to sound spookily like the role of "the
observer" in phenomenology or quantum physics). Whether this means that id()
is "informal" or not, I'll leave to others better informed than I.

Regards,

John


Grant Edwards

unread,
Jan 3, 2009, 12:38:46 PM1/3/09
to
On 2009-01-03, Marc 'BlackJack' Rintsch <bj_...@gmx.net> wrote:
> On Fri, 02 Jan 2009 04:39:15 -0600, Derek Martin wrote:
>
>> What the Python community often overlooks, when this discussion again
>> rears its ugly head (as it seems to every other hour or so), is that its
>> assignment model is BIZARRE, as in it's conceptually different from
>> virtually all other languages substantially taught in undergraduate
>> computer science programs.
>
> What's the difference between Python and Java or C# here!?

Or scheme, or lisp, or smalltalk, or ....

> Or are they also "BIZARRE"!?

One presumes that Mr. Martin finds anything different from his
first computer language to be BIZARRE. He should try out
Prolog or something genuinely different.

--
Grant

Aaron Brady

unread,
Jan 3, 2009, 6:42:47 PM1/3/09
to

I think the key ingredient is that there's no such thing as side
effect in math.

In example,

a= [0, 1, 2]
a[:]= [3, 4, 5]

There aren't many natural language senses in which 'a' is the same
object as before. If I have a leg transplant, I'm the same person,
but if you replace the entire contents of me, I'm not. But 'a' is.

The porch is defined by its location, but not exclusively. Natural
language identity is a cluster concept, without strict necessary and
sufficient conditions. Nothing really presses our boundaries of it
that much; there aren't many practical questions that lay out the
facts, then ask, 'But is it the same?' You can replace the porch
board-at-a-time, and it is; and you can haul it somewhere and it is.
But rearrange the same boards, and it's not. Continuity of form is
probably the prevalent feature, which as you state, does break down in
the case of composite (piece-wise) transformations.

You might get farther comparing container objects to spots on a
bulletin board. The only thing that goes 'in' a container is a
denoting phrase to another object (and by the way, not a description);
the other also has its own spot independently on the board.

It's not clear IMO that the question is so much a minefield-- a
question that it's really easy to get throw (fall) off course
pursuing, as it is that there's no such course. In short, there is no
such thing as composite identity, only matter; or in Python, only
spots on the bulletin board.

> Or to pose the question
> another way, are objects only mutable insofar as they are composite?

No; tuples are composite. If I flip one bit in a byte somewhere, is
it the same byte?

Steven D'Aprano

unread,
Jan 4, 2009, 2:28:38 AM1/4/09
to
I'm answering both John and Aaron's comments in the following. Mostly
John at the start, Aaron toward the end.


On Sat, 03 Jan 2009 15:42:47 -0800, Aaron Brady wrote:

> On Jan 3, 11:25 am, John O'Hagan <resea...@johnohagan.com> wrote:

[...]

> > >According to this, when you replace every floorboard on a porch, one
> > >at a time, it's still the same porch-- it's changed, it's different,
> > >and it's the same.  However, if you haul off the porch and put a new
> > >one in its place, it's not.  ('porch[:]=' vs. 'porch='.)  You can't
> > >just look at the initial and final configurations of matter to
> > >determine so.  Therefore, 'id' is an informal function.
> >
> > This analogy describes the "ontological minefield" I was referring to
> > in a previous post in this thread (which has expired in my mail
> > reader, so my apologies if the threading goes awry): In what sense is
> > a porch (or list, or string) the same if all (or even some of) its
> > parts have been exchanged?
> >
> > I think the answer is something to do with the abstraction, the
> > "container", the instance of the class.

That seems reasonable. When you say alist[:] = [1, 2, 3] the container
remains "the same", while the contents change.


> > Would it be fair to say that perhaps there are no
> > truly mutable objects, only immutable containers whose contents (also
> > immutable objects themselves) may be exchanged? Or to pose the
> > question another way, are objects only mutable insofar as they are
> > composite?

That depends on what you mean by composite. Everything is composite in
some sense, even a single bit in memory has a physical reality made of
atoms with magnetic fields. But taken as an abstract entity, it is
reasonable to treat a single bit as an atomic non-composite thing, and a
single bit is mutable.

In practice, actual Python objects tend to be mutable only if they are
composite (although being composite doesn't make them mutable -- consider
frozen sets and tuples). In principle, this is not necessary. There's no
reason why Python couldn't expose a single bit as a data type, so you
could write this:

>>> n = bit(1)
>>> bool(n)
True
>>> n.flip()
>>> bool(n)
False


> > As you argue above, the planks are not the porch; I would add that
> > it's your _decision_ to build (or tear down) a porch which makes it
> > _that_  particular porch (or not).

No, there's no such decision needed. Perhaps a hurricane comes through
and rips the porch up. Maybe a rogue television crew comes by while
you're at work and renovates your house without your knowledge.

The lack of decision-making needed is more obvious when you consider
something like a fast-flowing river. The specific water molecules making
up the river at any particular instant in time flow away in a matter of
days or weeks, but rivers have a continuity of existence measured in
thousands of years. I trust that nobody is going to argue that the river
makes any decisions at all?


> > As you imply above (I think), you have to keep looking (or someone
> > does, presumably the interpreter) to know whether an object is the
> > same as or just equal to another (which starts to sound spookily like
> > the role of "the observer" in phenomenology or quantum physics).

No, I think you're introducing mysticism here that isn't needed. A bit
like quantum mechanics, really :)

In Python, every object has an identity and a value. If objects X and Y
have the same identity, they are the same object. If X is the object with
id 1234, and Y is the object with id 1234, then both are the same object.
If their ids are different, then they are not.

In CPython, the id is given by the memory location of the object, which
leads to a very intuitive understanding of "same": the object with id
1234 is at memory location 1234, and since there can only be one object
at a particular memory location at a time, obviously all objects with id
1234 must be the same object (provided they exist simultaneously).

(To be pedantic, there can't actually be objects [note plural] existing
simultaneously with the same id. There can only be multiple references to
the one object.)

In Python implementations where the id is not a memory address
(IronPython and Jython I think?) the above remains true, even though
there isn't the simple intuitive picture of "only one object can be at a
specific memory address". Python guarantees that the id is *something*
which is guaranteed to be unique over the lifetime of every object.

Actually, our intuition about one thing per place at the one time is not
strictly correct. Consider the memory address 1234, which currently has
the value in hex of 0x58. That byte may be the numeric value 88, the
ASCII char "X", the set of flags 1011000, or any other thing, depending
on what interpretation we give to it. "What a thing is" is actually a
more difficult question than it appears at first glance.

[...]

> I think the key ingredient is that there's no such thing as side
> effect in math.

I don't see that this is relevant. We're not talking about mathematical
equality, but about the more general concepts of identity and sameness.


> In example,
>
> a= [0, 1, 2]
> a[:]= [3, 4, 5]
>
> There aren't many natural language senses in which 'a' is the same
> object as before.

Of course there are.

If I have a box containing three things (a piece of paper with the number
"0" written on it, a plastic block in the shape of "1" and a tally stick
with two notches cut in it), and then I remove those three things and
replace them with something else, it's the same box.

The English and Australian cricket teams have been playing international
Test cricket since 1877. None of the team members playing in 1877 are
still alive today. The entire lineup of both cricket teams has been
replaced repeatedly, and yet they are the same teams.

The same holds for many, many different organisations: churches, armies,
regiments, political parties, social clubs, companies, guilds, nations,
sporting teams, secret societies, criminal gangs, ecosystems, tribes,
communities of many sorts, and so forth.

Far from being rare, this is very common.


> If I have a leg transplant, I'm the same person,
> but if you replace the entire contents of me, I'm not.

Every (?) molecule in your body is replaced over a period of
approximately seven years. Some molecules are replaced much quicker, some
a little slower, but speaking roughly, the entire contents of you is
replaced every seven years. Aaron, are you the same person you were a
decade ago? In some sense, not at all -- you're a different person to the
annoying person who called himself "castironpi" and was repeatedly
accused of being a bot only a few months ago. But in another sense, yes,
you are the same person -- there is a continuity of existence.

See also the Ship of Theseus paradox, otherwise known as My Grandfather's
Axe paradox.

http://en.wikipedia.org/wiki/Ship_of_Theseus

[...]


> The porch is defined by its location, but not exclusively.

If we remove the porch from the house and transport it whole to another
house, it remains the same porch attached to a different house.


> Natural
> language identity is a cluster concept, without strict necessary and
> sufficient conditions. Nothing really presses our boundaries of it
> that much; there aren't many practical questions that lay out the
> facts, then ask, 'But is it the same?' You can replace the porch
> board-at-a-time, and it is; and you can haul it somewhere and it is.
> But rearrange the same boards, and it's not.

I think you overstate your case. If you move the boards around on the
porch, it remains the same porch. Likewise if I have a chest of drawers,
and I take the top drawer and put it at the bottom, the bottom drawer in
the middle and the middle drawer at the top, surely it is the same chest
of drawers? I haven't even replaced anything, just moved them around.


> Continuity of form is
> probably the prevalent feature, which as you state, does break down in
> the case of composite (piece-wise) transformations.

I think continuity of form is an important factor in deciding what is the
same and what is not, but I don't think it is the only one. See for
example the anecdote about the Japanese temple in the Wikipedia article
above. And I think you're wrong to say that piece-wise transformations
break down continuity of form. You are, in some sense, the same person
who some years ago was a crawling baby unable to speak. There are
significant changes and replacements and add-ons that nevertheless don't
break continuity.


> You might get farther comparing container objects to spots on a
> bulletin board. The only thing that goes 'in' a container is a
> denoting phrase to another object (and by the way, not a description);
> the other also has its own spot independently on the board.

That's a reasonable analogy for the implementation of CPython, but it
need not be the only implementation. It wouldn't be fast, or efficient,
or reasonable, but one could create a Python implementation where (for
example) a list didn't just hold pointers to objects, but it held the
actual entire object (no matter how large). Identity could be divorced
from memory location: the one object could exist in many different places
in memory, in the same way that an object can exist in many different
times. The underlying VM would ensure that all such instantiations of the
one object remained in sync at all time.

Such an implementation would be inefficient and foolish, but it would
still be Python.

Having said that, it is perfectly valid to ignore the implementation when
describing how Python operates. It really doesn't matter whether CPython
is implemented like a bulletin board or not, it behaves as if it were,
and that makes it a reasonable analogy.

--
Steven

Hendrik van Rooyen

unread,
Jan 4, 2009, 5:43:18 AM1/4/09
to pytho...@python.org
"Aaron Brady" <cas..@gmail.com> wrote:

>No; tuples are composite. If I flip one bit in a byte somewhere, is
>it the same byte?

Yes and No and No and Others:

Yes it is the byte at the same somewhere in memory.
No it is not the same as it was a moment ago,
because the bit has flipped.
No it is one of the bytes recently corrupted by a
passing cosmic ray.
[Insert other points of view here]

And of course, depending on what we are doing,
we take the viewpoint that is useful to the task in
hand. Taking all at the same time leads to a room
with soft walls and a jacket with funny sleeves.

Simplifying the porch example:

Here is a family heirloom - it is my grandfather's
axe. My father fixed it up by replacing the handle,
and I replaced the head because it was so worn.
I still think of it as my grandfather's axe, though.

Natural language seems to have very little to do
with logic, or even common sense, as constructs like
"my grandfather's axe" can be encountered in the wild,
without causing excessive cognitive dissonance.

I think the root trouble for computers when we want them
to make decisions about stuff like this is that they are too
rigid - their binary or boolean nature forces them into taking
the first branch that looks true at the time. We probably need
something softer based on majority logic like neural nets, or
something entirely new if we want to use them to explore this
kind of stuff. (yes I know we can write a simulation, but a
simulation is not an interpreter, is not a compiler, is not an
assembler is not an executable - and its at the executable level
that the rigidity is most apparent)

- Hendrik


Steve Holden

unread,
Jan 4, 2009, 8:29:50 AM1/4/09
to pytho...@python.org
Wolfgang Strobl wrote:
> Derek Martin <co...@pizzashack.org>:

>
>> It took me about a half a second to grasp the "named bins" concept --
>> i.e. as soon as I was finished reading the words that explained it I
>> understood it, so I'd say that based on your half-hour number,
>> Python's model is substantially more complicated.
>
> I don't think so. Personally, I started programming by punching Fortran
> IV statements into an IBM 26, submitting them as a batch job to an IBM
> 7090, so the "named bins" concept is quite heavily engraved into my
> brain. :-) But it didn't take me long to grasp (and enjoy!) the much
> more advanced concept of variable bindings in SNOBOL4, which is similar
> to Pythons, but predates Python quite some time.
>
> Quoting
>
> http://burks.bton.ac.uk/burks/language/snobol/catspaw/manual/ch6.htm
>
> Chapter 6 : DATA TYPES AND CONVERSION
>
> Most other programming languages require the user to explicitly declare
> the type of data to be stored in a variable. In SNOBOL4, any variable
> may contain any data type. Furthermore, the variable's type may be
> freely altered during program execution. SNOBOL4 remembers what kind of
> data is in each variable.
>
[...]
>
> C:\e\spitbol>spitbol test.spt
> SPITBOL-386 Release 3.7(ver 1.30.16) Serial 20158
> (c) Copyright 1987-1997 Robert B. K. Dewar and Catspaw, Inc.
> Snobol/Spitbol Beispiel
[...]
>
Thanks for the memories. I developed the DECSystem-10 Spitbol
implementation. I had no idea support of the language continued up to
1997, as I switched to Icon when Griswold produced that and found it a
far superior language.
Message has been deleted

Derek Martin

unread,
Jan 4, 2009, 9:03:11 PM1/4/09
to Marc 'BlackJack' Rintsch, pytho...@python.org
On Sat, Jan 03, 2009 at 10:15:51AM +0000, Marc 'BlackJack' Rintsch wrote:
> On Fri, 02 Jan 2009 04:39:15 -0600, Derek Martin wrote:
>
> > On Tue, Dec 30, 2008 at 02:21:29PM +0000, John O'Hagan wrote:
> > What the Python community often overlooks, when this discussion again
> > rears its ugly head (as it seems to every other hour or so), is that its
> > assignment model is BIZARRE, as in it's conceptually different from
> > virtually all other languages substantially taught in undergraduate
> > computer science programs.
>
> What's the difference between Python and Java or C# here!? Or are they
> also "BIZARRE"!?

I am happily ignorant of C#. As for Java, take the following code:

a = 6;
a = 5;

In Python, when you execute the equivalent code, it causes two
different objects to spring into existence, the first of which may be
cleaned up by the GC (except that since we're using small integers,
that's not likely to happen). Unless I'm misinformed (which is very
possible, my experience with Java has been extremely limited) in Java
that's not the case... the storage is allocated to the name a when
you execute its declaration, and the *same storage* is reused upon
subsequent assignment.

That behaves exactly like named bins.

> > And for that matter, it's pretty unintuitive generally.
>
> Names and objects are quite "natural" IMHO. There are many real world
> objects which we attach one or more names to, or refer to in sequences
> like "please give me the third book on that shelve" (``shelve[2]``).

Indeed, but the way we assign names to them does not behave as it does
in Python. Nor does Python's assignment work like it does in algebra,
or anywhere else the Python student is particularly likely to have
seen variable assignment before encountering it in Python. Let's
define intuitive, shall we? From dictionary.com (choosing the
definition which most easily makes my point):

intuitive: adj. capable of being perceived or known by intuition.

I'm going to go out on a limb and assert that there's NO POSSIBLE WAY
a student could intuit Python's variable assignment behavior, having
never been exposed to that same behavior prior. It needs to be
taught.

> > That is, in what I'll call "normal" computer languages, a variable name
> > is thought of as the address of a bin where some data is stored, and the
> > name is inexorably tied to that bin.
>
> You just call that "normal" or "intuitive" because that's what you
> learned first.

In a sense, yes... but isn't that what intuition really is? You can
figure something out whithout being told how it works... That's
either because it's immediately obvious from observing it, or it
behaves like something you've seen before. That is what intitive is.

> I think the "bin model" is more complex because you don't just have a
> name and an object but always that indirection of the "bin".

I cheerfully disagree. :) "Named bins" is essentially how algebra
works, and how several generations of computer languages, not to
mention the actual machine language those generated, behaved, before
the current crop. Those interpretations came first, because, much as
in the evolution of any other science, that was the model which was
most intuitive or easily explained.

But you need not take my word for it. Simply read the archives and
see for yourself how much confusion this has caused on this list.
[Please include the closely related behavior of parameter passing in
your search.]

Derek Martin

unread,
Jan 4, 2009, 9:07:51 PM1/4/09
to Grant Edwards, pytho...@python.org
On Sat, Jan 03, 2009 at 11:38:46AM -0600, Grant Edwards wrote:
> > Or are they also "BIZARRE"!?
>
> One presumes that Mr. Martin finds anything different from his
> first computer language to be BIZARRE. He should try out
> Prolog or something genuinely different.

One's presumption would be mistaken. However thank you for
illustrating my point so precisely, which was after all the
condescending and insulting way people "communicate" with people whom
(they think) know less than they do in this forum, and not actually
how difficult or easy the assignment model of Python is to understand.

Steve Holden

unread,
Jan 4, 2009, 9:30:20 PM1/4/09
to pytho...@python.org
Derek Martin wrote:
> On Sat, Jan 03, 2009 at 10:15:51AM +0000, Marc 'BlackJack' Rintsch wrote:
>> On Fri, 02 Jan 2009 04:39:15 -0600, Derek Martin wrote:
>>
>>> On Tue, Dec 30, 2008 at 02:21:29PM +0000, John O'Hagan wrote:
>>> What the Python community often overlooks, when this discussion again
>>> rears its ugly head (as it seems to every other hour or so), is that its
>>> assignment model is BIZARRE, as in it's conceptually different from
>>> virtually all other languages substantially taught in undergraduate
>>> computer science programs.
>> What's the difference between Python and Java or C# here!? Or are they
>> also "BIZARRE"!?
>
> I am happily ignorant of C#. As for Java, take the following code:
>
> a = 6;
> a = 5;
>
> In Python, when you execute the equivalent code, it causes two
> different objects to spring into existence, the first of which may be
> cleaned up by the GC (except that since we're using small integers,
> that's not likely to happen). Unless I'm misinformed (which is very
> possible, my experience with Java has been extremely limited) in Java
> that's not the case... the storage is allocated to the name a when
> you execute its declaration, and the *same storage* is reused upon
> subsequent assignment.
>
> That behaves exactly like named bins.
>
Ah, but if the right-hand-side expressions had been Integers rather than
integers, things would have been different, no? The point is that once
values become complex types it's convenient not to copy them each time
they are required. but I needn't flog this particular dead horse as you
clearly do understand Python's assignment semantics.

>>> And for that matter, it's pretty unintuitive generally.
>> Names and objects are quite "natural" IMHO. There are many real world
>> objects which we attach one or more names to, or refer to in sequences
>> like "please give me the third book on that shelve" (``shelve[2]``).
>

> Indeed, but the way we assign names to them does not behave as it does
> in Python. Nor does Python's assignment work like it does in algebra,
> or anywhere else the Python student is particularly likely to have
> seen variable assignment before encountering it in Python. Let's
> define intuitive, shall we? From dictionary.com (choosing the
> definition which most easily makes my point):
>

Algebra contains no assignments.

> intuitive: adj. capable of being perceived or known by intuition.
>
> I'm going to go out on a limb and assert that there's NO POSSIBLE WAY
> a student could intuit Python's variable assignment behavior, having
> never been exposed to that same behavior prior. It needs to be
> taught.
>

As does assignment of any kind. You can't argue that one semantic or
another is more intuitive without offering evidence.

>>> That is, in what I'll call "normal" computer languages, a variable name
>>> is thought of as the address of a bin where some data is stored, and the
>>> name is inexorably tied to that bin.
>> You just call that "normal" or "intuitive" because that's what you
>> learned first.
>

> In a sense, yes... but isn't that what intuition really is? You can
> figure something out whithout being told how it works... That's
> either because it's immediately obvious from observing it, or it
> behaves like something you've seen before. That is what intitive is.
>

>> I think the "bin model" is more complex because you don't just have a
>> name and an object but always that indirection of the "bin".
>

> I cheerfully disagree. :) "Named bins" is essentially how algebra
> works, and how several generations of computer languages, not to
> mention the actual machine language those generated, behaved, before
> the current crop. Those interpretations came first, because, much as
> in the evolution of any other science, that was the model which was
> most intuitive or easily explained.
>

You're perhaps familiar with some algebra that I didn't study. In
algebra and number theory identity and equality are equivalent. This is
far from the case in programming languages, so any analogy based on it
is specious to some degree. Programming isn't mathematics (except
perhaps for functional programming).

> But you need not take my word for it. Simply read the archives and
> see for yourself how much confusion this has caused on this list.
> [Please include the closely related behavior of parameter passing in
> your search.]
>

It's difficult to think of a single aspect of Python that doesn't cause
confusion in a typical year. The confusion is sometimes caused by
ill-informed comment. While well-informed, you appear to feel that
everyone else should share your idea of what's intuitive and what's BIZARRE.

Before extending this thread too long please ruminate on the recent
parameter-passing thread, of which you are clearly aware. Let's try and
create light rather than heat.

Grant Edwards

unread,
Jan 4, 2009, 10:56:33 PM1/4/09
to
On 2009-01-05, Derek Martin <co...@pizzashack.org> wrote:
> On Sat, Jan 03, 2009 at 11:38:46AM -0600, Grant Edwards wrote:
>> > Or are they also "BIZARRE"!?
>>
>> One presumes that Mr. Martin finds anything different from his
>> first computer language to be BIZARRE. He should try out
>> Prolog or something genuinely different.
>
> One's presumption would be mistaken. However thank you for
> illustrating my point so precisely, which was after all the
> condescending and insulting way people "communicate" with
> people whom (they think) know less than they do in this forum,
> and not actually how difficult or easy the assignment model of
> Python is to understand.

I'm sorry, but I really don't see how Python's assignment model
could be considered bizarre by anybody who's familiar with more
than one or two languages. It's actually somewhat common
outside the world of FORTRAN/assembly/C/Pascal. The only thing
about Python that ever struck me as odd was the semantic
significance of whitespace (and that's not without precedents
either). The significance of white-space changed very quickly
from odd to brilliant.

Among the languages I've known, Python is probably in the
bottom 10% as far as bizarrness goes. Lisp/Scheme, Prolog,
SNOBOL, COBOL, APL, Forth, Smalltalk and several now-forgotton
almost-purely-functional languages all seemed to me orders of
magnitude more bizarre than Python.

I must admit that a some of those languages (e.g. Forth and
Smalltalk) probably felt more "bizarre" due to their
developement environment than due to the language itself.

And then there is C++ which is bizarre only in the extent to
which it's a complete dog's-breakfast.

Back to work...

--
Grant

Derek Martin

unread,
Jan 4, 2009, 11:55:09 PM1/4/09
to Steve Holden, pytho...@python.org
On Sun, Jan 04, 2009 at 09:30:20PM -0500, Steve Holden wrote:
> > I'm going to go out on a limb and assert that there's NO POSSIBLE WAY
> > a student could intuit Python's variable assignment behavior, having
> > never been exposed to that same behavior prior. It needs to be
> > taught.
> >
> As does assignment of any kind.

I'm not sure that's true. Having taken algebra prior to learning Basic,
I intuitively understood what this program would do when I executed
it, the first time I saw the code, and before I read the explanation:

10 let x = 10
20 print x

[Well, to be honest it's been a very long time since I've programmed
in Pet BASIC, and the syntax may be wrong. The point is, just as I
did then, I am positive that you intuitively understand what the above
is intended to do, even if it is not valid BASIC syntax -- because if
you did not, we would not be having this discussion.]

> You can't argue that one semantic or another is more intuitive
> without offering evidence.

I think I have though, not that it matters, since that was never
really my point. Python's assignment model requires more explanation
than the traditional one, simply to state what it does. That alone is
evidence (but not proof). I haven't proven it scientifically, and I'm
not willing to jump through the necessary hoops (which would require a
psychological study) to do so simply to win an argument on Usenet.
It's not about winning... it's about illumination. ;-)



> You're perhaps familiar with some algebra that I didn't study.

Not unless you never studied it at all... ;-)

> In algebra and number theory identity and equality are equivalent.

Indeed. The point of bringing up algebra is that it provides a
background against which someone might be very likely to intuit what
variable assignment does in traditional programming languages -- at
least accurately enough to use it effectively without needing to
understand the underlying implementation and worry about any corner
cases. It really doesn't need to be explained, unless the student has
no prior background in either math or computers. In the case of
passing parameters things unavoidably get hairy, but at least at the
moment we're not discussing that, and also that has no analogous in
(at least high school) mathematics (at least, that I can think of) or
much of anywhere else from whence a student might draw any insights.

As for there being no assignment in algebra, is that not really what
variable substitution is? They have different names, but in my
estimation they perform exactly the same function. You're assigning
specific values to the variables in an expression so that you can
solve for a constant... just like in a computer program. There is
even an allocation of memory: it's in your brain. :D

> This is far from the case in programming languages, so any analogy
> based on it is specious to some degree. Programming isn't
> mathematics (except perhaps for functional programming).

I agree; but I wasn't making an analogy. I was pointing out (an
extremely likely) basis for intuition.

> It's difficult to think of a single aspect of Python that doesn't cause
> confusion in a typical year.

Surely some cause more than others... and surely some are more
surprising than others. ;-)

> The confusion is sometimes caused by ill-informed comment. While
> well-informed, you appear to feel that everyone else should share
> your idea of what's intuitive and what's BIZARRE.

Alright, perhaps I exaggerated when I said bizarre, but I did explain
exactly what I meant, and I believe that what I said in my explanation
is at least arguably true. I stand by the idea that it's much less
intuitive than the traditional assignment model, and despite your
protestations of lack of proof, I'm pretty sure you agree. ;-)

Ultimately, none of this really matters, as perhaps my point is that
Python *is different* from what A LOT of folks learning it have
already seen (if anything), and it's often easy for them to
misunderstand the Python way. As you said, let's provide light, not
heat, when we come across people who get confused between Python and
something else.

Derek Martin

unread,
Jan 5, 2009, 12:09:27 AM1/5/09
to Grant Edwards, pytho...@python.org
On Sun, Jan 04, 2009 at 09:56:33PM -0600, Grant Edwards wrote:
> On 2009-01-05, Derek Martin <co...@pizzashack.org> wrote:
> > On Sat, Jan 03, 2009 at 11:38:46AM -0600, Grant Edwards wrote:
> >> One presumes that Mr. Martin finds anything different from his
> >> first computer language to be BIZARRE. He should try out
> >> Prolog or something genuinely different.
> >
> > One's presumption would be mistaken. However thank you for
> > illustrating my point so precisely, which was after all the
> > condescending and insulting way people "communicate" with
> > people whom (they think) know less than they do in this forum,
> > and not actually how difficult or easy the assignment model of
> > Python is to understand.
>
> I'm sorry, but I really don't see how Python's assignment model
> could be considered bizarre by anybody who's familiar with more
> than one or two languages.

And... what if one wasn't? The OP of this thread clearly didn't
understand... Whereas if you've read the thread, clearly I do.
Of course, had you read my post, you probably would have understood
that my comment about the model being bizarre was intended to be
viewed from the perspective of someone who *had not* seen anything
like it before, which is LOTS of relatively new programmers, whether
or not it might be old hat to anyone here. The ultimate point of my
post was not so much about whether the assignment model of Python was
or wasn't easy to understand; it was about the idea that when someone
doesn't understand, we should try to help them instead of making snide
remarks about how stupid or small-minded they are.

Derek Martin

unread,
Jan 5, 2009, 12:27:31 AM1/5/09
to Steve Holden, pytho...@python.org
Forgive my indulgence, I find this rather academic discussion kind of
interesting, as it turns out.

On Sun, Jan 04, 2009 at 10:55:09PM -0600, Derek Martin wrote:
> > You can't argue that one semantic or another is more intuitive
> > without offering evidence.
>
> I think I have though, not that it matters, since that was never
> really my point. Python's assignment model requires more explanation
> than the traditional one, simply to state what it does. That alone is
> evidence (but not proof).

Here's (I think) a better argument, FWIW: The traditional model ties
a name to some (usually predefined and static) storage (a memory
address, or at least the start of a string of them). This is a very
concrete thing to represent, and the conceptualization of variables as
named bins in such languages captures this very succinctly, and
requires no understanding of the underlying implementation for the
programmer to use (at least with primitive data types, which are all
that are used generally when variables are first introduced).

The Python model binds a name to a particular Python object, which is
itself an abstraction; understanding requires understanding first what
an "object" is, and I think at least in some measure some knowledge
about how Python is implemented (primitive data types are actually
objects; and also recall the recent discussion about what constitutes
a "value" in Python). The abstraction, and the requirement to
partially understand the underlying implemenation, make the Python
model inherently more complicated, and therefore also inherently less
intuitive.

That also is not proof, but as I said, real proof is rather hard to
come by... And FWIW, remember that I never suggested that all this
was without good reason, and I'm not attempting to advocate for
simplifying the model. :)

Grant Edwards

unread,
Jan 5, 2009, 2:13:48 AM1/5/09
to
On 2009-01-05, Derek Martin <co...@pizzashack.org> wrote:

>> I'm sorry, but I really don't see how Python's assignment
>> model could be considered bizarre by anybody who's familiar
>> with more than one or two languages.
>
> And... what if one wasn't? The OP of this thread clearly
> didn't understand... Whereas if you've read the thread,
> clearly I do. Of course, had you read my post, you probably
> would have understood that my comment about the model being
> bizarre was intended to be viewed from the perspective of
> someone who *had not* seen anything like it before,

X is bizarre because it is unfamiliar to anybody who has never
seen X before?

--
Grant

Steven D'Aprano

unread,
Jan 5, 2009, 2:47:11 AM1/5/09
to


Bizarre: "conspicuously or grossly unconventional or unusual".

The bizarre is contingent on what people consider familiar, and naturally
if you've never seen X or anything like X before, you will find it
unfamiliar and likely bizarre.

There's no shame in finding spaghetti alla vongole bizarre if you've
never seen noodles or clams before. What is shameful is the refusal to
consider that just because it is bizarre to *you* doesn't mean that it is
bizarre to anyone else, and that your sense of bizarreness probably
reflects more your ignorance of the wide range of edible dishes than
anything strange about the food itself.

(On the other hand, maggot cheese really is bizarre.
http://en.wikipedia.org/wiki/Casu_marzu )

By all means, if Derek doesn't like the assignment model used by Python
(and Java, Ruby, C#, Perl, RealBasic, VisualBasic, Lua, and many other
languages going back to at least CLU in the mid 1970s) he's free to say
so. There are plenty of other languages out there, and perhaps he will
find one that he likes. Or he will continue to use Python, hating every
minute of it. Or perhaps he'll even come to like the assignment model,
and wonder how he ever could have found it bizarre. But it's rather rich
for him to claim that his subjective feelings about Python's assignment
model should be treated as objective fact.


--
Steven

Erik Max Francis

unread,
Jan 5, 2009, 3:28:43 AM1/5/09
to
Derek Martin wrote:

> On Sun, Jan 04, 2009 at 09:30:20PM -0500, Steve Holden wrote:
>>> I'm going to go out on a limb and assert that there's NO POSSIBLE WAY
>>> a student could intuit Python's variable assignment behavior, having
>>> never been exposed to that same behavior prior. It needs to be
>>> taught.
>>>
>> As does assignment of any kind.
>
> I'm not sure that's true. Having taken algebra prior to learning Basic,
> I intuitively understood what this program would do when I executed
> it, the first time I saw the code, and before I read the explanation:
>
> 10 let x = 10
> 20 print x

Did you understand that the first time you saw the statement in BASIC:

X = X + 1

the = symbol couldn't possibly have the same meaning as it does in
algebra? In BASIC, this is a statement which replaces the value of a
variable X with the previous value, incremented by one. In algebra,
this is an equation which has no solutions, since it reduces to 0 = 1,
an equation which is inconsistent. The two things aren't even related.

That is the whole point here. Computer science and programming
languages have objects. Mathematics has no such concept whatsoever,
unless you wish to define one. You're welcome to do so with a rigorous
definition that you can publish papers about and decide whether other
mathematicians are interested in your line of reasoning, but pretending
that there is a natural overlap between the mathematical concepts of
equality and identity and the computer scientific ones (especially since
the term _identity_ isn't even used in remotely the same way) is simply
ignoring the fact that other people either won't know what you mean or
will presume you're misunderstanding something. Because, based on your
previous comments, you are.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis

Do we ask what profit the little bird hopes for in singing?
-- Johannes Kepler, 1571-1630

Steven D'Aprano

unread,
Jan 5, 2009, 3:41:08 AM1/5/09
to
On Sun, 04 Jan 2009 20:03:11 -0600, Derek Martin wrote:


> I am happily ignorant of C#. As for Java, take the following code:
>
> a = 6;
> a = 5;
>
> In Python, when you execute the equivalent code, it causes two different
> objects to spring into existence, the first of which may be cleaned up
> by the GC (except that since we're using small integers, that's not
> likely to happen). Unless I'm misinformed (which is very possible, my
> experience with Java has been extremely limited) in Java that's not the
> case... the storage is allocated to the name a when you execute its
> declaration, and the *same storage* is reused upon subsequent
> assignment.
>
> That behaves exactly like named bins.

In the case of Java, that's because Java uses two assignment models:
named bins for "primitives" like ints and floats, and the Python model
for class instances, which is *nearly* everything in Java except a few
primitive types.

>> > And for that matter, it's pretty unintuitive generally.
>>
>> Names and objects are quite "natural" IMHO. There are many real world
>> objects which we attach one or more names to, or refer to in sequences
>> like "please give me the third book on that shelve" (``shelve[2]``).
>
> Indeed, but the way we assign names to them does not behave as it does
> in Python.

It doesn't?

Oh my, you're going to be confused in a few weeks when The President of
the USA ceases to be George W Bush and becomes Barack Obama. Same name
(or rather, title), different object (person).

> Nor does Python's assignment work like it does in algebra,

Nor does any programming language, with the possible exception of
computer algebra systems.


> or anywhere else the Python student is particularly likely to have seen
> variable assignment before encountering it in Python. Let's define
> intuitive, shall we? From dictionary.com (choosing the definition which
> most easily makes my point):
>
> intuitive: adj. capable of being perceived or known by intuition.
>
> I'm going to go out on a limb and assert that there's NO POSSIBLE WAY a
> student could intuit Python's variable assignment behavior, having never
> been exposed to that same behavior prior.

Unless they've used Java, Perl, Ruby, or any number of other languages.

> It needs to be taught.

Exactly the same as the named bins assignment model needs to be taught.

But, really, you're exaggerating the differences. There are differences
of course, but for somebody writing a simple programming with (say)
mathematical expressions, there's little or no difference between the
models.

x = 4
if y > 2:
x = x-1
else:
x = x+1
print x+y

will have the same effect whether you are using the named bins model or
not.

[...]


> I cheerfully disagree. :) "Named bins" is essentially how algebra
> works,

I don't think so. Variables in algebra are quite different from variables
in programming languages. Contrast the statement:

x = x+1

as a programming expression and an algebraic equation. As a programming
expression, it means "increment x by one". But as an algebraic
expression, it means "x is some value such that it is equal to one more
than itself", and there is no solution to such an equation.

In algebra, a variable name (like x, or c) generally represents one of
three things:

(1) an an unknown quantity to be solved for;

(2) a constant (either a known constant, or an arbitrary parameter); or

(3) an alias, such as when you do a change-of-variable.

One thing which algebraic variables are not is a bucket or bin that you
can set to some value, then modify over and over again.


> and how several generations of computer languages, not to mention
> the actual machine language those generated, behaved, before the current
> crop.

Sure. And?

> Those interpretations came first, because, much as in the
> evolution of any other science, that was the model which was most
> intuitive or easily explained.

No no no no. That was the model that was most easily implemented!

Before the named bins model of assignment was pure machine code, where
you didn't have bins at all, just bits, and there was no distinction
between code and data. And before that was *wires* -- early programmers
literally had to plug and unplug wires to change the state of the
computer. And before that were purely mechanical devices, such as the
Enigma Machine, old calculators, and the grand-daddy of them all, Charles
Babbage's difference engine and it's precursors.

> But you need not take my word for it. Simply read the archives and see
> for yourself how much confusion this has caused on this list. [Please
> include the closely related behavior of parameter passing in your
> search.]

In my opinion, the cause of that confusion is nothing to do with Python's
assignment model, and everything to do with the instance of some people
to use named bins terminology when describing the Python model. If you
keep the named bins terminology for describing the named bins model,
you're fine; and if you keep the name/object terminology for describing
languages with names/objects, you're fine. You only run into trouble when
you mix them. That's when you get people confused because "Python is Call
By Something, but it doesn't behave like Call By Something in language
Foo I've used before".


--
Steven

Marc 'BlackJack' Rintsch

unread,
Jan 5, 2009, 5:37:53 AM1/5/09
to
On Sun, 04 Jan 2009 20:03:11 -0600, Derek Martin wrote:

> On Sat, Jan 03, 2009 at 10:15:51AM +0000, Marc 'BlackJack' Rintsch
> wrote:
>> On Fri, 02 Jan 2009 04:39:15 -0600, Derek Martin wrote:
>>
>> What's the difference between Python and Java or C# here!? Or are they
>> also "BIZARRE"!?
>
> I am happily ignorant of C#. As for Java, take the following code:
>
> a = 6;
> a = 5;
>
> In Python, when you execute the equivalent code, it causes two different
> objects to spring into existence, the first of which may be cleaned up
> by the GC (except that since we're using small integers, that's not
> likely to happen). Unless I'm misinformed (which is very possible, my
> experience with Java has been extremely limited) in Java that's not the
> case... the storage is allocated to the name a when you execute its
> declaration, and the *same storage* is reused upon subsequent
> assignment.
>
> That behaves exactly like named bins.

So does the equivalent in Python. Or to see it the other way: In both
languages it *behaves* like (re)binding the name `a` to two different
objects. So it is an implementation detail. Even a Python
implementation could reuse the same memory location to store the two
numbers.

>> > And for that matter, it's pretty unintuitive generally.
>>
>> Names and objects are quite "natural" IMHO. There are many real world
>> objects which we attach one or more names to, or refer to in sequences
>> like "please give me the third book on that shelve" (``shelve[2]``).
>
> Indeed, but the way we assign names to them does not behave as it does
> in Python.

In what way?

>> I think the "bin model" is more complex because you don't just have a
>> name and an object but always that indirection of the "bin".
>
> I cheerfully disagree. :) "Named bins" is essentially how algebra
> works,

No it isn't. Mathematics is about binding names and not about putting
values into bins. And a mathematical variable can't be rebound once you
assigned a value to it. The "intuitive" model for people with a math
background would be that of functional languages like Haskell, which is
even more strange for people used to "named bins" than the Python, Java,
Ruby, … approach.

> and how several generations of computer languages, not to mention
> the actual machine language those generated, behaved, before the current
> crop. Those interpretations came first, because, much as in the
> evolution of any other science, that was the model which was most
> intuitive or easily explained.

In terms of the underlying machine, but that is exactly what I meant by
the additional indirection of the bins. You just have to drag the low
level named bins into the explanation because it is an implementation
detail of the languages.

And there where always languages that use a model like Python parallel to
the "named bins languages", it is nothing new.

Ciao,
Marc 'BlackJack' Rintsch

Marc 'BlackJack' Rintsch

unread,
Jan 5, 2009, 6:15:12 AM1/5/09
to
On Sun, 04 Jan 2009 22:55:09 -0600, Derek Martin wrote:

> On Sun, Jan 04, 2009 at 09:30:20PM -0500, Steve Holden wrote:
>> > I'm going to go out on a limb and assert that there's NO POSSIBLE WAY
>> > a student could intuit Python's variable assignment behavior, having
>> > never been exposed to that same behavior prior. It needs to be
>> > taught.
>> >
>> As does assignment of any kind.
>
> I'm not sure that's true. Having taken algebra prior to learning Basic,
> I intuitively understood what this program would do when I executed it,
> the first time I saw the code, and before I read the explanation:
>
> 10 let x = 10
> 20 print x

Do you really thought of `x` as a named memory location where the bit
pattern for the floating point value 10 is stored, with just the algebra
knowledge!? Isn't "Ah there the name `x` is bound to the value 10." more
likely? As it is the technically easier and IMHO more intuitive
explanation when you go from math to programming.

> [Well, to be honest it's been a very long time since I've programmed in
> Pet BASIC, and the syntax may be wrong. The point is, just as I did
> then, I am positive that you intuitively understand what the above is
> intended to do, even if it is not valid BASIC syntax -- because if you
> did not, we would not be having this discussion.]

Syntax is correct. :-) The ``let`` is optional in Commodore BASIC.

But where is the difference to

x = 10
print x

? Wouldn't you have guessed what this Python program will do just the
same?

Ciao,
Marc 'BlackJack' Rintsch

Steve Holden

unread,
Jan 5, 2009, 1:23:04 PM1/5/09
to pytho...@python.org
Derek Martin wrote:
> On Sun, Jan 04, 2009 at 09:56:33PM -0600, Grant Edwards wrote:
>> On 2009-01-05, Derek Martin <co...@pizzashack.org> wrote:
>>> On Sat, Jan 03, 2009 at 11:38:46AM -0600, Grant Edwards wrote:
>>>> One presumes that Mr. Martin finds anything different from his
>>>> first computer language to be BIZARRE. He should try out
>>>> Prolog or something genuinely different.
>>> One's presumption would be mistaken. However thank you for
>>> illustrating my point so precisely, which was after all the
>>> condescending and insulting way people "communicate" with
>>> people whom (they think) know less than they do in this forum,
>>> and not actually how difficult or easy the assignment model of
>>> Python is to understand.
>> I'm sorry, but I really don't see how Python's assignment model
>> could be considered bizarre by anybody who's familiar with more
>> than one or two languages.
>
> And... what if one wasn't? The OP of this thread clearly didn't
> understand... Whereas if you've read the thread, clearly I do.
> Of course, had you read my post, you probably would have understood
> that my comment about the model being bizarre was intended to be
> viewed from the perspective of someone who *had not* seen anything
> like it before, which is LOTS of relatively new programmers, whether
> or not it might be old hat to anyone here. The ultimate point of my
> post was not so much about whether the assignment model of Python was
> or wasn't easy to understand; it was about the idea that when someone
> doesn't understand, we should try to help them instead of making snide
> remarks about how stupid or small-minded they are.

Even if they really are small-minded or stupid I agree this wouldn't be
helpful behavior. But neither would your characterization of Python's
assignment model as "bizarre" (even ignoring that you SHOUTED IT AT US),
and I have yet to see you admit that such a characterization was, shall
we say, inappropriate.

It takes little to admit one is in the wrong even when one isn't. I've
had to learn to do it because I often *am* wrong about things. Could you
be persuaded to consider the possibility that you met with a somewhat
hostile reaction (whether or not such a reaction was useful or
necessary) because you were, in a small way, poking people in the side
with a sharp stick?

If you couldn't I might find that a *little* bizarre.

Steve Holden

unread,
Jan 5, 2009, 1:31:48 PM1/5/09
to pytho...@python.org
Steven D'Aprano wrote:
> On Sun, 04 Jan 2009 20:03:11 -0600, Derek Martin wrote:
[...]>>>> And for that matter, it's pretty unintuitive generally.

>>> Names and objects are quite "natural" IMHO. There are many real world
>>> objects which we attach one or more names to, or refer to in sequences
>>> like "please give me the third book on that shelve" (``shelve[2]``).
>> Indeed, but the way we assign names to them does not behave as it does
>> in Python.
>
> It doesn't?
>
> Oh my, you're going to be confused in a few weeks when The President of
> the USA ceases to be George W Bush and becomes Barack Obama. Same name
> (or rather, title), different object (person).
>
No, he will doubtless describe the White House as a President variable
whose value has been overwritten. There are many fine jokes to be made
about the need to garbage-collect President Bush ...

>
>
>> Nor does Python's assignment work like it does in algebra,
>
> Nor does any programming language, with the possible exception of
> computer algebra systems.
>
I'm still waiting for an explanation of where assignment comes into
algebra in the first place.
>
[...]

>
>> Those interpretations came first, because, much as in the
>> evolution of any other science, that was the model which was most
>> intuitive or easily explained.
>
> No no no no. That was the model that was most easily implemented!
>
Agreed. In those days the von Neumann architecture was a shiny new
thing, and it was even a while before people thought of using computers
for symbolic rather than numeric operations (which is IMHO what makes
them so interesting).

> Before the named bins model of assignment was pure machine code, where
> you didn't have bins at all, just bits, and there was no distinction
> between code and data. And before that was *wires* -- early programmers
> literally had to plug and unplug wires to change the state of the
> computer. And before that were purely mechanical devices, such as the
> Enigma Machine, old calculators, and the grand-daddy of them all, Charles
> Babbage's difference engine and it's precursors.
>

Aah, the old Univac 1004. Sorry, I'm rambling.


>
>
>> But you need not take my word for it. Simply read the archives and see
>> for yourself how much confusion this has caused on this list. [Please
>> include the closely related behavior of parameter passing in your
>> search.]
>
> In my opinion, the cause of that confusion is nothing to do with Python's
> assignment model, and everything to do with the instance of some people
> to use named bins terminology when describing the Python model. If you
> keep the named bins terminology for describing the named bins model,
> you're fine; and if you keep the name/object terminology for describing
> languages with names/objects, you're fine. You only run into trouble when
> you mix them. That's when you get people confused because "Python is Call
> By Something, but it doesn't behave like Call By Something in language
> Foo I've used before".
>
>

This really does go to show that (some) people will argue about
anything, with the major intention of proving themselves right rather
than reaching a common understanding.

Derek Martin

unread,
Jan 5, 2009, 2:21:09 PM1/5/09
to Steve Holden, pytho...@python.org
On Mon, Jan 05, 2009 at 01:23:04PM -0500, Steve Holden wrote:
> Even if they really are small-minded or stupid I agree this wouldn't be
> helpful behavior. But neither would your characterization of Python's
> assignment model as "bizarre" (even ignoring that you SHOUTED IT AT US),
> and I have yet to see you admit that such a characterization was, shall
> we say, inappropriate.

Actually I did, in one of my two most recent posts. But as Steve
D'Arpano just pointed out (even though he clearly disagreed with me),
such a characterization is subjective, and as such you can't rightly
say it's inappropriate. That's the largest part of my point in
posting in this thread. Many folks do exactly that, very often.
Someone disagrees with you, tries to shed some light on a different
perspective, or simply fails to understand something, and some members
of this community treat them like heretics, fools, or criminals.

I understand why the assignment model works the way it does, and it's
quite sensible, *when you understand it*. However, I do also think
that to someone who has not encountered such a model before, and who
has not had it explained to them, and/or who has not the background to
understand why it is implemented that way, it very likely might seem
"markedly unusual in appearance, style, or general character and often
involving incongruous or unexpected elements;" as dictionary.com
defines the term bizarre. So no, I don't think that's a
mischaracterization at all.

As for using the term in all caps, I did so precisely because it was
clear to me that many people here think that it could not be unusual,
and I wanted to emphasize the fact that other perspectives exist...
That they are not the same as yours does not invalidate them!

> It takes little to admit one is in the wrong even when one isn't. I've
> had to learn to do it because I often *am* wrong about things. Could you
> be persuaded to consider the possibility that you met with a somewhat
> hostile reaction (whether or not such a reaction was useful or
> necessary) because you were, in a small way, poking people in the side
> with a sharp stick?

I fully expected to receive a hostile reaction, because I am
criticising the behavior of the collective, and supplying a dissenting
perspective -- something I knew from the start would trigger such
hostility *because it always does*. I have witnessed hostile
reactions time and time again in this forum, from some of the same
people who are dumping on me for suggesting that the assignment model
might be something other than obvious, and from others, for much less:
I expect it because I see it in response to nothing more than asking a
simple question, when the question displays a clear indication that
the poster has missed something critical preventing them from
understanding how to achieve their goals. My intent was exactly to
point out this behavior, in an attempt to call to people's attention
that it is what they are doing, and thereby discourage it. I fully
expected a negative response. You in particular have responded quite
well, but the rest of the community by and large has sadly not failed
to live up to my expectations, even in the face of me saying that that
is exactly what they are doing. Quite impressive.

Some of the comments from people include the idea that the assignment
model is nothing special, if you've encountered any one of a dozen
other languages. I didn't realize programming in any of those
languages was a prerequisite for posting questions here, or for
programming with Python. And that speaks to my ultimate point: Some
members of the community seem to make assumptions about what people
know or should know, or have experienced, and talk down to people who
haven't met their expectations. They meet different perspectives with
hostility. Posts which phrase questions in terms commonly used in
other programming paradigms are generally even more likely to be met
with that same hostility, when they could simply instead explain
politely that Python behaves according to a different model than what
they are used to. Often this happens, but too often not without
someone also letting the OP know what a mindless jerk he is...

*This* is the "common understanding" which I'd hoped could be
reached... But you were right... it's very difficult for people to
admit that they might be wrong.

Steven D'Aprano

unread,
Jan 5, 2009, 5:28:59 PM1/5/09
to
On Mon, 05 Jan 2009 13:21:09 -0600, Derek Martin wrote:

> Some of the comments from people include the idea that the assignment
> model is nothing special, if you've encountered any one of a dozen other
> languages. I didn't realize programming in any of those languages was a
> prerequisite for posting questions here, or for programming with Python.

It's not. But the tone of your argument suggests you think that matching
the named bins assignment model of the 1970s should be a prerequisite for
all new programming languages.


There are, in general, four types of programmers new to Python. In no
particular order:

(1) People with no programming experience at all. They won't have any
problems with Python's assignment model because they have no preconceived
ideas about how assignment should work.

(2) People who are used to name binding in Ruby, Java, etc. and so will
find Python's assignment model more or less identical.

(3) Those who come from an entirely different programming model, say,
Forth or Haskell. For them, Python's assignment model is going to be the
least of their worries.

(4) People who are used to the named bins model from C, Pascal or
Fortran, who will find some unusual corner cases where Python behaves
differently to their mental model of assignment (but not for simple
arithmetic using numbers).

Python is accessible to *all* of the above groups, although naturally
some will need to put in more effort in different directions than others.


The tone of reproach in your posts suggests that you believe that the
people in group 4 are more authentic programmers whose opinions are more
correct than those in groups 1-3. I do not think there is any good reason
to believe that group 4 is more special than the other groups.

Nor do I believe that newly created languages (as Python was, a decade
and a half ago) should be limited to following the named bin assignment
model for fear that C etc programmers will be put off by the (supposed)
bizarreness of name binding. Speaking as a former Pascal programmer, I
think most C, Fortran and Pascal programmers are far too smart for that.


> And that speaks to my ultimate point: Some members of the community
> seem to make assumptions about what people know or should know, or have
> experienced, and talk down to people who haven't met their expectations.
> They meet different perspectives with hostility.

In my experience, two perspectives are likely to be met with hostility:

* those which arrogantly assume that they are the One True and Correct
perspective and all others are inferior and wrong; and

* those which ignorantly assume that they are the only perspective
possible.


Your first post in this topic made the extraordinarily arrogant and
incorrect claim that:

[quote]


What the Python community often overlooks, when this discussion again
rears its ugly head (as it seems to every other hour or so), is that
its assignment model is BIZARRE, as in it's conceptually different
from virtually all other languages substantially taught in
undergraduate computer science programs.

[end quote]

We can see some pretty poor assumptions right there:

* That the Python community is capable of uniformly overlooking Python's
differences from other languages.

* That only languages "substantially taught" in undergraduate CS courses
matter.

It seems that you don't include in the Python community all those who use
the term "name binding" instead of variable assignment specifically
because it gives new users a clue that Python is not the same as C.

You've also missed out on probably twenty years of CS where Java (using
the same assignment model as Python!) has been *the* language of choice
for undergrad CS, not to mention those introductory courses which use
Python.

And then you're shocked, SHOCKED!!! that people respond sharply.

How different do you think the response would have been if you had said:

"What we in the Python community should try to remember is that for those
new to the language, there can sometimes be preconceived ideas about how
assignment works that clashes with Python's assignment model. From my own
perspective, I found the differences between Python's name binding model
and the named-bins model of C/Pascal/Fortran confusing at first, and to
be honest, I still get caught by those differences. Naturally this is a
general problem for every language, Python is hardly unique, but please
remember not to bite the newbies just because they are still thinking in
some other language."


--
Steven

Rhodri James

unread,
Jan 5, 2009, 6:05:43 PM1/5/09
to pytho...@python.org
On Mon, 05 Jan 2009 22:28:59 -0000, Steven D'Aprano
<st...@remove-this-cybersource.com.au> wrote:

> * That only languages "substantially taught" in undergraduate CS courses
> matter.

As an aside, I use only one of the languages I was taught in my Computer
Science course, and that only for poking my EMACS configuration. Every
other language I use (yes, including C) I learned afterwards.

Moral: times change.

--
Rhodri James *-* Wildebeeste Herder to the Masses

Aaron Brady

unread,
Jan 5, 2009, 9:01:55 PM1/5/09
to
On Jan 4, 1:28 am, Steven D'Aprano <st...@REMOVE-THIS-

Hi, a bit behind in the discussion. (What'd I miss?)

I think it would be funny in math if someone said, "No, the answer is
*that* five, not this one," or "Don't use that five, use this other
one." You can use either one.

Containers are funny in Python in that 'a in a' can be true. It can't
in real containers. Also true in 'a in b and a in c and b is not
c' (and 'b not in c' technically).

About the porch, you could rearrange some of the boards into a swing
or porch door or something, and it's not the same; even though you
have the same boards. In the Grandfather's Axe story, you could
divide the blade into two, and reattach both halves. It's the same
material, but in a different configuration.

And here's a funny example of the usage of 'same'.
-- X and Y have the same teacher.
-- X and Y have the same shower curtain.
-- X and Y have the same car.
-- X and Y have the same shirt.
-- X and Y have the same shirt on.

Do you think that context determines the meaning of all of these; that
is, that they never lead to confusion? Do you think they're common to
say, or do people find other ways, to avoid confusion? The meaning of
'same' varies from one to another, without syntactical markings.

I want to conclude that 'equality' and 'identicality' (sharing an
identity) are two of the meanings of same, and closely related enough
that they can be confusing for neophyte programmers. 'J and K are not
the same, just the same.'

I think earlier, when John said, you have to keep an eye on the porch
to know if it's the same between two points in time, he was observing
that 'id([])==id([])' can be true. The porch was secretly wrecked and
rebuilt overnight.

'Same' isn't too far down in frequency (U.K. corpus).
http://ucrel.lancs.ac.uk/bncfreq/lists/2_2_spokenvwritten.txt

> actual entire object (no matter how large). Identity could be divorced
> from memory location: the one object could exist in many different places
> in memory, in the same way that an object can exist in many different

Yes, and it's even possible that multiple objects could exist in the
same place, such as in a copy-on-write.

> above. And I think you're wrong to say that piece-wise transformations
> break down continuity of form. You are, in some sense, the same person
> who some years ago was a crawling baby unable to speak. There are

It's common enough to say, 'He's not the same person around his
parents.'

> porch, it remains the same porch. Likewise if I have a chest of drawers,
> and I take the top drawer and put it at the bottom, the bottom drawer in
> the middle and the middle drawer at the top, surely it is the same chest
> of drawers? I haven't even replaced anything, just moved them around.

Surely. But what if you remove them, and exchange them with new
drawers?

> The English and Australian cricket teams have been playing international
> Test cricket since 1877. None of the team members playing in 1877 are
> still alive today. The entire lineup of both cricket teams has been
> replaced repeatedly, and yet they are the same teams.

Yet, you could comfortably say, 'The team's not the same without
Michael Jordan (star player)'.

I don't think identity is indestructible. Over the years, the
ballpark, name, uniform, fan base, manager, owner, and players have
*all* changed. Not the same.

There's a famous psychology example about a brain injury, after which
the subject's friends said, 'He's not the same man anymore', and 'It
just isn't him.' I don't remember if they (his friends) were native
speakers or not.

Terry Reedy

unread,
Jan 5, 2009, 11:45:10 PM1/5/09
to pytho...@python.org
Aaron Brady wrote:

>
> Containers are funny in Python in that 'a in a' can be true.
> It can't in real containers.

Guido uses 'container' in the Ref Manual because such 'contain'
references (of an undefined nature). Thinking more abstractly, I use
'collection', rather that 'container' and think of the object as a
'roster' -- like for the members of a club. A bibliography of
bibliographies could list itself but would only metaphorically 'contain'
itself. An association of associations could conceivably be a member of
itself.

tjr

Mark Wooding

unread,
Jan 6, 2009, 8:05:50 AM1/6/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> wrote:

> By all means, if Derek doesn't like the assignment model used by Python
> (and Java, Ruby, C#, Perl, RealBasic, VisualBasic, Lua, and many other
> languages going back to at least CLU in the mid 1970s)

It goes back to Lisp in the late 1950s.

[snip stuff I agree with.]

-- [mdw]

Mark Wooding

unread,
Jan 6, 2009, 9:03:16 AM1/6/09
to
Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au> wrote:

> (3) Those who come from an entirely different programming model, say,
> Forth or Haskell. For them, Python's assignment model is going to be the
> least of their worries.

Actually, Haskell's assignment model (you have to grubbing about for
IORefs or STRefs to find it but it's there) is exactly the same as Lisp,
Scheme, Python, Dylan, Perl, Lua, Icon, Ruby, Erlang, ML, ...

The variables-and-containers-hold-references-to-objects idea is common
to a very large number (probably the majority? depends how you count) of
high-level languages.

Java is in the same category. C# is definitely not, since `struct's are
composite, mutable value types clearly distinguishable from anything
Python can do.

The main dissent is probably from Tcl, which pretends to copy values
-- even complex objects such as lists -- wholesale (though actually does
fancy copy-on-write things under the covers).

> Your first post in this topic made the extraordinarily arrogant and
> incorrect claim that:
>
> [quote]
> What the Python community often overlooks, when this discussion again
> rears its ugly head (as it seems to every other hour or so), is that
> its assignment model is BIZARRE, as in it's conceptually different
> from virtually all other languages substantially taught in
> undergraduate computer science programs.
> [end quote]
>
> We can see some pretty poor assumptions right there:
>
> * That the Python community is capable of uniformly overlooking Python's
> differences from other languages.
>
> * That only languages "substantially taught" in undergraduate CS courses
> matter.

And a massive assumption about the languages taught to CS undergrads
too. In particular, Scheme is a fairly popular language to teach to
undergrads, often as a first language. See, for example, `The Structure
and Interpretation of Computer Programs' by Abelson and Sussman, and the
(much more recent) `How to Design Programs' by Felleisen, Findler, Flatt
and Krishnamurthi.

> It seems that you don't include in the Python community all those who
> use the term "name binding" instead of variable assignment
> specifically because it gives new users a clue that Python is not the
> same as C.

Unfortunately, this practice causes other confusion, since `binding' is
often used (in other language communities, notably Lisp and the
functional languages) to describe the association between names and
slots that hold references.

Let me explain. I'll try to be clear, though I know that Stephen
already understands this stuff well.

At run-time, each named variable denotes a storage area (I'll call it a
slot[2]) which holds a reference to some object[1].

+-----+
name ----> | ref -----> object
+-----+

If we `assign' a different object to the variable, what really happens
is that the slot is modified to refer to the other object; but the name
continues to denote the same slot.

Usually `binding', or `rebinding', a name describes a different process,
whereby the name (for a while) denotes a different slot. This name-to-
slot mapping is important because it's the mapping which is inherited by
nested functions.

This is most clearly shown by example. Consider this Python
interaction.

In [1]: l = []

In [2]: for i in [1, 2, 3]:
...: l.append(lambda: i)
...:

In [3]: [f() for f in l]
Out[3]: [3, 3, 3]

This prints [3, 3, 3]. What's happened is that the lambdas have closed
over the prevailing /binding/ of i -- i.e., which reference slot it
denotes. Since the for loop operates by assignment, and /not/ by
rebinding i, the three lambdas all closed over the same environment, and
return the same value.

Scheme's DO loop, by contrast, really does operate by binding. Consider
this example of a GNU Guile interaction.

guile> (define l '())
guile> (do ((i (list 1 2 3) (cdr i)))
... ((null? i))
... (set! l (append l (list (lambda () (car i))))))
guile> (map (lambda (f) (f)) l)
$1 = (1 2 3)

That is, each time through the loop, the variable I denotes a
/different/ reference slot; the LAMBDAs close over different
environments, and the functions return different values. (This example
illustrates both binding and assignment, since the SET! changes the
value referred to in the slot denoted by L, without rebinding L.)

A very approximate translation of the above into Python looks like this.

In [1]: l = []

In [2]: items = [1, 2, 3]

In [3]: def _loop(ix):
...: if ix >= len(items): return
...: l.append(lambda: items[ix])
...: _loop(ix + 1)
...:

In [4]: _loop(0)

In [5]: [f() for f in l]
Out[5]: [1, 2, 3]

(I've cheated and used indices because Python lists don't have the
head/tail structure of Lisp lists.)

None of this is a criticism of Python's behaviour. (Sometimes it'd be
nice if `for' worked by rebinding, but sometimes it's better that it
doesn't.) But it is a criticism of the Python community's confusing use
of the word `binding' to mean something different from what fairly
closely-related communities use it to mean.

[1] Lisp has a notion of `unbound variables', which is another confusing
use of the terminology. What this usually means is that the
variable really refers to a special value, and the run-time signals
an error if it retrieves this value from a variable.

[2] `Slot' gets used a lot too. Sorry. This usage has nothing to do
with Lisp's structure or instance slots, and nothing to do with
Python's __slots__.

> You've also missed out on probably twenty years of CS where Java (using
> the same assignment model as Python!) has been *the* language of choice
> for undergrad CS, not to mention those introductory courses which use
> Python.

There's no way that Java has been taught anywhere for 20 years. It just
isn't old enough. Wikipedia claims that Java appeared in 1995, which
looks right to me. Python, released in 1991, is therefore older.

>
> And then you're shocked, SHOCKED!!! that people respond sharply.
>
> How different do you think the response would have been if you had said:
>
> "What we in the Python community should try to remember is that for those
> new to the language, there can sometimes be preconceived ideas about how
> assignment works that clashes with Python's assignment model. From my own
> perspective, I found the differences between Python's name binding model
> and the named-bins model of C/Pascal/Fortran confusing at first, and to
> be honest, I still get caught by those differences. Naturally this is a
> general problem for every language, Python is hardly unique, but please
> remember not to bite the newbies just because they are still thinking in
> some other language."
>
>


-- [mdw]

Mark Wooding

unread,
Jan 6, 2009, 9:12:19 AM1/6/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> wrote:

> I don't think so. Variables in algebra are quite different from variables
> in programming languages. Contrast the statement:
>
> x = x+1
>
> as a programming expression and an algebraic equation. As a programming
> expression, it means "increment x by one". But as an algebraic
> expression, it means "x is some value such that it is equal to one more
> than itself", and there is no solution to such an equation.

Surely there is. The solution is: 1 = 0 (and hence x is an -- no, /the/
-- element of the trivial ring).

> > and how several generations of computer languages, not to mention
> > the actual machine language those generated, behaved, before the current
> > crop.
>
> Sure. And?

Actally, this is true only for /very/ small values of `several'. There
was FORTRAN in 1957, with what you're calling the `named bins' model,
and I call assignment-is-copying, and Lisp in 1958, with the assignment-
is-pointer-diddling model.

-- [mdw]

Mark Wooding

unread,
Jan 6, 2009, 9:32:04 AM1/6/09
to
Derek Martin <co...@pizzashack.org> wrote:

> I think I have though, not that it matters, since that was never
> really my point. Python's assignment model requires more explanation
> than the traditional one, simply to state what it does. That alone is
> evidence (but not proof).

Hmm. Actually, it's not the assignment model which is strange at all.
It's the data model. What does an expression like

[1, 2, 3]

denote? Is it the list itself, or a /reference/ to the list? If you
answer the first, you'll want Tcl/C/Fortran semantics. If you answer
the second, you'll want Lisp/Python/Javascript semantics. If you answer
`it depends', you'll want to be confused.

Python decided that all values are passed around as and manipulated
through references. (There are no locatives: references are not values,
and you can't have a reference to a reference.) Lists store references;
tuples store references; and so on.

If one is to be able to implement complex data structures which involve
sharing of data (e.g., cyclic graphs) or which allow efficient
reorganization (e.g., various kinds of trees) we need to be able to
manage references to values somehow. There are a number of ways of
doing this.

* Everything is a reference. This is the most uniform. Once you've
got the hang of it, there are no surprises.

* Nothing is a reference. If you want complex data structures, you're
either screwed (e.g., if your data model is too weak) or you have to
invent them yourself using array indices or something wretched like
that. Tcl is in this category: you have to mess with (associative)
arrays or variable names to make complex data structures.

* Some values are references to others. This is like C, and causes
exciting problems when you get confused. C++ makes things more
confusing because dereferencing can happen implicitly. Perl manages
to be in this camp /and/ the first one. It's very strange.

* Some things are references, and some aren't. This is what Java and
C# do. Java says that only simple, atomic things are
non-references, so assignment looks the same either way, but you
can't store primitive things in containers expecting to store
references (until Sun added automatic boxing and unboxing --
eventually). C# makes matters more complicated by letting users
define structured mutable data which aren't handled by reference,
but does the boxing and unboxing thing transparently.

> As for there being no assignment in algebra, is that not really what
> variable substitution is?

No.

> They have different names, but in my estimation they perform exactly
> the same function. You're assigning specific values to the variables
> in an expression so that you can solve for a constant... just like in
> a computer program.

When you do this, you construct a different expression. They might have
equal values, but they're still different. (You can consider
equivalence classes under some appropriate equivalence relation if you
like, but that just makes things more complex.)

> There is even an allocation of memory: it's in your brain. :D

Ahh! You're modifying a memory location in your brain so that it refers
to a different expression. Isn't this the Lisp/Python/Javascript model?
;-)

-- [mdw]

Joe Strout

unread,
Jan 6, 2009, 11:01:31 AM1/6/09
to pytho...@python.org, Mark Wooding
Mark Wooding wrote:

> Derek Martin <co...@pizzashack.org> wrote:
>
>> I think I have though, not that it matters, since that was never
>> really my point. Python's assignment model requires more explanation
>> than the traditional one, simply to state what it does. That alone is
>> evidence (but not proof).
>
> Hmm. Actually, it's not the assignment model which is strange at all.
> It's the data model. What does an expression like
>
> [1, 2, 3]
>
> denote? Is it the list itself, or a /reference/ to the list? If you
> answer the first, you'll want Tcl/C/Fortran semantics. If you answer
> the second, you'll want Lisp/Python/Javascript semantics. If you answer
> `it depends', you'll want to be confused.

Well said!

You can easily see that assignment in Python is perfectly ordinary, by
comparing it to languages that have both values and references (such as
C++, Java, or REALbasic). Those languages have only one assignment
model, that operates on both values and references just fine.

Python has only references, and I think it's for this reason that some
people here try to pretend that it doesn't have them at all, thus
leading them to weird explanations of strange assignment and
argument-passing behavior.

> Python decided that all values are passed around as and manipulated
> through references. (There are no locatives: references are not values,
> and you can't have a reference to a reference.)

Also very clearly put.

If you don't mind, I may crib some of your verbage for
<http://www.strout.net/info/coding/valref/>, as it may be clearer than
my own.

Best,
- Joe

sturlamolden

unread,
Jan 6, 2009, 12:18:10 PM1/6/09
to
On Jan 2, 5:43 pm, Steve Holden <st...@holdenweb.com> wrote:
> Derek Martin wrote:
> > On Tue, Dec 30, 2008 at 02:21:29PM +0000, John O'Hagan wrote:
> [...]

> > What the Python community often overlooks, when this discussion again
> > rears its ugly head (as it seems to every other hour or so), is that
> > its assignment model is BIZARRE, as in it's conceptually different
> > from virtually all other languages substantially taught in
> > undergraduate computer science programs. And for that matter, it's
> > pretty unintuitive generally.
>
> I'd definitely argue against bizarre. It's actually very easy to
> understand, and Python is by no means the only language to have used it.

A statement like

f(x) = 1

has no meaning in most languages - including Python, C and Java.

C++ references allows operator= to be overloaded. It is one of few
languages where a statement like 'f(x) = 1;' maybe meaningful. But C++
references are addresses (pointers in disguise), not names. The = is
Python's name binding operator. Python is similar to Java in this
respect. If anything is bizarre here, it is C++ references.

P.S. The C statement '*f(x) = 1;' does have meaning, but 'f(x) = 1;'
do not. But in the former case, one is not assigning to the return
value. Python and Java do not have raw pointers like C.

sturlamolden

unread,
Jan 6, 2009, 12:45:02 PM1/6/09
to
On Jan 2, 11:39 am, Derek Martin <c...@pizzashack.org> wrote:

> What the Python community often overlooks, when this discussion again
> rears its ugly head (as it seems to every other hour or so), is that
> its assignment model is BIZARRE, as in it's conceptually different
> from virtually all other languages substantially taught in
> undergraduate computer science programs. And for that matter, it's
> pretty unintuitive generally.

For one thing, Python's 'assignment model' (an annoying buzzword) is
similar to that of Java. It cannot be that different from what is
thought in undergraduate CS classes.

But take a look at C++:

int& foobar(int& x) {
// blahblah
}

Now a statement like 'foobar(x) = y;' can actually have a meaning.

Whereas,

int* foobar(int& x) {
// blahblah
}

would make the same statement illegal. I have yet to see undergraduate
students knowing the difference between C++ pointers and references
after attending an introductory CS course.

Try to do the same in, say, Java. You will see that is behaves like
Python.

And as for bizarreness, I feel that Python and Java is greatly
surpassed by C++. Note that C do not share the bizarreness of C++.


Aaron Brady

unread,
Jan 6, 2009, 4:43:01 PM1/6/09
to
On Jan 6, 8:03 am, Mark Wooding <m...@distorted.org.uk> wrote:
> Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au> wrote:
snip

> > It seems that you don't include in the Python community all those who
> > use the term "name binding" instead of variable assignment
> > specifically because it gives new users a clue that Python is not the
> > same as C.
>
> Unfortunately, this practice causes other confusion, since `binding' is
> often used (in other language communities, notably Lisp and the
> functional languages) to describe the association between names and
> slots that hold references.
>
> Let me explain.  I'll try to be clear, though I know that Stephen
> already understands this stuff well.
>
> At run-time, each named variable denotes a storage area (I'll call it a
> slot[2]) which holds a reference to some object[1].
>
>               +-----+
>    name ----> | ref -----> object  
>               +-----+
>
> If we `assign' a different object to the variable, what really happens
> is that the slot is modified to refer to the other object; but the name
> continues to denote the same slot.
>
> Usually `binding', or `rebinding', a name describes a different process,
> whereby the name (for a while) denotes a different slot.  This name-to-
> slot mapping is important because it's the mapping which is inherited by
> nested functions.

Say you start with:
+------+
a ----> | ref1 -----> (1, 2, 3)
+------+
Then you can do:
+------+
a ----> | ref2 -----> (4, 5, 6)
+------+
But not:
+------+
a ----> | ref1 -----> (4, 5, 6)
+------+
That is, you can 'repoint a' to another 'ref', but not repoint a
'ref'.

I think one of the ideas we have trouble communicating is that [1, 2,
3] and [4, 5, 6] can be the same object (using '[:]='), but [1, 2, 3]
and [1, 2, 3] don't have to be.

Steven D'Aprano

unread,
Jan 6, 2009, 6:15:35 PM1/6/09
to
On Tue, 06 Jan 2009 14:03:16 +0000, Mark Wooding wrote:

>> You've also missed out on probably twenty years of CS where Java (using
>> the same assignment model as Python!) has been *the* language of choice
>> for undergrad CS, not to mention those introductory courses which use
>> Python.
>
> There's no way that Java has been taught anywhere for 20 years. It just
> isn't old enough. Wikipedia claims that Java appeared in 1995, which
> looks right to me. Python, released in 1991, is therefore older.

I stand corrected. Can we agree that Java has been the language of choice
for most of a decade?


--
Steven

Steven D'Aprano

unread,
Jan 6, 2009, 8:02:54 PM1/6/09
to
On Tue, 06 Jan 2009 14:32:04 +0000, Mark Wooding wrote:

> Derek Martin <co...@pizzashack.org> wrote:
>
>> I think I have though, not that it matters, since that was never really
>> my point. Python's assignment model requires more explanation than the
>> traditional one, simply to state what it does. That alone is evidence
>> (but not proof).
>
> Hmm. Actually, it's not the assignment model which is strange at all.
> It's the data model. What does an expression like
>
> [1, 2, 3]
>
> denote? Is it the list itself,

Yes.


> or a /reference/ to the list?

No.


> If you answer the first, you'll want Tcl/C/Fortran semantics.

Absolutely not! I want *Python* semantics, and amazingly enough, that's
*just what Python gives*.


> If you answer the second, you'll want Lisp/Python/Javascript
> semantics.

If I wanted a reference to a list, I'd expect to *dereference* the
reference to get to the list. That's not what Python forces you do to:
you just use the list as the list object itself.

This isn't hard people. Stop confusing the implementation details of how
CPython works under the hood with Python level code.

In Python, [1, 2, 3] is a list, not a reference to a list. When you pass
[1, 2, 3] to a function, the function sees the list you passed it. The
function doesn't see "a reference to a list", it sees a list:

>>> def func(x):
... print type(x)
...
>>> func([1, 2, 3])
<type 'list'>


It's so easy, some people refuse to believe it could be that easy, and
insist on complicating matters by bring the implementation details into
the discussion. Just stop, please. References belong in the
*implementation*, nothing to do with Python level code.

In Python code, there are no references and no dereferencing.


> Python decided that all values are passed around as and manipulated
> through references.

Oh really? Then why can't I write a Python function that does this?

x = 1
y = 2
swap(x, y)
assert x == 2
assert y == 1

You can't, because Python doesn't have references. In a language with
references, that's easy. Here's an untested Pascal version for swap:

procedure swap(var x: integer, var y: integer);
var
tmp: integer;
begin
tmp := x;
x := y;
y := x;
end;

It's harder (impossible?) to write a version that will operate on
arbitrary types, but that's statically typed languages for you.

> (There are no locatives: references are not values,

But references *are* locatives.


> and you can't have a reference to a reference.) Lists store references;
> tuples store references; and so on.

No no no, lists and tuples store *objects*. Such storage happens to be
implemented as pointers in CPython, but that's an irrelevant detail at
the level of Python.


--
Steven

Steven D'Aprano

unread,
Jan 6, 2009, 9:25:21 PM1/6/09
to
On Tue, 06 Jan 2009 13:43:01 -0800, Aaron Brady wrote:


> I think one of the ideas we have trouble communicating is that [1, 2, 3]
> and [4, 5, 6] can be the same object

Not at the same time they can't.


> (using '[:]='), but [1, 2, 3] and [1, 2, 3] don't have to be.

I don't think this is hard to get across, if you think about objects.

You have a list. It's like a box. That box can hold items 1, 2 and 3. You
can replace those items with 4, 5 and 6, and it's still the same box.

Likewise, you can have a box with items 1, 2 and 3 inside it, and a
different box also with items 1, 2 and 3, and they're still different
boxes.

The only tricky thing is that items 1, 2 and 3 can be inside two
different boxes at the same time. There's no obvious real world analogy
to that without the boxes being nested. This ability for objects to be in
two places at once (or even to be inside themselves!) is one of the few
reasons why Python's use of references in the implementation needs to be
mentioned.

--
Steven

ru...@yahoo.com

unread,
Jan 6, 2009, 10:21:13 PM1/6/09
to
On Jan 6, 7:03 am, Mark Wooding <m...@distorted.org.uk> wrote:
...

> > It seems that you don't include in the Python community all those who
> > use the term "name binding" instead of variable assignment
> > specifically because it gives new users a clue that Python is not the
> > same as C.
>
> Unfortunately, this practice causes other confusion, since `binding' is
> often used (in other language communities, notably Lisp and the
> functional languages) to describe the association between names and
> slots that hold references.

Is not the proper term "aliasing"? Perhaps Python "variables" should
be called "alises".

From http://en.wikipedia.org/wiki/Aliasing_(computing)
"aliasing describes a situation in which a
data location in memory can be accessed through
different symbolic names in the program."

Mark Wooding

unread,
Jan 6, 2009, 10:36:50 PM1/6/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> wrote:

> If I wanted a reference to a list, I'd expect to *dereference* the
> reference to get to the list. That's not what Python forces you do to:
> you just use the list as the list object itself.

That's odd. No, you give a reference to the list to a function, and the
function messes with the list for you.

> This isn't hard people. Stop confusing the implementation details of
> how CPython works under the hood with Python level code.

I'm not confusing anything. This is conceptual-model stuff, not
implementation details. (Further discussion below.)

> In Python, [1, 2, 3] is a list, not a reference to a list.

In [1]: l = [1, 2, 3]

In [2]: l[1] = l

In [3]: l
Out[3]: [1, <Recursion on list with id=3079286092>, 3]

Now, if you're right, then l directly contains itself and some other
stuff, which is obviously absurd: it's a list, not a Tardis. If I'm
right, then l is bound to a reference to a list which contains three
references, two of them to integers and a third to the list itself.
This doesn't seem absurd at all any more.

Variables are not the only places where sharing can occur! Explaining
this is much harder if you don't start from the idea that all you're
doing is carting uniformly shaped references about.

Another example:

In [1]: a = [1, 2, 3]

In [2]: b = (a, a)

In [3]: b
Out[3]: ([1, 2, 3], [1, 2, 3])

In [4]: a[1] = 0

In [5]: b
Out[5]: ([1, 0, 3], [1, 0, 3])

If b is a tuple containing two copies of a, then this shouldn't have
happened. The only satisfactory explanation is that the tuple that b
refers to actually contains two references to the same list, so when I
mutate that list, the change shows up twice.

> When you pass [1, 2, 3] to a function, the function sees the list you
> passed it. The function doesn't see "a reference to a list", it sees a
> list:
>
> >>> def func(x):
> ... print type(x)
> ...
> >>> func([1, 2, 3])
> <type 'list'>

It sees the reference. `type' sees the reference. `type' digs the type
of the object out of the reference, and returns you a reference to the
type.

> It's so easy, some people refuse to believe it could be that easy, and
> insist on complicating matters by bring the implementation details into
> the discussion. Just stop, please. References belong in the
> *implementation*, nothing to do with Python level code.

I'm not getting into implementation details. I'm presenting a mental
model. The `they're objects: they contain other objects' model is
invalidated when you create circular or shared structures, as I've shown
above.

There are other epicyclic explanations you could invent to explain
sharing, maybe -- like keeping lists of clones, and magically updating
all the clones whenever one us mutated. That may even be a valid
implementation for a distributed Python (with cached copies of objects
and a cache-coherency protocol and all that), but it makes a rotten
mental model. And it still doesn't explain circularity.

Internally, Tcl uses pointers to values in its implementation. The
common currency inside the Tcl interpreter is a Tcl_Obj *. (It used to
be a char *, before Tcl 8.) So Tcl could easily offer the same
semantics as Python and friends. But there's a twist. Tcl does
copy-on-write. It's just impossible to make a circular value in Tcl,
and sharing doesn't happen. For example, here's a snippet of a tclsh
session.

% set l {a b c}
a b c
% lreplace $l 1 1 $l
a {a b c} c

Tcl really /can/ be explained without talking about references. The
existence of Tcl_Obj, and its strange dual-ported nature (it contains a
string and an internal representation, and lazily updates one from the
other, and uses the string in order to allow changes of internal
representation as necessary) really is an implementation detail, and
it's possible to have a full understanding of the behaviour of Tcl
programs without knowing about it.

This is just impossible with Python. Reference semantics pervade the
language.

> In Python code, there are no references and no dereferencing.

You're right! But the concept is essential in understanding the
semantics of the language. Even though no references are explicitly
made, and no dereferencing explicitly performed, these things are done
repeatedly under the covers -- and failure to understand that will lead
to confusion.

> > Python decided that all values are passed around as and manipulated
> > through references.
>
> Oh really? Then why can't I write a Python function that does this?
>
> x = 1
> y = 2
> swap(x, y)
> assert x == 2
> assert y == 1

Because the function is given references to the objects. It's not given
references to /your/ references to those objects. Therefore it can't
modify /your/ references, only its ones.

Pedantic answer:

def swap(hunoz, hukairz):
global x, y
x, y = y, x

(Maybe nonlocal for Python 3.)

> You can't, because Python doesn't have references. In a language with
> references, that's easy. Here's an untested Pascal version for swap:

[snip]

That's call-by-reference, which is a different thing. Python, like
Lisp, Scheme, Javascript, ML, Haskell, Lua, Smalltalk, Erlang, Prolog,
Java, and indeed C, does call-by-value exclusively. This deserves to be
called out as a display:

Python passes references by value.

By contrast, Pascal (sometimes) passes values by reference!

The terminology is admittedly confusing, because it comes from different
places. If you don't like me talking about Python having references,
then pretend I've been saying `pointer' instead, all the way through. I
think `pointer' and `reference' are synonymous in this context, attempts
by Stroustrup to confuse everybody notwithstanding. But `pointer' has
unhelpful connotations:

* pointers are more usually values rather than strange behind-the-
scenes things, e.g., in C;

* pointers, probably because of C, are associated with scariness and
non-safe-ness; and

* talking of pointers does seem like it's getting towards
implementation details, and I wanted to avoid that.

Anyway, call-by-value means that the function gets given copies of the
caller's arguments; call-by-reference means that the function gets told
where the caller's arguments are. In other words call-by-reference
introduces /another/ level of indirection between variables and values.

> > (There are no locatives: references are not values,
>
> But references *are* locatives.

No! A locative is a /reified/ reference -- a /value/ that /is/ a
reference. That is a locative is a reference, but a reference need not
be a locative. (A sheep is a mammal, but not all mammals are sheep.)

The Lisp Machine had real locatives. You dereferenced them using CAR
and RPLACA -- most unpleasant. In modern Lisp systems they seem to have
died a death, probably because making them work with fancy things like
resizing arrays when you don't have invisible pointers is too painful.

> No no no, lists and tuples store *objects*. Such storage happens to be
> implemented as pointers in CPython, but that's an irrelevant detail at
> the level of Python.

Uh-uh. There's no way that an object can store itself and still have
room left over. The idea is just crazy. It can't possibly fit. (Axiom
of foundation, if you're into that funky stuff.) If you say `no, but it
can store a reference to itself', then everything makes sense. It's
completely uniform, and not very scary.

Lisp people draw these box-and-pointer diagrams all over the place

+-----+-----+
| * | *------> NIL
+--|--+-----+
|
v
3

to show how the data model works. Of course, the Lisp data model is
/exactly the same as Python's/.

After a while, the diagrams get less pedantic, and tend to show values
stashed /in/ the cons cells. In fact, this is actually closer to most
implementations for small things like fixnums, characters and flonums,
because they're represented by stashing the actual value with some
special not-really-a-pointer tag bits -- but the program can't tell, so
this doesn't need to be part of your mental model until you start
worrying about performance hacking and why your program is consing so
much.

-- [mdw]

Mark Wooding

unread,
Jan 6, 2009, 10:49:02 PM1/6/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> wrote:

> The only tricky thing is that items 1, 2 and 3 can be inside two
> different boxes at the same time. There's no obvious real world analogy
> to that without the boxes being nested. This ability for objects to be in
> two places at once (or even to be inside themselves!) is one of the few
> reasons why Python's use of references in the implementation needs to be
> mentioned.

Ahh. So it /does/ need to be mentioned after all. But you're wrong:
it's not an implementation detail: it's an essential part of the
language semantics.

A better analogy. The objects are scattered across the floor. No
object is contained in another. However, we have a plentiful supply of
bits of string, each of which is tied to a Teflon-covered paperweight at
one end and has a blob of Blu-Tack on the other. Instead of putting
something in a box directly, what we do is grab a piece of string, stick
the Blu-Tack to the thing, and put the paperweight in the box. This
way, we can stick several bits of string to the same object and put the
paperweights in different boxes. Indeed, nothing stops us sticking two
bits of string to a box, and putting both paperweights inside that same
box. But fitting a box into itself twice requires origami skills that
frighten me.

The Teflon stops the Blu-Tack from sticking to the paperweights, 'cos
you're not allowed to do that.

There's a daemon who comes around periodically and cleans up the mess of
paperweights which aren't in boxes, and tidies away things which don't
have any string stuck to them any more, but really he's just an
implementation detail and you wouldn't need him if your floor was big
enough and you had enough bits of sufficiently long string.

-- [mdw]

Mark Wooding

unread,
Jan 6, 2009, 11:20:26 PM1/6/09
to
ru...@yahoo.com <ru...@yahoo.com> wrote:

> Is not the proper term "aliasing"? Perhaps Python "variables" should
> be called "alises".

No. The proper term is most definitely `binding': see SICP, for
example. (Wikipedia has a link to the full text.)

The topic of `aliasing' deals with a problem in compiler implementation,
where certain optimizations are valid only if two objects are known not
to share storage, so that mutating one won't alter the other. This is a
particular problem for C, since C programs makes heavy use of pointers;
also, Fortran semantics allow the compiler to assume that aliasing does
not occur in a number of places, and C compiler writers are keen to keep
up with Fortran performance levels.

In a wider context, `aliases' tend to be /additional/ names for things,
with the connotation of being secondary to some primary or canonical
name. For example, Linux 2.2 network interfaces had `aliases', which
were additional logical interfaces associated with the physical
interface, but with different (but related) names and distinct
addresses. Nowadays, Linux network interfaces can have multiple
addresses anyway, and the idea of aliases is left as a compatibility
hack.

-- [mdw]

Steve Holden

unread,
Jan 7, 2009, 12:19:11 AM1/7/09
to pytho...@python.org
Thanks for nailing that one. I have long felt the semantics of Python
could be but poorly served without the use of the term "reference" (and
indeed I have pointed out int he past that the language reference manual
feels free to use the term liberally), but I wasn't able to persist long
enough to bring the conversation to this conclusion (except that I am
pretty sure this *won't* be a conclusion ;-)

Hendrik van Rooyen

unread,
Jan 7, 2009, 3:20:43 AM1/7/09
to pytho...@python.org
"Mark Wooding" <m....w@distorted.org.uk> wrote:

> A better analogy. The objects are scattered across the floor. No
> object is contained in another. However, we have a plentiful supply of
> bits of string, each of which is tied to a Teflon-covered paperweight at
> one end and has a blob of Blu-Tack on the other. Instead of putting
> something in a box directly, what we do is grab a piece of string, stick
> the Blu-Tack to the thing, and put the paperweight in the box. This
> way, we can stick several bits of string to the same object and put the
> paperweights in different boxes. Indeed, nothing stops us sticking two
> bits of string to a box, and putting both paperweights inside that same
> box. But fitting a box into itself twice requires origami skills that
> frighten me.
>
> The Teflon stops the Blu-Tack from sticking to the paperweights, 'cos
> you're not allowed to do that.
>
> There's a daemon who comes around periodically and cleans up the mess of
> paperweights which aren't in boxes, and tidies away things which don't
> have any string stuck to them any more, but really he's just an
> implementation detail and you wouldn't need him if your floor was big
> enough and you had enough bits of sufficiently long string.
>

Lovely!

This is the nicest analogy I have seen,
and it seems to completely account
for all the observed effects.

The only other one that comes close
is Dennis L Bieber's "Wandering Names".

I propose that we name the garbage
collection demon "Steven" because
he has IMO lost this argument, and
therefore deserves to spend eternity
tied up in string.

;-)

- Hendrik

--
With the disappearance of the gas mantle and the advent
of the short circuit, man's tranquillity began to be threatened
by everything he put his hand on.
(James Thurber. First sentence of Sex ex Machina)


Steven D'Aprano

unread,
Jan 7, 2009, 3:53:29 AM1/7/09
to
On Wed, 07 Jan 2009 03:49:02 +0000, Mark Wooding wrote:

> Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> wrote:
>
>> The only tricky thing is that items 1, 2 and 3 can be inside two
>> different boxes at the same time. There's no obvious real world analogy
>> to that without the boxes being nested. This ability for objects to be
>> in two places at once (or even to be inside themselves!) is one of the
>> few reasons why Python's use of references in the implementation needs
>> to be mentioned.
>
> Ahh. So it /does/ need to be mentioned after all.

Only in the sense that the behaviour of *real world* objects don't
entirely match the behaviour of Python objects. If you just accept that
Python objects can be in two places at once, an unintuitive concept I
accept but hardly difficult to grasp, then you don't need to mention
references.

(Of course, as a purely practical matter, the English language makes it
difficult to avoid the word "reference" entirely. That's not my
intention.)

> But you're wrong:
> it's not an implementation detail: it's an essential part of the
> language semantics.

Er, pardon me, but you yourself suggested that one could implement Python
without using references to objects, "like keeping lists of clones, and

magically updating all the clones whenever one us mutated. That may even

be a valid implementation for a distributed Python".

Like you suggested, it would be a seriously rotten model for standard
Python, but it is possible. The language semantics specifies the
*behaviour*, not the *mechanism* required to implement that behaviour.

> A better analogy. The objects are scattered across the floor. No
> object is contained in another. However, we have a plentiful supply of
> bits of string, each of which is tied to a Teflon-covered paperweight at
> one end and has a blob of Blu-Tack on the other. Instead of putting
> something in a box directly, what we do is grab a piece of string, stick
> the Blu-Tack to the thing, and put the paperweight in the box.

Not a bad analogy. I like it. But it still fails.

Why can't I stick the paperweight in the box *before* attaching the Blu-
Tack to something else, and then forget about attaching the Blu-Tack?
There's nothing in your model to prevent dangling pointers, except hand-
waving "it doesn't work like that".

I assume the string is made of Teflon, otherwise I could stick the Blu-
Tack to another piece of string. By the same token, the floor needs to be
Teflon too.

Why can't I grab the string by the end with the Blu-Tack and follow it
backwards to find out where the paperweight is? I obviously know how to
handle the end, because according to your model I'm sticking it to other
objects. I suppose maybe there's a robot that does that Blu-Tack sticking
for me, I just point to the object and say "That one!" and it happens.
The string itself is invisible except to radar, which the robot has, and
I don't. That way I can't follow the string backwards to find out where
the paperweight is. Hmmm. This model is getting awfully complicated:
Teflon string, Teflon paperweights, Blu-Tack, *and* a robot (presumably
Teflon as well), none of which are visible to Python code, as well as
objects which are.

> This
> way, we can stick several bits of string to the same object and put the
> paperweights in different boxes. Indeed, nothing stops us sticking two
> bits of string to a box, and putting both paperweights inside that same
> box. But fitting a box into itself twice requires origami skills that
> frighten me.

Ah, you've obviously never studied origami under Sensei Ping of the Clan
of the Pointed Stick!


> The Teflon stops the Blu-Tack from sticking to the paperweights, 'cos
> you're not allowed to do that.
>
> There's a daemon who comes around periodically and cleans up the mess of
> paperweights which aren't in boxes, and tidies away things which don't
> have any string stuck to them any more,

So there's a brief moment between creating the object and sticking the
Blu-Tack on it when the daemon might take the object and the string away?
No, I guess not, that's another thing I just have to take on faith... the
daemon knows not to touch anything until the robot has finished with it.

Can I tie two pieces of string together, stop the daemon from disposing
of them? Apparently not.

Objects in two places at one time isn't sounding that weird any more.

I actually do like your model, despite poking holes in it. As a model for
what CPython is doing under the hood, it pretty good.

But it's not a model for what a Python programmer does when writing
Python code. There's no action equivalent to "attach blob of Blu-Tack to
object", no action equivalent to "put the paperweight in the box". The
robot does that when you point to an object and say "put that inside the
box". The programmer doesn't do these things, he says "put that object in
the box" and the robot attaches the Blu-Tack and moves the paperweight.
The strings and paperweights and Blu-Tack are invisible and intangible to
the programmer, *and* they are an implementation detail: as you put it,
we could implement Python using clones of objects magically kept in sync,
no string required.

--
Steven

Mark Wooding

unread,
Jan 7, 2009, 5:17:55 AM1/7/09
to
Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> wrote:

> Only in the sense that the behaviour of *real world* objects don't
> entirely match the behaviour of Python objects. If you just accept
> that Python objects can be in two places at once, an unintuitive
> concept I accept but hardly difficult to grasp, then you don't need to
> mention references.

To my mind, explaining that objects can actually be in two (or three, or
any unbounded number) of places at once, stashed inside each other to an
arbitrary degree -- that looks like the excuses of someone who's been
caught in a lie. Maybe it was a useful lie-to-children, meant to avoid
explaining the full details in advance, but the time comes to put away
childish things, and learn the truth. (I can't believe I just quoted
Paul. I feel all dirty.)

> Er, pardon me, but you yourself suggested that one could implement
> Python without using references to objects, "like keeping lists of
> clones, and magically updating all the clones whenever one us mutated.
> That may even be a valid implementation for a distributed Python".
>
> Like you suggested, it would be a seriously rotten model for standard
> Python, but it is possible. The language semantics specifies the
> *behaviour*, not the *mechanism* required to implement that behaviour.

Yes, there's an isomorphism between the two, so technically either could
be used as a model to explain the behaviour of Python. But, to my mind
at least, the idea of references (or sticky bits of string) is the
simpler -- it doesn't involve doing anything`magically' -- so Occam
suggests that it's superior. I'm sure, if I tried, I could come with an
even more absurd model, or express it in more complicated ways, but the
power of a model lies in its combination of simplicity and explanatory
power.

The `they're just objects' model is very simple, but gets tied up in
knots explaining things. The `it's all references' model is only a
little more complicated, but explains everything.

It might be -- and I don't know, because I'm not an educator -- that the
`they're just objects' model hits a local maximum in the tradeoff
between simplicity and explanation that's sufficiently high that it's
useful for teaching beginners. It's hard to expose this simple model's
weaknesses without assignment (or messing with `is' or `id');
unfortunately, it's very easy to explose them once you do have
assignment (or any kind of mutable state). And Python's purely
functional subset is rarely used exclusively in nontrivial programs. So
I'm sceptical that this particular lie-to-children doesn't cause more
harm than good.

> Why can't I stick the paperweight in the box *before* attaching the Blu-
> Tack to something else, and then forget about attaching the Blu-Tack?
> There's nothing in your model to prevent dangling pointers, except hand-
> waving "it doesn't work like that".

Perils of posting at half past three in the morning, I'm afraid. I
seemed to have hit a creative streak, but my clarity of thinking was
definitely impaired.

You are only allowed to handle paperweights. A robot does the rest.
Some of the objects might give you splinters or paper cuts. The robot
is concerned about your safety and won't let you go near them. There's
a wall between you and the playpen, with a catflap in it. The robot
will fit through the catflap but you're too big.

(For advanced users only: there might be a secret hatch which lets you
into the main arena where the robot works, via a storeroom containing a
surprising quantity of handy power tools, heavy weaponry, and
explosives, but oddly lacking in safety goggles. You can build some
truly marvellous things by sneaking through here, and persuade the robot
to do things it wouldn't usually by threatening it at gunpoint, but you
can also blow yourself up.)

You tell the robot what you want him to do by handing him paperweights.
He doesn't take the paperweights away with him, but instead hooks onto
the string so that he can follow it to the other end. He's quite good
at following even tangled strings, and at finding paperweights in boxes
and hooking onto their strings too. The robot will stick new strings
onto objects at your request and hand you the paperweights.

> I assume the string is made of Teflon, otherwise I could stick the Blu-
> Tack to another piece of string. By the same token, the floor needs to be
> Teflon too.

You could do, if you were actually given a loose piece of string. But
you aren't, so that's OK. I was wrong that the paperweights needed to
be Teflon.

> Why can't I grab the string by the end with the Blu-Tack and follow it
> backwards to find out where the paperweight is?

Because you're never at that end. And the robot just won't do that.

(The daemon in the MIT Scheme environment /can/ do this for you. It
uses a feature called `wabbit hunting'. You set up a `Fudd thunk'
describing which objects you want it to find the paperweights of, and
set the thing to `wabbit season'. The daemon will track down the
`wabbits' -- boxes holding those paperweights -- that you asked for and
returns them. When you want it to stop doing this, you return to `duck
season'. Yes, it's very silly.)

> This model is getting awfully complicated: Teflon string, Teflon
> paperweights, Blu-Tack, *and* a robot (presumably Teflon as well),
> none of which are visible to Python code, as well as objects which
> are.

Wow. I didn't actually read this far before hitting `follow-up', but
you anticipated the robot. Well done. But, no, actually nothing needs
to be made of Teflon, and I was just tired.

> Ah, you've obviously never studied origami under Sensei Ping of the
> Clan of the Pointed Stick!

Apparently not. My origami skills are, alas, weak.

> So there's a brief moment between creating the object and sticking the
> Blu-Tack on it when the daemon might take the object and the string away?
> No, I guess not, that's another thing I just have to take on faith... the
> daemon knows not to touch anything until the robot has finished with
> it.

The daemon knows not to interfere with the robot, and the robot knows to
do everything in the right order. But the daemon is an optional part of
the model, so we can just ignore him until we're ready to deal with him.

The daemon's name is Maxwell, by the way. Say hello, Maxwell.

> Can I tie two pieces of string together, stop the daemon from disposing
> of them? Apparently not.

No, but you can confuse him for a little while by building box-
paperweight-string-box-... cycles. Eventually he cottons on to what
you've done, though.

> But it's not a model for what a Python programmer does when writing
> Python code. There's no action equivalent to "attach blob of Blu-Tack
> to object", no action equivalent to "put the paperweight in the box".

No, indeed. Python is a language for talking about paperweights. And
it's because of the paperweights that the duck-typing works: all the
paperweights are the same shape and size, so they're physically
interchangeable.

> The robot does that when you point to an object and say "put that
> inside the box". The programmer doesn't do these things, he says "put
> that object in the box" and the robot attaches the Blu-Tack and moves
> the paperweight.

Yup!

> The strings and paperweights and Blu-Tack are invisible and intangible
> to the programmer, *and* they are an implementation detail: as you put
> it, we could implement Python using clones of objects magically kept
> in sync, no string required.

You could try to explain Python in terms of paperweights only, but since
they all look identical, it's hard to see why interesting behaviour
emerges without explaining about the world on the side of the strings.

Of course, the paperweights-and-string-(and-robot-and-catflap-(and-
storeroom-cum-arms-cache)) model explains it all, and doesn't leave you
having to learn Sensei Ping's arcane origami skills.

If you're actually /in/ the arena with the objects, armed with the
ability to fold a box so strangely that you can store it in three other
boxes and itself, how come you never make a catastrophic mistake?

My answer is that the robot doesn't make mistakes often, and the worst
you can do to yourself is get in a bit of a tangle with those bits of
string. If you're really cunning, you might manage to persuade the
robot to fetch a hand-grenade from the storeroom and blow itself up, but
there'll be a new version of the robot available later which won't fall
for that trick.

-- [mdw]

sturlamolden

unread,
Jan 7, 2009, 6:45:00 AM1/7/09
to
On Jan 7, 2:02 am, Steven D'Aprano
<ste...@REMOVE.THIS.cybersource.com.au> wrote:

> In Python code, there are no references and no dereferencing.

The why does CPython keep track of reference counts?


> You can't, because Python doesn't have references. In a language with
> references, that's easy.

Python does not 'pass-by-reference' as Fortran or Pascal do.


> It's harder (impossible?) to write a version that will operate on
> arbitrary types, but that's statically typed languages for you.

In Python an assignment (re)binds the name to another value. You can
certainly write a swap method for mutable types. But you cannot use
the assignment operator to swap the values.


> No no no, lists and tuples store *objects*.


>>> a = 123456789
>>> b = [a]
>>> c = [a]
>>> d = [a, a]

>>> b[0] is a
True
>>> c[0] is a
True
>>> d[0] is a
True
>>> d[1] is a
True

Where is the object 'a' stored?

Marc 'BlackJack' Rintsch

unread,
Jan 7, 2009, 9:37:09 AM1/7/09
to
On Wed, 07 Jan 2009 03:45:00 -0800, sturlamolden wrote:

> On Jan 7, 2:02 am, Steven D'Aprano
> <ste...@REMOVE.THIS.cybersource.com.au> wrote:
>
>> In Python code, there are no references and no dereferencing.
>
> The why does CPython keep track of reference counts?

Show me the *Python* code that does that. Using reference counting for
memory management is an implementation detail. It's possible to use
other garbage collectors without the need of reference counting.

Ciao,
Marc 'BlackJack' Rintsch

Steve Holden

unread,
Jan 7, 2009, 4:35:53 PM1/7/09
to pytho...@python.org
Dan Esch wrote:
> Wait a sec...
>
> I think I get this...
>
> In essence, the implication of immutability for Python is that there is
> only one "parrot", one "spam,"in fact one anything. (This seems like it
> must hold for data primitives - does it hold for complex objects as
> well? It seems it must...) In addition there is only one 1, and one 2
> etc. We may or may not have realized that string in a memory address to
> which variable names can be bound, but should we do so, there is only
> one "parrot"
>
> Python, is in fact, a Platonic programming language. Weird. If I've
> got this right, worth chewing on....
>
'Fraid not. Certain immutables are cached by the interpreter, but most
are not.

>>> s1 = "a" + "b" + "c"
>>> n = 12345
>>> s2 = "ab" + chr(99)
>>> m = 2469 * 5
>>> s1 == s2
True
>>> s1 is s2
False
>>> n == m
True
>>> n is m
False
>>> id(s1), id(s2), id(n), id(m)
(2146661888, 2146661792, 14453620, 14453584)

ru...@yahoo.com

unread,
Jan 7, 2009, 6:06:47 PM1/7/09
to
On Jan 6, 9:20 pm, Mark Wooding <m...@distorted.org.uk> wrote:
> ru...@yahoo.com <ru...@yahoo.com> wrote:
> > Is not the proper term "aliasing"? Perhaps Python "variables" should
> > be called "alises".
>
> No. The proper term is most definitely `binding': see SICP, for
> example. (Wikipedia has a link to the full text.)

I thought you were objecting to Python's use of the term "binding"
when you wrote:

> Unfortunately, this practice causes other confusion, since `binding' is
> often used (in other language communities, notably Lisp and the
> functional languages) to describe the association between names and
> slots that hold references.

in response to someone talking about "...all those who use the term
\"name binding\" instead of variable assignment...".

Joe Strout

unread,
Jan 7, 2009, 6:34:14 PM1/7/09
to pytho...@python.org
Dan Esch wrote:

> In essence, the implication of immutability for Python is that there is
> only one "parrot", one "spam,"in fact one anything. (This seems like it
> must hold for data primitives - does it hold for complex objects as
> well? It seems it must...) In addition there is only one 1, and one 2
> etc.

That's not necessarily true. If you have

a = "par" + "rot"
b = "parrot"

then, most likely (though it depends on how clever the compiler
optimizations are), there are two different string objects containing
the data "parrot". In this case, "a == b" is true because string
equality testing compares the data, but "a is b" is false because a and
b refer to different objects.

And by the way, don't let the people claiming that Python's assignment
model is bizarre confuse you. Assignment and parameter-passing in
Python is exactly the same as in any other modern OOP language; it just
so happens that in Python, all variables are references, while in most
other languages, some variables are references and others are primitive
types. But it should be obvious (though apparently isn't, to some) that
this restricted, uniform data model does not fundamentally change
anything; it just makes Python a little more restricted and uniform.
For details, see: <http://www.strout.net/info/coding/valref/>

Best,
- Joe


Terry Reedy

unread,
Jan 7, 2009, 7:22:00 PM1/7/09
to pytho...@python.org
Joe Strout wrote:

> That's not necessarily true. If you have
>
> a = "par" + "rot"
> b = "parrot"
>
> then, most likely (though it depends on how clever the compiler
> optimizations are), there are two different string objects containing
> the data "parrot".

>>> a='par'+'rot'
>>> b='parrot'
>>> a is b
True

ru...@yahoo.com

unread,
Jan 7, 2009, 7:45:06 PM1/7/09
to
On Jan 5, 12:21 pm, Derek Martin <c...@pizzashack.org> wrote:
...
> I understand why the assignment model works the way it does, and it's
> quite sensible, *when you understand it*. However, I do also think
> that to someone who has not encountered such a model before, and who
> has not had it explained to them, and/or who has not the background to
> understand why it is implemented that way, it very likely might seem
> "markedly unusual in appearance, style, or general character and often
> involving incongruous or unexpected elements;" as dictionary.com
> defines the term bizarre. So no, I don't think that's a
> mischaracterization at all.
...

Ignoring the nit-picking over choice of words, or what
languages are taught in CS courses, I agree with Derek's
general point that Python's assignment semantics is *not*
the same as many other common languages, and that this
confuses people coming to Python from those languages,
as evidenced by frequent postings to this list by those
people. I concluded exactly the same a long time ago.

When I started using Python I had no problem with Python's
assignment semantics because I had been using references in
Perl for years. I did not have a very hard time with Perl's
references, after I recognized their similarities to C's
pointers. But as I recall, it took a *long* time to wrap
my mind around C pointers.

Here is the output of set of equivalent programs in five
common (at least at one time) languages (code below) that I
have worked in and that formed my "intuition" about how
assignment works.

Sure looks to me as though Python is the odd man out.

Perl:
1, 4, 3
1, 2, 3

Basic (MS VBA):
1 4 3
1 2 3

C:
1, 4, 3
1, 2, 3

Fortran:
1 4 3
1 2 3

Python:
[1, 4, 3]
[1, 4, 3]

Of course, one can dismiss these as non-mainstream or
non-modern languages, and maintain that all "important"
languages have the same assignment semantics as Python,
but then one is left having to explain the frequent
confusion about assignment that is visible on this list.
I find Derek's explantion more plausible than any others
I have read in this thread.

========================================================
Python:
#/usr/bin/python
a = [1,2,3]
b = a
a[1] = 4
print a
print b

========================================================
Perl:
#!/usr/bin/perl
@a = (1,2,3);
@b = @a;
$a[1] = 4;
print join (',', @a), "\n";
print join (',', @b), "\n";

========================================================
Basic:
Sub test()
Dim a, b
a = Array(1, 2, 3)
b = a
a(1) = 4
Debug.Print a(0), a(1), a(2)
Debug.Print b(0), b(1), b(2)
End Sub

========================================================
C:
#include <stdio.h>
main () {
int i; struct {int a[3];} a, b;
for (i=0; i<3; i++) {
a.a[i] = i+1; }
b = a;
a.a[1] = 4;
printf ("%i,%i,%i\n", a.a[0], a.a[1], a.a[2]);
printf ("%i,%i,%i\n", b.a[0], b.a[1], b.a[2]);
}

==========================================================
Fortran:
program test
integer a(3), b(3)
do 100, i=1,3
a(i) = i
100 continue
b = a
a(2) = 4
write(unit=*,fmt=*) a
write(unit=*,fmt=*) b
end

Erik Max Francis

unread,
Jan 7, 2009, 8:07:29 PM1/7/09
to

One exactly doesn't really say much. It's implementation dependent, and
depends on the length of the string:

>>> a = 'this is a much longer ' + 'parrot'
>>> b = 'this is a much longer parrot'
>>> a is b
False

In practice, tests like these are pretty much never useful. It's
completely implementation dependent when and under what circumstances
fundamental immutable objects are reused, and it's not useful anyway;
what you care about is whether two objects are equal or not, not whether
they're the same object through some optimization behind the scenes.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
All delays are dangerous in war.
-- John Dryden, 1631-1700

Rhodri James

unread,
Jan 7, 2009, 9:46:21 PM1/7/09
to pytho...@python.org
On Thu, 08 Jan 2009 00:45:06 -0000, <ru...@yahoo.com> wrote:

> When I started using Python I had no problem with Python's
> assignment semantics because I had been using references in
> Perl for years. I did not have a very hard time with Perl's
> references, after I recognized their similarities to C's
> pointers. But as I recall, it took a *long* time to wrap
> my mind around C pointers.

I'd suggest that part of the reason for that is C's blurring
of the line between arrays and pointers. You can treat them
interchangeably enough of the time that when you can't it
catches you by surprise.

My experience of teaching twelve-year olds Python is that
they understand assignment when it's explained in terms of
giving names to these objects (numbers, strings, wombats...)
that we've already shown them. It's a lot harder to get
them to understand the "putting an object into a labelled
box" model when working with other languages. I don't know
why this should be, but it is.

--
Rhodri James *-* Wildebeeste Herder to the Masses

Terry Reedy

unread,
Jan 8, 2009, 12:22:44 AM1/8/09
to pytho...@python.org
Rhodri James wrote:
> On Thu, 08 Jan 2009 00:45:06 -0000, <ru...@yahoo.com> wrote:
>
>> When I started using Python I had no problem with Python's
>> assignment semantics because I had been using references in
>> Perl for years. I did not have a very hard time with Perl's
>> references, after I recognized their similarities to C's
>> pointers. But as I recall, it took a *long* time to wrap
>> my mind around C pointers.
>
> I'd suggest that part of the reason for that is C's blurring
> of the line between arrays and pointers. You can treat them
> interchangeably enough of the time that when you can't it
> catches you by surprise.
>
> My experience of teaching twelve-year olds Python is that
> they understand assignment when it's explained in terms of
> giving names to these objects (numbers, strings, wombats...)
> that we've already shown them. It's a lot harder to get
> them to understand the "putting an object into a labelled
> box" model when working with other languages. I don't know
> why this should be, but it is.

Kids have little experience with being 'the guest in Room 203' or 'the
inmate in cell a-23'.

Steven D'Aprano

unread,
Jan 8, 2009, 2:45:35 AM1/8/09
to
On Wed, 07 Jan 2009 10:17:55 +0000, Mark Wooding wrote:

> Steven D'Aprano <ste...@REMOVE.THIS.cybersource.com.au> wrote:
>
>> Only in the sense that the behaviour of *real world* objects don't
>> entirely match the behaviour of Python objects. If you just accept that
>> Python objects can be in two places at once, an unintuitive concept I
>> accept but hardly difficult to grasp, then you don't need to mention
>> references.
>
> To my mind, explaining that objects can actually be in two (or three, or
> any unbounded number) of places at once, stashed inside each other to an
> arbitrary degree -- that looks like the excuses of someone who's been
> caught in a lie. Maybe it was a useful lie-to-children, meant to avoid
> explaining the full details in advance, but the time comes to put away
> childish things, and learn the truth. (I can't believe I just quoted
> Paul. I feel all dirty.)

All analogies are lies-to-children. I don't think this is any worse than
the lie-to-children about magic pieces of string that you can only handle
by the paperweight at one end. Both analogies contain leaky abstractions.


> The `they're just objects' model is very simple, but gets tied up in
> knots explaining things. The `it's all references' model is only a
> little more complicated, but explains everything.

But it *over* explains, because it implies things that "everybody knows"
about references in other languages that aren't true for Python.

Of course it's not literally true that "everybody knows" that you can use
references to implement a swap(x, y) procedure. But people coming from a
C or Pascal background tend to assume that everything is like C/Pascal,
and there are a lot of them. If C was a rare, unfamiliar language, my
opposition to using the term "reference" would be a lot milder. Maybe in
another five years?


> No, indeed. Python is a language for talking about paperweights. And
> it's because of the paperweights that the duck-typing works: all the
> paperweights are the same shape and size, so they're physically
> interchangeable.

Okay, the abstraction has leaked again... are the paperweights references
to the objects, or the names we've bound objects to? I'm confused...

How do we deal with anonymous objects in your model?


--
Steven

Steven D'Aprano

unread,
Jan 8, 2009, 3:37:12 AM1/8/09
to
On Wed, 07 Jan 2009 03:45:00 -0800, sturlamolden wrote:

> On Jan 7, 2:02 am, Steven D'Aprano
> <ste...@REMOVE.THIS.cybersource.com.au> wrote:
>
>> In Python code, there are no references and no dereferencing.
>
> The why does CPython keep track of reference counts?

Two different levels of explanation. At the level of Python code, you
don't see reference counts. You never manipulate reference counts
directly. The gc module does expose them, if you want to see them, but
the gc module deliberately peaks behind the curtains. It's special.

At the implementation level, CPython uses references so it needs
reference counts. Jython doesn't keep reference counts at all, because it
uses Java's garbage collection (or so I understand). And the hypothetical
Distributed Python uses clones of objects and a daemon which keeps them
in sync, and hence there are no reference counts because each clone is
attached once and once only.

>> You can't, because Python doesn't have references. In a language with
>> references, that's easy.
>
> Python does not 'pass-by-reference' as Fortran or Pascal do.

That's right. But sadly, if you tell people that Python uses references,
many people will say "How do I pass a reference to this object to a
function?".


>>>> a = 123456789
>>>> b = [a]
>>>> c = [a]
>>>> d = [a, a]
>
>>>> b[0] is a
> True
>>>> c[0] is a
> True
>>>> d[0] is a
> True
>>>> d[1] is a
> True
>
> Where is the object 'a' stored?

Somewhere in memory, floating free, where it is referred to under the
name 'a'. In CPython, it will be in the heap, unless it has been paged
out to disk.

In the lists 'b', 'c' and (twice) 'd'.

I don't have a problem with objects being in two places at the same time.
It's just a mental model. I understand that, underneath, the memory for
the object is in *one place*, somewhere, because distributed storage is a
hard problem and no existing Python does it. But I also understand that
underneath, *everything* is just mutable bytes. There are no ints or
strings or lists or dicts, they're just an abstraction. If you keep
looking behind the curtains, looking at the implementation of each level
of abstraction, eventually you'll get to bytes, and then electrons. If
you go there, then you'll conclude that the object 'a' isn't anywhere.

I'm happy with a high-level abstraction where Python objects can be in
more than one place at once. Now, how do you implement such an
abstraction? The easiest way is to have the object in one (hidden?)
place, and have everywhere else use a pointer or reference to it. But
that's a lower level of description than you can reach from Python code,
because you can't access those pointers. You can only infer that they are
there because otherwise you have to accept that objects can be in two
places at once.

Or because you've read the source code, but that's implementation.


--
Steven

Aaron Brady

unread,
Jan 8, 2009, 6:11:05 AM1/8/09
to
On Jan 8, 1:45 am, Steven D'Aprano

<ste...@REMOVE.THIS.cybersource.com.au> wrote:
> On Wed, 07 Jan 2009 10:17:55 +0000, Mark Wooding wrote:
snip

> > The `they're just objects' model is very simple, but gets tied up in
> > knots explaining things.  The `it's all references' model is only a
> > little more complicated, but explains everything.
>
> But it *over* explains, because it implies things that "everybody knows"
> about references in other languages that aren't true for Python.
>
> Of course it's not literally true that "everybody knows" that you can use
> references to implement a swap(x, y) procedure. But people coming from a
> C or Pascal background tend to assume that everything is like C/Pascal,
> and there are a lot of them. If C was a rare, unfamiliar language, my
> opposition to using the term "reference" would be a lot milder. Maybe in
> another five years?
>
> > No, indeed.  Python is a language for talking about paperweights.  And
> > it's because of the paperweights that the duck-typing works: all the
> > paperweights are the same shape and size, so they're physically
> > interchangeable.
>
> Okay, the abstraction has leaked again... are the paperweights references
> to the objects, or the names we've bound objects to? I'm confused...
>
> How do we deal with anonymous objects in your model?
>
> --
> Steven

Mark, hi, Steven, pleasure as always.

Neither side is perfect or wild; (Do admit it); How do we decide what
is best for newcomers to Python, depending on background?

Mark Wooding

unread,
Jan 8, 2009, 6:13:40 AM1/8/09
to
ru...@yahoo.com <ru...@yahoo.com> wrote:

> I thought you were objecting to Python's use of the term "binding"
> when you wrote:

[snip]

> in response to someone talking about "...all those who use the term
> \"name binding\" instead of variable assignment...".

Oh, that. Well, the terms are `binding' and `assignment'.

Python doesn't need another name for assignment, because actually its
idea of assignment is the same as anyone else's. The difference is in
the way it deals with objects. See argument elsewhere.

-- [mdw]

Steve Holden

unread,
Jan 8, 2009, 7:18:06 AM1/8/09
to pytho...@python.org

The crux of this mistake is assuming that all beginners are alike, and
that there is therefore a single "best" way to explain things to them.
Teaching should be a dialog, in which the teacher makes use of knowledge
revealed by the student about their existing knowledge and ways of
thinking to present ideas in an easily assimilable form.

In other words, don't treat all students the same.

Mark Wooding

unread,
Jan 8, 2009, 1:33:50 PM1/8/09
to
[Steven's message hasn't reached my server, so I'll reply to it here.
Sorry if this is confusing.]

Aaron Brady <casti...@gmail.com> wrote:
> On Jan 8, 1:45 am, Steven D'Aprano
> <ste...@REMOVE.THIS.cybersource.com.au> wrote:
> > On Wed, 07 Jan 2009 10:17:55 +0000, Mark Wooding wrote:
> >
> > > The `they're just objects' model is very simple, but gets tied up in
> > > knots explaining things. The `it's all references' model is only a
> > > little more complicated, but explains everything.
> >
> > But it *over* explains, because it implies things that "everybody knows"
> > about references in other languages that aren't true for Python.

I addressed this elsewhere. Summary: `pass-by-reference' is a different
thing to `all you manipulate are references': Python does pass-by-value,
but the things it passes -- by value -- are references.

(The `pass-by-*' notions are confusingly named anyway. Pass-by-name
doesn't actually involve names at all.)

> > Of course it's not literally true that "everybody knows" that you
> > can use references to implement a swap(x, y) procedure. But people
> > coming from a C or Pascal background tend to assume that everything
> > is like C/Pascal, and there are a lot of them. If C was a rare,
> > unfamiliar language, my opposition to using the term "reference"
> > would be a lot milder. Maybe in another five years?

I agree with the comment about Pascal, but C is actually pretty similar
to Python here. C only does pass-by-value. If you want a function to
modify your variable, you have to pass a pointer value which points to
it. Python has no pointer values, so you need a different hack. The
hack usually involves lists. (Though it's easier in the main to return
compound data objects like tuples. I don't suppose that a proposal for
true multiple return values would go down well here. No, didn't think
so...)

> > Okay, the abstraction has leaked again... are the paperweights references
> > to the objects, or the names we've bound objects to? I'm confused...

They're the references to the objects. You don't bind names to
objects. You bind names slots in which you store references.

This discussion -- I'd call it an argument, but that might give the
wrong impression, because I think we're being remarkably civil and
constructive by the standards of Usenet arguments! -- hasn't started on
the topic of variable bindings or environments yet.

> > How do we deal with anonymous objects in your model?
> >
> > --
> > Steven
>
> Mark, hi, Steven, pleasure as always.

Hello. ;-)

> Neither side is perfect or wild; (Do admit it);

It's true.

> How do we decide what is best for newcomers to Python, depending on
> background?

That I really don't know. I'm not good at teaching total beginners
(does it show?) because I'm too enmired in the theory. (It doesn't help
that I go off on tangents about how language X does something similar
but subtly different all the time, though my rich background comes in
very useful all over the place and that's something I think is worth
sharing.)

It probably doesn't help that I came to Python with a thorough
understanding of Scheme (among many others) under my belt, because many
Scheme concepts carry over directly, including the data model (it's all
references) and the variable model (nested, mutable, lexical
environments with closures).

What I am pretty sure of is that references are going to have to enter
the picture at some point, because other models get too complicated.

Oh, while I remember: the `distributed Python' model, with auto-updating
copies, only works for sharing. Circular structures still require
actual references or a Tardis.

-- [mdw]

Mark Wooding

unread,
Jan 8, 2009, 2:13:38 PM1/8/09
to
Erik Max Francis <m...@alcyone.com> wrote:

> Terry Reedy wrote:
>
> > >>> a='par'+'rot'
> > >>> b='parrot'
> > >>> a is b
> > True
>
> One exactly doesn't really say much. It's implementation dependent, and
> depends on the length of the string:
>
> >>> a = 'this is a much longer ' + 'parrot'
> >>> b = 'this is a much longer parrot'
> >>> a is b
> False

That Terry's example works is due to constant folding in the bytecode
compiler. Consider:

In [1]: a = 'parrot'

In [2]: a is 'par' + 'rot'
Out[2]: True

Fair enough. But build the string in a more complicated way:

In [3]: b = 'par'

In [4]: a is b + 'rot'
Out[4]: False

What's going on? In the first case, the compiler notices that both
operands to `+' are constants, and evaluates the concatenation at
compile-time. The resulting constant string is then interned if it's
short enough.

Putting part of the string in a variable is enough to stymie this
optimization -- the same compiler gets used in functions which can't
assume that the variable will still have the same value as it does now.
The concatenation method on strings doesn't try to intern the result, as
that might be a runtime performance loss.

> In practice, tests like these are pretty much never useful. It's
> completely implementation dependent when and under what circumstances
> fundamental immutable objects are reused, and it's not useful anyway;
> what you care about is whether two objects are equal or not, not whether
> they're the same object through some optimization behind the scenes.

Absolutely. The examples above provide insight into how the specific
implementation actually behaves; but that's of strictly academic
interest. (Well, I find that sort of thing interesting, anyway.)

-- [mdw]

Joe Strout

unread,
Jan 8, 2009, 2:57:05 PM1/8/09
to Mark Wooding, pytho...@python.org
Mark Wooding wrote:

>>>> The `they're just objects' model is very simple, but gets tied up in
>>>> knots explaining things. The `it's all references' model is only a
>>>> little more complicated, but explains everything.
>>> But it *over* explains, because it implies things that "everybody knows"
>>> about references in other languages that aren't true for Python.
>
> I addressed this elsewhere. Summary: `pass-by-reference' is a different
> thing to `all you manipulate are references': Python does pass-by-value,
> but the things it passes -- by value -- are references.

Quite right. It's easy to see this in languages where some types are
references and others are simple values; and even easier in such a
language that supports both pass-by-value and pass-by-reference (such as
REALbasic or VB.NET). Then you can easily see, in one language, all
combinations of [value type, reference type] * [pass by ref, pass by val].

In Python, we only have reference types, and we only have pass by value,
so out of the four combinations above, there is only one: references
passed by value. You'd think this would make it easier, but from the
raging debates and repeated obfuscation on this point, it apparently
makes Python MORE difficult to understand and explain (at least for some).

> I agree with the comment about Pascal, but C is actually pretty similar
> to Python here. C only does pass-by-value. If you want a function to
> modify your variable, you have to pass a pointer value which points to
> it.

Right -- a C/C++ pointer is (or at least, can be in normal usage) pretty
similar to a reference (though of course you can do more low-level and
hackish things with them too). In C, such a reference is always passed
by value, as in Python or Java, and just like the default mode in RB or
.NET. In C++, you can also choose to pass such a parameter by
reference, like the ByRef mode in RB and .NET. This parameter passing
mode is unavailable in Python or Java.

>>> Okay, the abstraction has leaked again... are the paperweights references
>>> to the objects, or the names we've bound objects to? I'm confused...
>
> They're the references to the objects. You don't bind names to
> objects. You bind names slots in which you store references.

Well put (again). This is technically the correct description, though
in casual usage, I think it's fine to occasionally gloss over some of
these layers as long as everyone involved understands what is meant.
(This is especially true when the references are to immutable objects,
which are functionally very similar to simple values.)

>> How do we decide what is best for newcomers to Python, depending on
>> background?
>
> That I really don't know. I'm not good at teaching total beginners

> (does it show?) because I'm too enmired in the theory. ...

FWIW, I've spent a fair amount of time teaching beginners, though not so
much in Python yet. But plenty of time in other languages where the
same questions come up. In my experience, pointing out that a variable
of any object type contains a *reference* to that object, rather than
the object data itself, and then illustrating with a couple of examples,
quickly clears up any confusion. I've never had a newbie require more
than a couple of exchanges on this topic before they get it. (And
before I joined the Python community, I never even felt the need to
actually draw a picture [1] to make it clearer.)

> What I am pretty sure of is that references are going to have to enter
> the picture at some point, because other models get too complicated.

I agree completely. I can barely understand the other models myself.

Best,
- Joe

[1] http://www.strout.net/info/coding/valref/


ru...@yahoo.com

unread,
Jan 8, 2009, 8:24:25 PM1/8/09
to
Mark Wooding wrote:
...

> Python doesn't need another name for assignment,

OK.

> because actually its
> idea of assignment is the same as anyone else's. The difference is in
> the way it deals with objects. See argument elsewhere.

"the same as anyone else's" only if [Python's] "idea
of assignment" does not include producing the same
results.

a = array (1,2,3)


b = a
a[1] = 4

print b

C, C++, VBA, Fortran, Perl: 1, 2, 3
Python: 1, 4, 3

Telling someone coming to Python from one of those
languages that Python's assignment works the same way
as those languages is confusing at best. "dealing
objects" is part of assignment semantics ISTM.


ru...@yahoo.com

unread,
Jan 8, 2009, 8:27:33 PM1/8/09
to
Mark Wooding wrote:
...

> I agree with the comment about Pascal, but C is actually pretty similar
> to Python here. C only does pass-by-value.

As a side comment (because it always bugs me when
I read this, even though I read it in very authoritative
sources), ISTM that C passes everything by value except
arrays; they are passed by reference (by passing a
pointer to the array by value.) Admittedly, the close
relationship between arrays and pointers makes it easy
conflate them.

Joe Strout

unread,
Jan 8, 2009, 11:22:17 PM1/8/09
to Python List
ru...@yahoo.com wrote:

> "the same as anyone else's" only if [Python's] "idea
> of assignment" does not include producing the same
> results.
>
> a = array (1,2,3)
> b = a
> a[1] = 4
> print b
>
> C, C++, VBA, Fortran, Perl: 1, 2, 3
> Python: 1, 4, 3

You are mistaken (except perhaps in the Fortran case, which is an
oddball by modern standards, and I don't know Perl well enough to judge).

C/C++ code:

int* a = malloc(3);
a[0] = 1;
a[1] = 2;
a[2] = 3;
int* b = a;
a[1] = 4;
print_array(b)
---> Result: 1, 4, 3

REALbasic code:

Dim a() As Integer = Array(1,2,3)
Dim b() As Integer = a
a(1) = 4
PrintArray b
--> Result: 1, 4, 3

VB.NET code would be very similar in syntax, and identical in behavior,
to the REALbasic code. Java would also have the same semantics, though
my Java is too rusty to get the syntax right without actually trying it.

If you can find a language where an array variable is NOT a reference
(and thus does not behave exactly as in Python, Java, REALbasic, C++,
etc.), then that language is either a dinosaur or some weird academic
oddity.

Best,
- Joe


It is loading more messages.
0 new messages