Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #91898 > unrolled thread

Can Python function return multiple data?

Started byfl <rxjwg98@gmail.com>
First post2015-06-02 14:27 -0700
Last post2015-06-07 15:33 +1000
Articles 20 on this page of 84 — 22 participants

Back to article view | Back to comp.lang.python


Contents

  Can Python function return multiple data? fl <rxjwg98@gmail.com> - 2015-06-02 14:27 -0700
    Re: Can Python function return multiple data? Joel Goldstick <joel.goldstick@gmail.com> - 2015-06-02 17:35 -0400
    Re: Can Python function return multiple data? sohcahtoa82@gmail.com - 2015-06-02 14:40 -0700
    Re: Can Python function return multiple data? John Gordon <gordon@panix.com> - 2015-06-02 21:40 +0000
    Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-03 09:56 +1000
      Re: Can Python function return multiple data? Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2015-06-03 15:56 +0200
        Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-04 07:35 +1000
        Re: Can Python function return multiple data? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-03 22:56 +0100
          Re: Can Python function return multiple data? sohcahtoa82@gmail.com - 2015-06-03 15:28 -0700
            Re: Can Python function return multiple data? Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-06-03 21:30 -0400
            Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-04 11:52 +1000
            Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-04 23:47 +1000
              Re: Can Python function return multiple data? Marko Rauhamaa <marko@pacujo.net> - 2015-06-04 17:25 +0300
                Re: Can Python function return multiple data? Grant Edwards <invalid@invalid.invalid> - 2015-06-04 14:37 +0000
                  Re: Can Python function return multiple data? Marko Rauhamaa <marko@pacujo.net> - 2015-06-04 18:04 +0300
                    Re: Can Python function return multiple data? Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-06-04 19:51 -0400
                  Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 03:11 +1000
                    Re: Can Python function return multiple data? Marko Rauhamaa <marko@pacujo.net> - 2015-06-04 20:30 +0300
                      Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 08:37 +1000
                    Re: Can Python function return multiple data? random832@fastmail.us - 2015-06-04 13:30 -0400
                      Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 08:31 +1000
                    Re: Can Python function return multiple data? Grant Edwards <invalid@invalid.invalid> - 2015-06-04 18:38 +0000
                      Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 08:52 +1000
                        Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-05 09:04 +1000
                        Re: Can Python function return multiple data? Grant Edwards <invalid@invalid.invalid> - 2015-06-05 02:02 +0000
                          Re: Can Python function return multiple data? Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2015-06-05 09:11 +0200
                            Re: Can Python function return multiple data? Marko Rauhamaa <marko@pacujo.net> - 2015-06-05 12:27 +0300
                              Re: Can Python function return multiple data? Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2015-06-05 14:04 +0200
                    Re: Can Python function return multiple data? BartC <bc@freeuk.com> - 2015-06-04 21:52 +0100
                      Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 09:13 +1000
                        Re: Can Python function return multiple data? BartC <bc@freeuk.com> - 2015-06-05 01:16 +0100
                          Re: Can Python function return multiple data? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-05 02:40 +0100
                            Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 11:48 +1000
                              Re: Can Python function return multiple data? BartC <bc@freeuk.com> - 2015-06-05 11:06 +0100
                    Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-05 07:44 +1000
                  Re: Can Python function return multiple data? BartC <bc@freeuk.com> - 2015-06-05 10:51 +0100
              Re: Can Python function return multiple data? ElChino <elchino@cnn.cn> - 2015-06-04 17:37 +0200
                Re: Can Python function return multiple data? Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-06-04 19:57 -0400
              Re: Can Python function return multiple data? random832@fastmail.us - 2015-06-04 13:26 -0400
                Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 08:16 +1000
                  Re: Can Python function return multiple data? random832@fastmail.us - 2015-06-04 18:59 -0400
                    Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 12:37 +1000
                      Re: Can Python function return multiple data? Rustom Mody <rustompmody@gmail.com> - 2015-06-04 20:16 -0700
                        Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 21:06 +1000
                          Re: Can Python function return multiple data? Rustom Mody <rustompmody@gmail.com> - 2015-06-05 06:29 -0700
                            Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-06 07:59 +1000
                              Re: Can Python function return multiple data? Rustom Mody <rustompmody@gmail.com> - 2015-06-05 20:20 -0700
                                Re: Can Python function return multiple data? random832@fastmail.us - 2015-06-05 23:28 -0400
                                  Re: Can Python function return multiple data? Rustom Mody <rustompmody@gmail.com> - 2015-06-05 22:28 -0700
                                    Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-06 15:43 +1000
                                      Lawful != Mutable (was Can Python function return multiple data?) Rustom Mody <rustompmody@gmail.com> - 2015-06-07 08:49 -0700
                                        Re: Lawful != Mutable (was Can Python function return multiple data?) Chris Angelico <rosuav@gmail.com> - 2015-06-08 02:07 +1000
                                        Re: Lawful != Mutable (was Can Python function return multiple data?) Rustom Mody <rustompmody@gmail.com> - 2015-06-07 09:20 -0700
                                          Re: Lawful != Mutable (was Can Python function return multiple data?) Chris Angelico <rosuav@gmail.com> - 2015-06-08 02:34 +1000
                                            Re: Lawful != Mutable (was Can Python function return multiple data?) Rustom Mody <rustompmody@gmail.com> - 2015-06-20 18:59 -0700
                                              Re: Lawful != Mutable (was Can Python function return multiple data?) Chris Angelico <rosuav@gmail.com> - 2015-06-21 12:32 +1000
                                                Re: Lawful != Mutable (was Can Python function return multiple data?) Rustom Mody <rustompmody@gmail.com> - 2015-06-20 19:50 -0700
                                                  Re: Lawful != Mutable (was Can Python function return multiple data?) Laura Creighton <lac@openend.se> - 2015-06-21 11:14 +0200
                                                  Re: Lawful != Mutable (was Can Python function return multiple data?) Ron Adam <ron3200@gmail.com> - 2015-06-21 08:55 -0400
                                    Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-07 15:51 +1000
                                Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-06 13:49 +1000
                                Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-06 14:50 +1000
                                  Re: Can Python function return multiple data? Chris Angelico <rosuav@gmail.com> - 2015-06-06 15:29 +1000
                                  Re: Can Python function return multiple data? Rustom Mody <rustompmody@gmail.com> - 2015-06-05 22:32 -0700
                                    Re: Can Python function return multiple data? Dave Farrance <df@see.replyto.invalid> - 2015-06-06 07:52 +0100
                                    Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-07 15:53 +1000
                      Re: Can Python function return multiple data? random832@fastmail.us - 2015-06-05 08:21 -0400
                        Re: Can Python function return multiple data? Marko Rauhamaa <marko@pacujo.net> - 2015-06-05 16:37 +0300
                  Re: Can Python function return multiple data? Rustom Mody <rustompmody@gmail.com> - 2015-06-04 19:07 -0700
              Re: Can Python function return multiple data? Michael Torrie <torriem@gmail.com> - 2015-06-04 11:36 -0600
              Re: Can Python function return multiple data? random832@fastmail.us - 2015-06-04 13:51 -0400
              Re: Can Python function return multiple data? Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2015-06-04 20:17 +0200
                Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-05 08:45 +1000
                  Re: Can Python function return multiple data? Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2015-06-05 08:59 +0200
            Re: Can Python function return multiple data? Michael Torrie <torriem@gmail.com> - 2015-06-04 08:16 -0600
          Re: Can Python function return multiple data? sohcahtoa82@gmail.com - 2015-06-05 11:55 -0700
        Re: Can Python function return multiple data? random832@fastmail.us - 2015-06-04 01:01 -0400
        Re: Can Python function return multiple data? Ian Kelly <ian.g.kelly@gmail.com> - 2015-06-04 12:34 -0600
        Re: Can Python function return multiple data? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-04 20:16 +0100
    Re: Can Python function return multiple data? Serhiy Storchaka <storchaka@gmail.com> - 2015-06-04 09:56 +0300
    Re: Can Python function return multiple data? fl <rxjwg98@gmail.com> - 2015-06-06 10:57 -0700
      Re: Can Python function return multiple data? Rustom Mody <rustompmody@gmail.com> - 2015-06-06 21:35 -0700
      Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-07 15:47 +1000
    Re: Can Python function return multiple data? Steven D'Aprano <steve@pearwood.info> - 2015-06-07 15:33 +1000

Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →


