[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