I'm wrong or Will we fix the ducks limp?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Jun 9 03:36:30 EDT 2016


On Wednesday 08 June 2016 19:41, Antoon Pardon wrote:

>> What you seem to be describing is similar to reference parameter semantics
>> from Pascal. Assignment doesn't work that way in C, or Python.
> 
> I disagree. In python the assignment does work similar to the reference
> parameter semantics in pascal. See the following
> 
>   A = range[4]
>   B = A
>   B[2] = 5
>   print A # [0, 1, 5, 2]
> 
> This is exactly the result you would get with B as a reference parameter in
> pascal.

It might be the same result, but it is a different cause.

Your example demonstrates object mutation, not assignment. Although Python uses 
the same syntax X = X for both name binding (assignment) and item assignment, 
item assignment is a *mutator method*: it calls B.__setitem__, which modifies B 
in place. Since the name A is bound to the same object, it is hardly surprising 
that A shows the same change.

But since you think that assignment in Python behaves like Pascal var 
parameters (reference variables), you should be able to write a "swap" 
procedure that swaps two arguments. That's the definitive test for reference 
parameters, since it works in all languages with reference parameters (e.g. 
Pascal, Basic and C++), and doesn't work in any language without them (or 
equivalent, like Algol's pass-by-name parameters).

The Pythonic way to swap two variables is to use tuple unpacking:

a, b = b, a

but that uses a completely different mechanism to get the same effect. 
"Reference parameter" is all about mechanism.

I want to see the Python equivalent of Pascal's var parameters:

procedure swap(var a:integer; var b:integer);
  var
    temp: integer;
  begin
    temp := a;
    a := b;
    b := a;
  end;

(or the Algol equivalent, a slightly different mechanism), and then see it 
called like this:

a = 1
b = 2
swap(a, b)  # absolutely NOT `a, b = swap(a, b)`
assert a == 2 and b == 1


without passing in or making use of hard-coded parameter names.

That is my challenge to you: if you can write such a function, in pure Python, 
which swaps two parameters given as ordinary arguments (passing their names as 
strings does not count), then I will cheerfully apologise for doubting you, 
admit that I was wrong, and publicly acknowledge that Python does have 
reference variables just like you said.

If you cannot meet that challenge, then I would like you to acknowledge that 
whatever Python variables are, and however Python's assignment works, it is 
*not* the same as Pascal's reference variables, and so calling Python variables 
"reference variables" is misleading and an abuse of a well-established term 
from computer science since long before Python even existed.

Are you willing to accept that challenge?

Or are you going to try to weasel out of it by changing the definition of 
reference parameter to mean "whatever I want it to mean to avoid admitting I 
was wrong"?


>> And of course Python doesn't have reference variables either. There is
>> nothing you can do in Python to get this effect:
>>
>> a = 1
>> b = a
>> b = 99
>> assert a == 99
> 
> It is true that you can't get such an effect in python, but that doesn't
> imply that python doesn't have reference variables (as an abstract notion).
> Because having reference variables doesn't imply you can have that effect.

Ah, well that answers that question. Weasel out it is.



-- 
Steve



More information about the Python-list mailing list