#92095

FromSteven D'Aprano <steve@pearwood.info>
Date2015-06-05 08:31 +1000
Message-ID<5570d1ce$0$12999$c3e8da3$5496439d@news.astraweb.com>
In reply to#92075
On Fri, 5 Jun 2015 03:30 am, random832@fastmail.us wrote:

> On Thu, Jun 4, 2015, at 13:11, Steven D'Aprano wrote:
>> You need at least one more test to prove pass by value: you need to
>> demonstrate that the value bound to y is copied when passed to the
>> function. E.g. pass a mutable value (say, a list) and mutate it inside
>> the
>> function. If the list in the outer scope is *not* mutated, then and only
>> then can you say it is pass by value.
> 
> That's not true at all. Being able to mutate the object doesn't make it
> not-pass-by-value any more than being able to use an int argument as an 
> index to mutate a global array makes the int not-pass-by-value.
> 
> a = [0]*16
> 
> def f(x, i):
>     x[i] = 3
> 
> f(a, 0)
> 
> If x is not pass-by-value, then clearly i is also not pass-by-value,
> despite integers being immutable. 

Neither are pass by value, and the results of running that code are
consistent with that fact. Nothing in the above code snippet shows pass by
value behaviour: neither the list a nor the literal 0 is copied. We know
that the list is not copied because the mutation operation inside the
function shows up on the outside (it affects the list bound to a). Nothing
in your code demonstrates that 0 is not copied, but this code snippet does:

