On 05/06/2015 00:13, Steven D'Aprano wrote:
On Fri, 5 Jun 2015 06:52 am, BartC wrote:
On 04/06/2015 18:11, Steven D'Aprano wrote:
If there is
any language where assignment uses one style and argument passing always
uses another, I've never come across it.
My language does that. I'd be very surprised if it was the only one in
existence that does so.
I would be. That means that
func(x)
and
tmp = x
func(tmp)
behave differently,
Not as far as func() is concerned. But overall there is a difference
because now tmp contains a copy of x. (Also, if x contains a list for
example, func() can modify the copy in tmp, not in x. But this shouldn't
be surprised because the code is different!)
and that would be very surprising to me (and, I think,
most people).
Assignments involve a deep copy. Argument passing is something
in-between by-value and by-reference (depending also on the type of data
involved).
When you say "something in-between ...", do you mean pass by sharing?
No, it's a rather untidy mechanism which is not intended to be used when
a parameter is modified (mutated), because the information passed is
incomplete. But for read-access, or local assignment is used within the
function, it works as expected.
There is a also an actual by-reference mode (where a pointer
is passed).
Passing a pointer is not necessarily by reference. Pass by sharing also uses
a pointer.
This can get tricky to explain. If variables (if you forgive me that
term) are implemented actually as pointers, then when you pass that
variable to a function, a copy of the pointer it contains is pushed (I
think this is how CPython works).
In that case, it is not passed by reference, even though a pointer is
used. Because the pointer doesn't point /at/ the variable, but with it.
So if the variable contains a List, its pointer points to the list, and
the function parameter points at the same list; it can change the list,
but it can't make the variable point to something else.
When I use pass-by-reference then, regardless of whether variables
already make use of pointers, I need to construct an extra pointer that
points /at/ the variable (and box it in my case).
(Example of how I think CPython works:
def fn():
a = 5622
b = [10,20,30]
For this purpose, a and b are locals, and they are allocated on some
sort of stack, which gives them one pointer each. After those
assignments, they might contain:
a (pointer 1003) -> 1003: [int 5622 ....]
b (pointer 1007) -> 1007: [list ........]
Now the following is executed:
fn2(a)
A copy of a, (pointer 1003), is pushed, which points to the int. These
are immutable anyway. It is impossible (AFAIK) to make a contain
something else, such as a string, from outside fn().
The language could be extended:
x = &a
x might now be:
x (pointer 1012) -> 1012: [Ref (pointer 1003)]
Now it is possible to call fn2(x), and inside fn2, some dereferencing is
done (using explicit pointer ops, C-style):
*x = "XYZ" # this will change a)
--
Bartc
--
https://mail.python.org/mailman/listinfo/python-list