why cannot assign to function call

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Tue Jan 13 10:54:20 CET 2009

On Sat, 10 Jan 2009 15:46:35 +0000, Mark Wooding wrote:

> [Another tome.  I hope this contains sufficient new material to continue
> to be of interest to other readers.]

I found it interesting. I don't know about others. However, at 756 lines 
(including quoting) it was nearly double the size of my previous tome, so 
I think this discussion is clearly not going anyway. I think this 
conversation is reaching it's natural end. Frustration levels are rising. 
I could -- and in fact intended to -- write a point-by-point argument, 
but that would only send the size of this skyrocketing and probably 
nobody would read it. So I'm going to take a different tack in an attempt 
to reduce frustration levels: if I can't convince the other side they're 
wrong, can I at least get them to understand where I'm coming from a 
little better?

As I see it, this conversation is floundering on two radically different 
ideas about what it means to say a language uses pass-by-foo.

On the one hand, some people (me and possibly rurpy) consider "this is 
pass-by-foo" to be a statement about behaviour directly visible to the 
programmer. We have a set of behavioral traits in mind, and if a language 
exhibits those behaviours, then it is clearly and obviously pass-by-foo 
no matter how that behaviour is implemented. I'll call these the 

On the other hand, others (I'm going to put Joe and Mark into this group) 
consider "pass-by-foo" to be a statement about mechanism, or if you 
prefer, implementation. If a compiler does X, then the language is pass-
by-foo, regardless of behaviour. I'll call these the mechanists.

To a behaviorist, Python simply can't be pass-by-value, because it 
doesn't behave like pass-by-value in other languages (particularly C and 
Pascal). The Python community has a tradition of duck-typing: if it 
quacks like a duck and swims like a duck, then it is a duck in every way 
that is important. If it can't swim and doesn't quack, it isn't a duck, 
no matter how much duck DNA is in it. If it flies, that's irrelevant to 
the question, because some ducks fly and some don't.

According to the behaviorist view, what makes an evaluation strategy call-
by-reference is whether or not it exhibits the following three behaviours:

(1) passing a value to a function does not copy the value;

(2) modifications to the value inside the function are visible to the 

(3) assignments to the value inside the function are visible to the 

where "value" means the thing the programmer manipulates symbolically in 
source code. Values are ints, strings, lists and so forth. Pointers or 
references are *only* values if the language allows you to write the 
equivalent of:

ptr = SomeReferenceTo(x)  # like Pascal's ptr := ^x;
x = Dereference(ptr)  # like Pascal's x := ptr^;

According to this viewpoint, Python clearly cannot be pass-by-reference 
because (3) is not true.

Similarly, what makes pass-by-value is:

(1) passing a value to a function makes a copy of the value, where value 
is an entity the programmer can symbolically manipulate in source code 
(lists, ints, floats etc.);

(2) modifications to the value inside the function are not visible to the 

(3) assignments to the value inside the function are not visible to the 

According to this viewpoint, Python clearly cannot be pass-by-value 
either because neither (1) nor (2) are true. The underlying mechanism is 

Mechanists take a different view. A typical argument paraphrased from Joe 
in previous threads is:

"Of course Python makes a copy of the value you pass to a function. The 
difference is that the value you pass is a reference."

Mechanists reject the restriction that values only include entities 
manipulated by the programmer. Consequently they're prepared to say that 
values in Python aren't the things which Python programmers symbolically 
manipulate (strings, ints etc.) but are references. Needless to say this 
claim strikes behaviorists as nonsensical and rather incoherent. If the 
value of 2 isn't 2, then value has no meaning. If mechanists see the 
behaviorists as "willfully ignorant", the behaviorists see the mechanists 
as being blatantly obfuscatory, introducing irrelevant details and 
ignoring clear examples of the duck quacking.

And these two viewpoints are why this debate never ends, merely goes 
quite for a few weeks or months.


More information about the Python-list mailing list