x = 0  # or use any value you like
print(id(x))

def test(arg):
    print(id(arg))


test(x)



> Being able to use an argument to cause 
> a side effect does not mean the argument has not been passed by value.

Of course it does. The lack of side-effects is the defining characteristic
of pass by value: since the argument is copied, any direct mutations you
apply to it cannot affect the original.


> a hasn't changed,

Yes it has. It was [0,0,0,...0] and now it is [3,0,0,...0]. That's a
mutation to the value, and it is visible in the outer scope. Hence, a has
not been copied, which means it wasn't passed by value.


> 0 hasn't changed, the only thing that has changed is 
> the list object, which is *not the same thing as a*.

This is an interesting (and sometimes useful) distinction you are making,
between the value of a variable and the variable itself, but it is not
relevant to the discussion of pass by value.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#92085

FromGrant Edwards <invalid@invalid.invalid>
Date2015-06-04 18:38 +0000
Message-ID<mkq5ur$cj6$1@reader1.panix.com>
In reply to#92068
On 2015-06-04, Steven D'Aprano <steve@pearwood.info> wrote:
> On Fri, 5 Jun 2015 12:37 am, Grant Edwards wrote:
>> On 2015-06-04, Marko Rauhamaa <marko@pacujo.net> wrote:
>
>>> Anyway, I would say Python definitely is in the classic pass-by-value
>>> camp. Here's a simple test:
>>>
>>>    def f(x):
>>>        x = 3
>>>
>>>    y = 1
>>>    f(y)
>>>    print(y)
>>>
>>> If it prints 1, it's pass by value. If it prints 3, it's pass by
>>> reference.
>
> Wrong.

>> Somebody else might just as honestly say that it's pass by reference:
>
> And they would be just as wrong.

Yep, that was my point.  They're both wrong and yet people can be just
as honest when they argue one or the other.

>> def f(x):
>>     x[2] = 2;
>> 
>> x = ['a','b','c']
>> f(x)
>> print(x)
>> 
>> If it prints ['a','b','c'], it's pass by value.  If it's pass by
>> reference, it prints ['a', 'b', 2].
>
> Wrong.

I know.

>> But, discussing pass-by-this vs. pass-by-that without also discussing
>> the semantics of the assignment operator is rather pointless.
>
> No, that's a red-herring.

I don't think so.  The reason that many people seem to confused about
Python's argument passing is that they don't understand what
assignment does.

-- 
Grant Edwards               grant.b.edwards        Yow! Are we live or on
                                  at               tape?
                              gmail.com            

