why cannot assign to function call

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Jan 9 05:01:00 EST 2009


On Thu, 08 Jan 2009 18:33:50 +0000, Mark Wooding wrote:

> [Steven's message hasn't reached my server, so I'll reply to it here.
> Sorry if this is confusing.]
> 
> Aaron Brady <castironpi at gmail.com> wrote:
>> On Jan 8, 1:45 am, Steven D'Aprano
>> <ste... at 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': 

You know, I've written a fair bit of Python code over the years, and I've 
never manipulated a reference *once*. Ints, strings, floats, lists, 
tuples... but references? Never.

I'm pretty sure that no other pure-Python coder has manipulated 
references either. They've manipulated objects. Whatever the VM does 
under the hood is another story.

If you insist on talking about implementations, then at least get it 
right: in Python, like every other programming language, all you do is 
flip bits. It's *all* bit flipping.

That's why we should try to keep the different layers of explanation 
separate, without conflating them. Python programmers don't actually flip 
bits, and neither do they manipulate references. Python programmers don't 
have access to bits, or references. What they have access to is objects.

(Of course, there are ways to get under the hood if you really want to.)


> Python does pass-by-value,
> but the things it passes -- by value -- are references.

If you're going to misuse pass-by-value to describe what Python does, 
*everything* is pass-by-value "where the value is foo", for some foo. You 
can't have anything but pass-by-value with current computer technology, 
because computers don't actually move arguments, they only copy bytes. So 
pass-by-value becomes a meaningless term, because it describes every 
computer language imaginable, including hypothetical ones using calling 
conventions not yet invented, and therefore explains nothing.


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

You might find them confusing, but I don't. What I find confusing is that 
people insist on misusing terminology invented for describing one type of 
behaviour in order to use it for a completely different type of behaviour 
just because of certain similarities under the hood.



>> > 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.

Except for arrays.


> If you want a function to
> modify your variable, you have to pass a pointer value which points to
> it.

Yes, because the variable is copied before the function sees it. So if 
you pass a struct, and modify one of the struct's fields, the caller 
doesn't see the change.

Now try that with Python, and you'll see completely different behaviour. 
(You'll have to use something *like* a struct, because Python doesn't 
have them. Try an object with attributes.)

In other words... C is call-by-value, and (according to you) Python is 
call-by-value, but they behaviour differently.


> 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...)

Out of curiosity, what makes Python returning tuples less "true" than 
"true multiple return values", and what can you do with TMRVs that you 
can't do with tuples?


>> > 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.

Amazing. It sure feels like it to me.

x = 23

There's a name, and an object, and I've bound the name to the object so I 
can refer to the object 23 by the name x.


>  You bind names slots in which you store references.

I'm pretty sure I don't. I'd have noticed.



You may have missed my last question:

>> > How do we deal with anonymous objects in your model?



> 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.

Well, I dare say that at *some* point all models are insufficient. The 
map is not the territory, and there's always something that gets left 
out. But I think your model with strings is more complicated: robots, 
sticky Blu-Tack, string that you can't touch or see, and so forth. 
Compared to that, TARDIS technology enabling objects to be in two places 
at once is remarkably straightforward. Despite it being physically 
unrealistic, it's logically simple.



-- 
Steven



More information about the Python-list mailing list