A question on modification of a list via a function invocation
Steve D'Aprano
steve+python at pearwood.info
Wed Sep 6 08:58:59 EDT 2017
On Wed, 6 Sep 2017 05:12 pm, Antoon Pardon wrote:
[...]
>> I'm not saying that we should never use this model. Its a good model. But we
>> should be clear that it is a model of the implementation, and it describes
>> entities which are not part of the Python language. We cannot do this:
>>
>>
>> +-----+
>> | |
>> | 5 |
>> | |
>> +-----+
>> ^
>> |
>> <x>
>> ^
>> |
>> <y>
>>
>>
>> or any of the other things we can do in a language with references-as-values,
>> like C or Pascal.
>
> I don't agree that the above is an accurate picture of C or Pascal.
I'm surprised. You can do this in Pascal:
type
intpointer = ^integer;
var
x: intpointer;
y: ^intpointer;
begin
new(x); {reserve memory in the heap for an integer, and point x at it}
x^ := 5;
y := @x; {y points to the pointer x}
end.
which would translate to the diagram above. If you don't like the fact that I'm
using the "address of" operator @ which is non-standard Pascal, I can write
this instead:
type
intpointer = ^integer;
var
y: ^intpointer;
begin
new(y); {reserve memory in the heap for an intpointer, and point y at it}
new(y^); {reserve memory in the heap for an integer, and point y^ at it}
y^^ := 5;
end.
I would be shocked if C were less powerful in this regard than Pascal.
> It is more
> like the following:
>
> +-----+ +-----+
> | | | |
> | 5 |<----+--* |
> | | | |
> +-----+ +-----+
> ^ ^
> | |
> <x> <y>
That would be equivalent to a different piece of code:
type
intpointer = ^integer;
var
x: intpointer;
y: ^intpointer;
begin
new(x); {reserve memory in the heap for an integer, and point x at it}
x^ := 5;
new(y); {reserve memory in the heap for an intpointer, and point y at it}
y^ := x; {assignment copies; y^ now points to the same thing as x}
end.
These two are not the same thing.
> And in case of a VAR parameter in Pascal like
>
> procedure f(VAR x);
> f(y)
>
> one could use the following, which is the same
> as after an assignment in python.
>
>
> +-----+
> | |
> | 7 |
> ---> | |
> / +-----+
> /
> / ^
> / |
> <x> <y>
No no no! Pascal VAR parameters are not the same as Python assignment! You
cannot write a Pascal swap procedure in Python!
Pascal VAR parameters are, in a sense, syntactic sugar for pointer manipulation.
(I'm not sure just how far we can take this analogy, but I think its pretty
far.) That's probably why C didn't bother with VAR parameters: anything you can
do with a VAR parameter, you can do with explicit pointers.
I think that these two increment procedures will be (more or less?) equivalent:
type
intpointer = ^integer;
procedure increment(var n: integer);
begin
n := n + 1
end;
procedure increment2(p: intpointer);
begin
p^ := p^ + 1
end;
var
a: integer;
b: integer;
begin
a := 99;
increment(a);
writeln(a); {will print 100}
b := 99;
increment2(@b);
writeln(b); {will print 100}
end.
If there's a difference, its a subtle one which I haven't found in a short
amount of testing.
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list