[toc] | [prev] | [next] | [standalone]


#92098

FromSteven D'Aprano <steve@pearwood.info>
Date2015-06-05 08:52 +1000
Message-ID<5570d6b3$0$12993$c3e8da3$5496439d@news.astraweb.com>
In reply to#92085
On Fri, 5 Jun 2015 04:38 am, Grant Edwards wrote:

>>> But, discussing pass-by-this vs. pass-by-that without also discussing
>>> the semantics of the assignment operator is rather pointless.
>>
>> No, that's a red-herring.
> 
> I don't think so.  The reason that many people seem to confused about
> Python's argument passing is that they don't understand what
> assignment does.


I don't see the connection, but do explain, I'm interested.




-- 
Steven

[toc] | [prev] | [next] | [standalone]


#92101

FromChris Angelico <rosuav@gmail.com>
Date2015-06-05 09:04 +1000
Message-ID<mailman.182.1433459100.13271.python-list@python.org>
In reply to#92098
On Fri, Jun 5, 2015 at 8:52 AM, Steven D'Aprano <steve@pearwood.info> wrote:
> On Fri, 5 Jun 2015 04:38 am, Grant Edwards wrote:
>
>>>> But, discussing pass-by-this vs. pass-by-that without also discussing
>>>> the semantics of the assignment operator is rather pointless.
>>>
>>> No, that's a red-herring.
>>
>> I don't think so.  The reason that many people seem to confused about
>> Python's argument passing is that they don't understand what
>> assignment does.
>
>
> I don't see the connection, but do explain, I'm interested.

The connection is that argument passing is, in Python and in many
other languages, a form of assignment, and follows all the same rules
as assignment follows. (It's a kind of magic assignment that spans two
namespaces, but that has nothing to do with pass-by-X questions.)
These two will exhibit the same behaviour:

# Option 1
x = some_object()
y = x
... do something with y ...
... compare y and x

# Option 2
def do_stuff(y):
    ... do something with y ...

x = some_object()
do_stuff(x)
... compare y and x


Python's object semantics go far deeper than just argument passing,
but everyone's confusions about pass-by-X are always about function
calls.

Whether this makes a real difference to anything is a separate question.

ChrisA

[toc] | [prev] | [next] | [standalone]


#92114

FromGrant Edwards <invalid@invalid.invalid>
Date2015-06-05 02:02 +0000
Message-ID<mkqvv1$779$1@reader1.panix.com>
In reply to#92098
On 2015-06-04, Steven D'Aprano <steve@pearwood.info> wrote:
> On Fri, 5 Jun 2015 04:38 am, Grant Edwards wrote:
>
>>>> But, discussing pass-by-this vs. pass-by-that without also discussing
>>>> the semantics of the assignment operator is rather pointless.
>>>
>>> No, that's a red-herring.
>> 
>> I don't think so. ??The reason that many people seem to confused
>> about Python's argument passing is that they don't understand what
>> assignment does.
>
> I don't see the connection, but do explain, I'm interested.

To many people the difference between pass-by-value and
pass-by-reference is what the effects are of assigning to the formal
parameter from within the function.  Using the model of "assignment"
they're used to using from FORTAN/C/C++ Python appears to behave
weirdly and inconsistently.

