[Tutor] who makes FOR loop quicker

Steven D'Aprano steve at pearwood.info
Thu Aug 6 15:45:12 CEST 2015


On Thu, Aug 06, 2015 at 11:34:51AM +0300, John Doe wrote:

> Can You, please, elaborate this "..Passing in Python is different than 
> in C or other languages..."

Argument passing in Python is:

- different to Perl, C, Scala, Algol and Pascal;

- the same as Ruby, Lua, Applescript and Javascript;

- the same as Java boxed values (object);

- different to Java unboxed values (machine types).


In C, all values are passed by value. When you pass an argument to a 
function, the C compiler makes a copy of that value and passes the 
value.

In Pascal, values can be passed by value (like C), or by reference. 

The simplest demonstration of pass-by-reference is to write a "swap" 
procedure. In Python terms:


# This does not actually work in Python.
def swap(a, b):
    tmp = a
    a = b
    b = tmp

x = 23
y = 42
swap(x, y)
print x, y  # prints 42 23

z = 19
swap(x, z)
print x, z  # prints 19 42


You *cannot* write a swap procedure like this in Python. The closest you 
can do is write a function that returns the two values, then assign 
them:

def swap(a, b):
    return b, a

x, y = swap(x, y)  # this works

but that is not pass by reference.

In Pascal, you can write such a swap procedure.

Scala and Algol use pass by name, and pass by value. This page explains 
pass by name in Scala, and how it differs from pass by value:

http://alvinalexander.com/source-code/scala/simple-scala-call-name-example

In Java, unboxed values (not objects, low-level machine ints and floats) 
are passed by value, like C.

Python, Ruby, Javascript, Lua, Java boxed values (objects), and many 
other languages, all use the same passing style. This has a number of 
names: 

- pass by object;
- pass by sharing;
- pass by object sharing;

Some people (especially Ruby programmers) call it "pass by reference" 
but that is wrong. Others (especially Java programmers) call it "call by 
value, where the value is a reference" which is technically correct but 
too long. Another name is "call by value/pass by reference", which is 
just confusing.

See also:

https://en.wikipedia.org/wiki/Evaluation_strategy

In pass by object sharing, the argument is evaluated but *not* copied. 
Since the argument is not copied, it is not pass-by-value. Inside the 
function, you can modify the object, and since it is not a copy, the 
original sees the changes. But *assignment* to the local variable inside 
the function does not affect the caller's variable, so it is not 
pass-by-reference.

To summarise:

Pass by value:
- Argument is copied? YES
- Assignment inside function affects original? NO
- Mutation of argument inside function affects original? NO

Pass by reference:
- Argument is copied? NO
- Assignment inside function affects original? YES
- Mutation of argument inside function affects original? YES

Pass by object sharing:
- Argument is copied? NO
- Assignment inside function affects original? NO
- Mutation of argument inside function affects original? YES



> 'Cause as far as I know - default major Python's implementation CPython 
> is written in C.

That is irrelevent. The argument passing strategy of a language is part 
of the language itself, not the implementation language.

C does not allow variables to change type. But Python does. You cannot 
do this in C:

x = 23  # x is an integer
x = "foo"  # and now it is a string

so clearly the behaviour of a programming language is not always the 
same as that of the implementation language.



-- 
Steve


More information about the Tutor mailing list