why cannot assign to function call

Steve Holden steve at holdenweb.com
Fri Jan 9 17:42:16 CET 2009

Joe Strout wrote:
> Aaron Brady wrote:
>> Possible compromise.  You can think of functions as mutation-only.
>> You pass the object, and it gets a new (additional) name.  The old
>> name doesn't go in.  </compromise>
> That's correct.  The reference itself is passed in, not the variable (or
> expression) that held or generated the reference in the calling code.
> This is no different from, in C, passing an integer:
> void foo(int bar) {
>    bar = 42;
> }
> int baz = 0;
> foo(baz);
> This doesn't change baz because, speaking precisely, baz wasn't passed
> to foo -- only the *value* of baz (i.e. 0) was passed to foo.  Within
> foo, that value was stored in bar.  Assigning a new value to bar does
> not affect foo.
> It's the exact same thing when the value happens to be a reference to an
> object:
> typedef SomeClass* SomeClassPtr;
> void foo(SomeClassPtr bar) {
>    bar = new SomeClass();
> }
> SomeClassPtr baz = NULL;
> foo(baz);
> Again, we're not passing baz into foo; we're passing the *value* of baz
> (i.e. NULL) into foo.  That value is stored in bar within foo, and when
> we assign a new value (a reference to a freshly minted SomeClass object)
> into bar, of course it doesn't affect baz.
>> Regardless, IMO, references don't add any explanatory power; they just
>> make you feel cocky that you know what they are.
> Nonsense.  They are the simple and clear explanation of what's going on.
>> M: If 'fun()' returned a reference, you would be able to assign to it.
>> m: You can't assign to it.
>> C: It doesn't return a reference.
> C is false because M is false (at least, in the way I believe you mean
> it).  Or, more precisely, both M and m are nonsensical; what does it
> mean to "assign to a reference"?  It makes no sense.  What would it mean
> to assign to 42?
> You don't assign to references any more than you assign to integers or
> assign to strings or assign to None.  Those are all values, and you
> don't assign to values -- you assign to variables.  "Assign" means to
> give a new value to a variable, i.e. to let (or cause) a variable to
> have a new value.  (Ye olde BASIC even used the LET keyword to indicate
> this, e.g. LET X = 42.)  Speaking casually, we don't always make this
> distinction, but I think precision is needed here.
> So, I see two ways to make sense of your argument:
> M1: If 'fun()' returned a variable, you would be able to assign to it.
> m1: You can't assign to it.
> C1: It doesn't return a variable.
> This is true.  (Technically, instead of variable, we should say "LValue"
> here -- there are things slightly more complex than simple variables
> that can serve as the left-hand side of an assignment.  So replace
> "variable" with "lvalue" above if you prefer.)
> Or, the other way some may see it is:
> M2: If 'fun()' returned a reference, you might be able to mutate the
> object that refers to.
> m2: You can sometimes mutate the object it refers to.
> C2: 'fun()' returns a reference.
> This is true (though the logic is flawed, but fixable).
>> -- Why can't I assign to a function call?
>> -- Python variables are references only.
>> -- Ok, why can't I assign to a function call?
> You're right, "Python variables are references only" has nothing to do
> with it.  In a language where the only data type were "integer", you
> wouldn't be able to assign to a function call either.
> You can't assign to a function call because a function call is not
> itself an lvalue, and it doesn't return an lvalue.  That's just not
> something you can get for free from the type model; it's an extra
> feature that would have to be built into the language somehow, and
> Python doesn't have it.
> If assignment were an operator rather than a statement, and could be
> overridden in a class via some specially-named method -- or, for that
> matter, if the assignment statement looked for such a method when it
> finds an object reference on the left-hand side -- then any object could
> be an lvalue, and you COULD (in some cases) assign to the result of a
> function.  But it's not and it doesn't.
Pretty soon you guys will have me believing Python doesn't work ...

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

More information about the Python-list mailing list