But, it's not really because the parameter passing mechnism is
something novel (it's not). It's because of what assignment does.
Python's parameter passing is quite simple: it's exactly the same as
an assignment: it binds a name within the funciton's namespacepace to
an object.  If you don't first understand that's what an assignment
does, then trying to explain the parameter passing using phrases
spelled 'pass-by-<whatever>' isn't going to help.

At least that's how it works in my head.  First, you have to
understand assignment.  Then you can understand what Python parameter
passing does.

Or to be a bit obtuse: Python parameters are passed by value, but all
values are references.

[I once had a CS prof who didn't know there was anything other than
pass-by-reference, but that's another story.]

--
Grant

[toc] | [prev] | [next] | [standalone]


#92126

FromAlain Ketterlin <alain@universite-de-strasbourg.fr.invalid>
Date2015-06-05 09:11 +0200
Message-ID<87iob2k4t3.fsf@universite-de-strasbourg.fr.invalid>
In reply to#92114
Grant Edwards <invalid@invalid.invalid> writes:

[...]
> Or to be a bit obtuse: Python parameters are passed by value, but all
> values are references.

Exactly, that's a perfect description. There's is no need for a new
name. As a corollary, all names (including "variables" and object
attributes) are references.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#92130

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-06-05 12:27 +0300
Message-ID<87y4jy4i90.fsf@elektro.pacujo.net>
In reply to#92126
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>:

> Grant Edwards <invalid@invalid.invalid> writes:
>
> [...]
>> Or to be a bit obtuse: Python parameters are passed by value, but all
>> values are references.
>
> Exactly, that's a perfect description. There's is no need for a new
> name. As a corollary, all names (including "variables" and object
> attributes) are references.

We are all confusing each other because of the word "reference" means so
many things.

In Grant's explanation, a "reference" is a pointer, the invisible gluons
that bind, say, a variable to an object.

In Alain's sentence a "reference" is a variable or any other "lvalue"
that can be bound to an object.

Thus, the statement

    a[3] = 4

contains the reference[Alain] "a[3]". After the statement is executed,
the reference[Alain] contains a reference[Grant] to an int object 4.

Now, is it useful to make the distinction and use the verb "contain?"

Yes, it is. Consider these statements:

    a[0] = 4
    a[1] = 4
    a[2] = a[1]

Now, "a[0]", "a[1]" and "a[2]" are three separate references[Alain].
However between the three, they contain a maximum of two distinct
references[Grant], which can be ascertained with an "is" test:

    a[2] is a[1]
    => True

So while the references[Grant] are identical, the references[Alain] are
not. If I'm not mistaken, Python has no means of comparing the
identities of references[Alain].


Marko

[toc] | [prev] | [next] | [standalone]


#92135

FromAlain Ketterlin <alain@universite-de-strasbourg.fr.invalid>
Date2015-06-05 14:04 +0200
Message-ID<87eglqjr9m.fsf@universite-de-strasbourg.fr.invalid>
In reply to#92130
Marko Rauhamaa <marko@pacujo.net> writes:

> Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>:
>
>> Grant Edwards <invalid@invalid.invalid> writes:
>>
>> [...]
>>> Or to be a bit obtuse: Python parameters are passed by value, but all
>>> values are references.
>>
>> Exactly, that's a perfect description. There's is no need for a new
>> name. As a corollary, all names (including "variables" and object
>> attributes) are references.
>
> We are all confusing each other because of the word "reference" means so
> many things.
>
> In Grant's explanation, a "reference" is a pointer, the invisible gluons
> that bind, say, a variable to an object.
>
> In Alain's sentence a "reference" is a variable or any other "lvalue"
> that can be bound to an object.
>
> Thus, the statement
>
>     a[3] = 4
>
> contains the reference[Alain] "a[3]". After the statement is executed,
> the reference[Alain] contains a reference[Grant] to an int object 4.

You're right, my wording is imprecise, your interpretation is absolutely
correct.

> Now, is it useful to make the distinction and use the verb "contain?"
>
> Yes, it is. Consider these statements:
>
>     a[0] = 4
>     a[1] = 4
>     a[2] = a[1]
>
> Now, "a[0]", "a[1]" and "a[2]" are three separate references[Alain].
> However between the three, they contain a maximum of two distinct
> references[Grant], which can be ascertained with an "is" test:
>
>     a[2] is a[1]
>     => True
>
> So while the references[Grant] are identical, the references[Alain] are
> not. If I'm not mistaken, Python has no means of comparing the
> identities of references[Alain].

Right.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#92091

FromBartC <bc@freeuk.com>
Date2015-06-04 21:52 +0100
Message-ID<wU2cx.757611$I81.286196@fx33.am4>
In reply to#92068
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.

Assignments involve a deep copy. Argument passing is something 
in-between by-value and by-reference (depending also on the type of data 
involved). There is a also an actual by-reference mode (where a pointer 
is passed).


-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#92103

FromSteven D'Aprano <steve@pearwood.info>
Date2015-06-05 09:13 +1000
Message-ID<5570dbaa$0$12995$c3e8da3$5496439d@news.astraweb.com>
In reply to#92091
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, 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?


> 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.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#92110

FromBartC <bc@freeuk.com>
Date2015-06-05 01:16 +0100
Message-ID<uT5cx.584043$oZ4.56869@fx38.am4>
In reply to#92103
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

[toc] | [prev] | [next] | [standalone]


#92112

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-06-05 02:40 +0100
Message-ID<mailman.188.1433468465.13271.python-list@python.org>
In reply to#92110
On 05/06/2015 01:16, BartC wrote:
> 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!)
>

Really?

 >>> x=[1,2,3]
 >>> tmp=x
 >>> def func(thing):
...     thing.clear()
...
 >>> func(tmp)
 >>> tmp
[]
 >>> x
[]

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

[toc] | [prev] | [next] | [standalone]


#92113

FromSteven D'Aprano <steve@pearwood.info>
Date2015-06-05 11:48 +1000
Message-ID<5570fff7$0$12992$c3e8da3$5496439d@news.astraweb.com>
In reply to#92112
On Fri, 5 Jun 2015 11:40 am, Mark Lawrence wrote:

> On 05/06/2015 01:16, BartC wrote:
>> 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.

[...] 

> Really?

Probably. I can't be sure, because I've never used Bart's language. But
surely he has no reason to lie about his language, and I'm pretty sure you
can't disprove any claims about his language by running Python code.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#92132

FromBartC <bc@freeuk.com>
Date2015-06-05 11:06 +0100
Message-ID<%wecx.985112$wk1.522127@fx19.am4>
In reply to#92113
On 05/06/2015 02:48, Steven D'Aprano wrote:
> On Fri, 5 Jun 2015 11:40 am, Mark Lawrence wrote:
>
>> On 05/06/2015 01:16, BartC wrote:
>>> 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.
>
> [...]
>
>> Really?
>
> Probably. I can't be sure, because I've never used Bart's language. But
> surely he has no reason to lie about his language, and I'm pretty sure you
> can't disprove any claims about his language by running Python code.

Well, my language does assignments differently.

Using tmp=x[:], the Python example will emulate the behaviour better.

(This is actually what I've always had trouble getting my head around. 
For example:

x=[10,20]
y=[x,x,x]
print (y)

gives:

   [[10,20],[10,20],[10,20]]

So far so good. But now, thousands of lines and minutes of runtime later 
so that everyone's forgotten that exactly y was from x:

  x[0]="Cat"
  print (y)

gives:

    [['Cat',20],['Cat',20],['Cat',20]]

WTF?!

Or:

   y[0][0]=99      # change one element, you think
   print (y)

=> [[99,20],[99,20],[99,20]]      # no, you change half of them!

Anyway, I am now upgrading my language to work the same way, *and* 
getting rid of explicit pointers, references and full pass-by-reference, 
because Python seems to manage without them. I'll find out in few weeks 
if I've made a big mistake!)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#92092

FromChris Angelico <rosuav@gmail.com>
Date2015-06-05 07:44 +1000
Message-ID<mailman.178.1433454275.13271.python-list@python.org>
In reply to#92068
On Fri, Jun 5, 2015 at 3:11 AM, Steven D'Aprano <steve@pearwood.info> wrote:
> You need at least one more test to prove pass by value: you need to
> demonstrate that the value bound to y is copied when passed to the
> function. E.g. pass a mutable value (say, a list) and mutate it inside the
> function. If the list in the outer scope is *not* mutated, then and only
> then can you say it is pass by value.

Minor quibble: This discussion is about semantics, not timing. A
language can use pass-by-value but with optimizations for the
read-only case.

$ cat array_argument.php
<?php
function readonly($arr) {if ($arr[1] != 1) echo "WRONG!\n";}
function readwrite($arr) {$arr[1] = 1;}

$array = array();
//Populate a big array
for ($i=0; $i<1000; ++$i) $array[$i] = $i;

//Now pass it repeatedly as an argument
$start = microtime(1);
for ($i=0; $i<100000000; ++$i) readonly($array);
$i/=1000000;
$t = (microtime(1)-$start);
echo "Read-only: $i million iterations in $t seconds\n";

$start = microtime(1);
for ($i=0; $i<100000; ++$i) readwrite($array);
$i/=1000;
$t = (microtime(1)-$start);
echo "Read-write: $i thousand iterations in $t seconds\n";

$ time php array_argument.php
Read-only: 100 million iterations in 11.251608133316 seconds
Read-write: 100 thousand iterations in 2.6384630203247 seconds

real 0m13.914s
user 0m13.780s
sys 0m0.000s


PHP passes arrays by value, but optimizes away the copy in the
read-only case - which means that array mutations can trigger
unexpected copying. But it's still pass-by-value, even though you can
appear to have the performance of pass-by-object/pass-by-reference.
Conceivably, a language might implement pass-by-value by having a
"shadow" that knows that it's "the same as that array only this one
got changed", although I can't imagine it'd be efficient for
real-world work. It'd still be legitimate pass-by-value though.

ChrisA

[toc] | [prev] | [next] | [standalone]


#92131

FromBartC <bc@freeuk.com>
Date2015-06-05 10:51 +0100
Message-ID<aiecx.889996$3i4.397133@fx29.am4>
In reply to#92062
On 04/06/2015 15:37, Grant Edwards wrote:
> On 2015-06-04, Marko Rauhamaa <marko@pacujo.net> wrote:
>> Steven D'Aprano <steve@pearwood.info>:
>>
>>> But you still find a few people here and there who have been exposed
>>> to Java foolishness, and will argue that Python is "pass by value,
>>> where the value is an implementation dependent reference to the thing
>>> that you thought was the value".
>>
>> Why fight terminology? Definitions can't be proved right or wrong.
>>
>> Anyway, I would say Python definitely is in the classic pass-by-value
>> camp. Here's a simple test:
>>
>>     def f(x):
>>         x = 3
>>
>>     y = 1
>>     f(y)
>>     print(y)
>>
>> If it prints 1, it's pass by value. If it prints 3, it's pass by
>> reference.
>
> Somebody else might just as honestly say that it's pass by reference:
>
> def f(x):
>      x[2] = 2;
>
> x = ['a','b','c']
> f(x)
> print(x)
>
> If it prints ['a','b','c'], it's pass by value.  If it's pass by
> reference, it prints ['a', 'b', 2].
>
> IMO, it's pass by reference.

No, it's not. Pass-by-reference specifically means (as Steven D'Aprano 
pointed out some weeks back in another thread) that you can directly 
change the caller's 'variable' so that it becomes something else, such 
as a string.

In your example, the caller's x is still a list. And the same list 
(assign it to y before the call. y will be ['a','b','2'] too, and (x is 
y) is True).

To modify, mutate or in any way update the data associated with the 
caller's argument, pass-by-reference is not needed. But it's not exactly 
pass-by-value either.

In a language like Python, such a limited choice would be too naive, 
because pointers and references are also used internally and 
transparently, and they help to confuse matters.

If you want to call it something, perhaps call it call-by-handle. 
Because a handle to the data is being passed. In the same way that if X 
is a handle to a file, a window, image, or any external resource, then:

   func(X)

might update the file, draw into the window or image or whatever, but 
no-one would be talking about whether that file or window is passed by 
value or by reference!

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#92064

FromElChino <elchino@cnn.cn>
Date2015-06-04 17:37 +0200
Message-ID<mkpr8v$1tp$2@dont-email.me>
In reply to#92052
Steven D'Aprano wrote:

 > But you still find a few people here and there who have been exposed to Java
> foolishness, and will argue that Python is "pass by value, where the value
> is an implementation dependent reference to the thing that you thought was
> the value".

To quote Niklaus Wirth (the father of Pascal, Modula-2 etc.),
"You may call me by name. But you may also call me by reference".

[toc] | [prev] | [next] | [standalone]


#92109

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2015-06-04 19:57 -0400
Message-ID<mailman.186.1433462356.13271.python-list@python.org>
In reply to#92064
On Thu, 04 Jun 2015 17:37:20 +0200, ElChino <elchino@cnn.cn> declaimed the
following:

>Steven D'Aprano wrote:
>
> > But you still find a few people here and there who have been exposed to Java
>> foolishness, and will argue that Python is "pass by value, where the value
>> is an implementation dependent reference to the thing that you thought was
>> the value".
>
>To quote Niklaus Wirth (the father of Pascal, Modula-2 etc.),
>"You may call me by name. But you may also call me by reference".
>
	As I recall, the proper form of that quotation is "You can call me by
name, or you may call me by value"...

	Playing on the common mistake in England and the US... "Wirth" is
correctly pronounced with a leading "V" (and likely with a silent "h") --
"virt" (the "name") ... But many tend to pronounce it as "worth" (the
"value")
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#92073

Fromrandom832@fastmail.us
Date2015-06-04 13:26 -0400
Message-ID<mailman.168.1433438784.13271.python-list@python.org>
In reply to#92052
On Thu, Jun 4, 2015, at 09:47, Steven D'Aprano wrote:
> In other words, according to this Java philosophy, following `x = 23`,
> the
> value of x is not 23 like any sane person would expect, but some
> invisible
> and unknown, and unknowable, reference to 23.

Well, no, because, in Java, if the type of x is int, then the value
really is 23. If it's Integer, then it's a reference to a boxed Integer
object. Which is (thankfully) immutable. But isn't invisible, unknown,
or unknowable at all.

Of course, in CPython, the type of an object reference is PyObject *.
Which isn't invisible, unknown, or unknowable, either.

If the value really were 23, the "is vs ==" problem wouldn't exist.

x = 500
y = x+1
z = y-1

x and z (probably) point to two different objects.

[toc] | [prev] | [next] | [standalone]


#92094

FromSteven D'Aprano <steve@pearwood.info>
Date2015-06-05 08:16 +1000
Message-ID<5570ce43$0$12991$c3e8da3$5496439d@news.astraweb.com>
In reply to#92073
On Fri, 5 Jun 2015 03:26 am, random832@fastmail.us wrote:

> On Thu, Jun 4, 2015, at 09:47, Steven D'Aprano wrote:
>> In other words, according to this Java philosophy, following `x = 23`,
>> the
>> value of x is not 23 like any sane person would expect, but some
>> invisible
>> and unknown, and unknowable, reference to 23.
> 
> Well, no, because, in Java, if the type of x is int, then the value
> really is 23. If it's Integer, then it's a reference to a boxed Integer
> object. Which is (thankfully) immutable. But isn't invisible, unknown,
> or unknowable at all.

I was talking about Python, hence the use of Python syntax <wink>

In Java, primitive types are passed by value, but objects are not, and to
the best of my knowledge, what I say below about Python also applies to
Java objects.


> Of course, in CPython, the type of an object reference is PyObject *.
> Which isn't invisible, unknown, or unknowable, either.

Well, I just tried to see that reference, so I would know what it is:

py> PyObject
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'PyObject' is not defined

Well, let me try another way:

py> x = 23
py> reference(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'reference' is not defined

Maybe it's a method?

py> x.getreference()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'getreference'

I tried another ~hundred~ ~dozen~ few possibilities, and they all failed
just as above. It seems that there is no way to see that object reference
from Python code, or know what it is. Hence, it is invisible, unknown and
unknowable.

What is visible and known is the *object itself*.

You have made the same mistake as the Java people: caring more about the
underlying implementation details rather than what's going on at the level
of Python code.


> If the value really were 23, the "is vs ==" problem wouldn't exist.

What "problem"? "is versus ==" is not a problem, it is a feature. The two
operators do two different things.

But I am *astonished* that you think that the value of x after x = 23 is not
23. If it's not 23, then what is it?

(Actually, I'm not that astonished. There are some kinds of foolishness that
only really smart people can fall for.)

Remember, you've tried to claim that it is not invisible or unknown, so you
must be able to see and know that value. So what is the value?


> x = 500
> y = x+1
> z = y-1
> 
> x and z (probably) point to two different objects.

Maybe they do, maybe they don't. That's not specified by the Python
language, and is an implementation detail. Other languages may make other
promises. Either way, that's irrelevant to the question at hand.




-- 
Steven

[toc] | [prev] | [next] | [standalone]


Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →

Back to top | Article view | comp.lang.python


csiph-web