[Tutor] who makes FOR loop quicker

Steven D'Aprano steve at pearwood.info
Thu Aug 6 16:21:01 CEST 2015


On Thu, Aug 06, 2015 at 08:57:34AM -0400, Joel Goldstick wrote:
> On Thu, Aug 6, 2015 at 4:34 AM, John Doe <z2911 at bk.ru> wrote:
> > Can You, please, elaborate this "..Passing in Python is different than in C
> > or other languages..."
> >
> I hesitate, because this question is usually the fuel of flaming wars.

Very wise :-)

But since I'm not so wise, here are some more comments.


> So in short:
> 
> C can pass a value or a reference to a value (the address of the place
> in memory where the value is stored)

You are correct that C can pass a reference to a value, namely a 
pointer. But from the perspective of the C compiler, that pointer *is* 
the value, not the thing being pointed at. So passing a pointer as 
argument is no different from passing an int or a float or a bool, it's 
just a value, and the C compiler will use pass by value on the pointer 
itself.

In C, one can use pointers to *simulate* pass by reference. But this is 
not the same thing as actual pass by reference. In pass by reference, 
you don't pass (a pointer to the variable you want), you pass (the 
variable you want), and the compiler does all the magic needed to make 
it work.

Pascal is a good example of pass by reference because it also has 
pointers, so we can demonstrate both the real thing and the simulation. 
Here is a small Pascal program that uses pass by value, a pointer 
simulating pass by reference, and actual pass by reference:


=== cut ===

program demo (input, output);

type
  intptr = ^integer;
var
  x, y, z: integer;
  w: intptr;

function sum(a: integer; b: intptr; var c: integer): integer;
  var
    total: integer;
  begin
    total := 0;
    total := total + a;
    total := total + b^;
    total := total + c;
    a := -1;
    b^ := -1;
    c := -1;
    sum := total;  {set the return value}
end;

begin
  x := 100;
  y := 100;
  z := 100;
  w := @y;   { address-of operator @ is non-standard Pascal }
  writeln(x, ' ', y, ' ', z);
  writeln(sum(x, w, z));
  writeln(x, ' ', y, ' ', z);
end.


=== cut ===

The output is:

100 100 100
300
100 -1 -1


Note that except for the declaration, inside the body of the function 
you treat c as an ordinary variable just like a, while with b you have 
to manually dereference the pointer whenever you want to access the int 
value. Since C lacks real pass by reference (var c), you have to use the 
pointer work-around (b) technique.

Also, assigning to a inside the function has no visible effect since it 
is a purely local variable; assignment to b also would have no effect, 
since b itself is a local variable, but assignment to what b points to 
(b^) is visible outside the function; and of course assignment to c is 
visible outside the function.

Pascal "var" parameters are sometimes called output parameters, since 
they can be used to pass values back out to the caller.


> Python passes an object -- everything in python is an object.  If the
> object is mutable, and the function mutates it, those results will be
> seen outside the function.  If the object is immutable, and the
> function tries to change its value, a new object is created with the
> new value.  Its name is the name given in the parameter list -- not
> the name that the function was called with.  When the function
> completes, that object is lost since the outer scoped named object
> wasn't changed.

I agree with this paragraph.


-- 
Steve


More information about the Tutor mailing list