Re: A question on modification of a list via a function invocation

2017-09-08 Thread Steve D'Aprano
On Sat, 9 Sep 2017 10:34 am, Gregory Ewing wrote:

> Steve D'Aprano wrote:
>> The paradox of the axe is one illustration of the difficulty in defining "the
>> same" in full generality.
> 
> The axe situation doesn't arise in Python, because "same
> object" in Python is a concept that only applies to objects
> existing at the same time.

Indeed. That's why in an earlier post I mentioned that it wasn't relevant to the
question of `is`. I only mentioned it again because Rustom claimed to not
understand why I mentioned it. I mentioned it because I was *agreeing with him*
about the notion of sameness being hard to define vigorously in FULL
GENERALITY.

Which is irrelevant to the question of "same object". Either the paradoxes
of "sameness" don't apply to Python objects, in which the paradoxes don't
matter, or they apply to everything, in which case we're stuck with them and
shouldn't let them prevent us using the common sense meaning of "same object"
when discussing Python `is`.


> There's no way to even ask a question like "does a refer
> to the same object that b did a second ago", because
> the only way to test object identity is to use the
> 'is' operator, which takes two expressions evaluated
> at the same time.

I wouldn't quite go that far. We could, for example, record the ID, type, and
some representation of the object (repr? str?), and compare them to those of
the existing object. If any of them differ, then we know they aren't (weren't?)
the same object. If all three are the same, we cannot draw any conclusions.


"Is this list I have now identical to the tuple I had five minutes ago?"

"Obviously not, because lists aren't tuples."

But apart from tricks like that, I agree: objects that existed in the past but
no longer exist don't have a meaningful identity in Python.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-08 Thread Pavol Lisy
On 9/8/17, Gregory Ewing  wrote:
> Steve D'Aprano wrote:
>> A harder question is, what if you take a random number from the Integers?
>> How
>> many digits will it have in (say) base 10? I don't have a good answer to
>> that.
>> I think it may be ill-defined.
>
> I think the answer is that on average it has infinitely many
> digits -- despite every actual integer only having finitely
> many digits!
>
> We can prove this by contradiction. Suppose the answer were
> some finite number N. There are only finitely many integers
> with N or fewer digits, but there are infinitely many with
> more than N digits, so including them in the average must
> make it bigger than N. So N cannot be finite.

Sorry that my english is so poor that I could only draft ideas. :/

I think that it probably depends on distribution.

Think something like:

def numbers(e=0.999):
''' random numbers from integers '''
while 1:
r = random.random()
yield int(1/(1-r)**e)

and see:
https://www.wolframalpha.com/input/?i=area+between+y+%3D+1%2Fx%5E0.999+and+y+%3D+0+between+x+%3D+0+and+1

and unbounded (for e==1) ->
https://www.wolframalpha.com/input/?i=area+between+y+%3D+1%2Fx+and+y+%3D+0+between+x+%3D+0+and+1

# if somebody likes to test hipothesis ->
def avg(N=1000):
return sum(itertools.islice(numbers(), 0,N,1))/N
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-08 Thread Steve D'Aprano
On Fri, 8 Sep 2017 01:01 pm, Rustom Mody wrote:

> On Friday, September 8, 2017 at 7:39:38 AM UTC+5:30, Steve D'Aprano wrote:


>> Rustom, I've already given you the definitive answer to your question about
>> how to define `is` without talking about memory. You haven't replied or
>> acknowledged it, so here is it again:
>> 
>> `is` compares the two operands for identity.
> 
> Preamble… so far so good
> 
>> If the two operands are the same
>> object, `is` returns True, if they are distinct objects, `is` returns False.
> 
> restated
> a is b iff a is b

I hope you are not seriously claiming this is a circular argument.

The first half of your restatement, before the "iff", represents *Python code*,
not natural language, and needs to be quoted[1] to make sense.

If you don't quote it, you are just stating a tautology: a is b iff a is b,
which is true by definition, no matter what meaning we assign to the word "is".

But that's not what I'm saying, and you are wrong to accuse me of giving a
tautology. I'm referring to the Python expression (which is source code in a
programming language which merely looks a bit like English), and explaining it
in English terms.

The "is" in the first half is not the same as the "is" in the second, which
makes the sentence non-circular. This would be more obvious if we were having
this discussion in (say) Hindi, Latin, Swahili, or German:

`A is B` ob und nur wenn A ist B

(Or should that be "ob und nur ob"? Google Translate prefers the first, but I
have my doubts.)

If Python used a mathematical symbol instead of the word "is" as the operator,
it also would obviously be non-circular:

`A ≡ B` if and only if A is B

The mere happenstance that:

(1) Python uses the English word "is" as the operator, rather than some other
symbol like `≡` or `===` or `≣` or `.ist.`; and

(2) we happen to be writing in English, rather than (say) Japanese or Russian or
Esperanto or the Black Speech of Mordor;

does not make my argument circular. You have been lead astray by the mere
contingent fact that Python uses `is` for the operator, instead of some other
symbol.

Don't be fooled: the operator `is` is not the same as the English word "is".

But you know that, so I'm not sure why you are trying to misrepresent my
argument as circular.

So let us start repairing your restatement by adding quotation marks. I use ``
rather than "" because that's the convention used in Markdown for displaying
inline code, and I'm quoting the code:

`a is b` if and only if a is b

is not circular, but it's not very clear[2]. I intentionally avoided using the
English word "is" (not to be confused with the Python operator `is`) in my
explanation, because I knew it would confuse people and lead them astray. So
let us use a better explanation, one which is less likely to give a misleading
impression:

`a is b` if and only if the two operands are the same object

which is closer to what I actually said and avoids giving the mistaken
impression of circular reasoning.

Now if you want to argue about the definition of "same", I have already stated
my position: the commonsense or intuitive meaning of "the same thing" is
sufficient here. If you disagree, then it is up to you to demonstrate a problem
with the commonsense meaning in this context.


>> This does require that we agree on "same object", which as you point out is
>> (in its full generality) a difficult thing to define.
> 
> More than difficult, impossible in the fully abstract philosophical case

Fortunately, the fully abstract philosophical case is irrelevant here.


[...]
> E.g. in the past I've raised
>> the paradox of My Grandfather's Axe.
> 
> Dont see the relevance (here)

The paradox of the axe is one illustration of the difficulty in defining "the
same" in full generality. When objects persist through time and are subject to
change, there are questions raised about what it means to say that something is
the same when all its component bits have been replaced.

So I'm agreeing with you[2] that "the same" in its full generality is difficult
to define in a non-paradoxical way.


>> But the intuitive, common-sense notion of "same object" is, I think,
>> sufficient here. If you want to argue that it is *not* sufficient, I think
>> it's up to you to demonstrate a problem with the definition.
>> 
> 
> Its not that you cant raise philosophical problems if you want
> But when concretized to (basic) math, there are no disputes
> so the argument becomes obtuseness to no point

I'm afraid I have no idea what you think you are saying here.


> In the case of python data model every single interminable thread like this
> one, obviously started by a noob asking something genuinely and indicating
> a real confusion disproves your claim to obvious intuition and common sense

The Original Poster wasn't confused by "sameness". The OP was confusing by
scoping and mutation.

You have to go back to 15 August to find the beginning of the thread, but the OP
was 

Re: A question on modification of a list via a function invocation

2017-09-08 Thread Steve D'Aprano
On Fri, 8 Sep 2017 08:20 pm, Ben Bacarisse wrote:

> Steve D'Aprano  writes:
> 
>> On Fri, 8 Sep 2017 12:28 am, Chris Angelico wrote:
>>
>>> languages without mutable objects don't
>>> really care whether they're pass-by-X or pass-by-Y.
>>
>> Only if you don't care about efficiency.
>>
>> Believe me, the first time you pass a five gigabyte array to a function using
>> pass-by-value, on a machine with only six gigabytes of memory, you'll care.
> 
> I think your general idea to separate language semantics from
> implementation details is a good one, but you've dropped it here.  A
> language with call-by-value semantics need not copy large objects when
> passing them to a function.  The program must behave *as if* there is a
> copy but there need not actually be one.

You're right: I didn't think of the case where a language simulates
pass-by-value semantics without actually copying. I was thinking only of actual
pass-by-value implementations.

Why would any compiler for a language with immutable arrays actually copy them
when passing them to a function? *shrug* Call it a quality of implementation
issue. Lots of compilers have sub-optimal implementations.

One counter-example might be to implement copy-on-write, in which case the
copying can be delayed until the array is written to. (Although Chris did
specify languages with immutable data structures, so that's out.)

But the larger point that I'm making is that we're not actually doing
computation in some abstract, Platonic space of pure mathematics, we're using
real computers that have to shunt actual electrons through wires and
semiconductors at high speed to do anything. Computation has real costs. We can
try to ignore them, but they exist. And even absent mutation, the way you pass
arguments has costs to:

- the overhead of passing arguments to functions adds up; even a tiny
  difference in efficiency can make a big difference to the overall
  speed of the implementation;

- as well as the memory consumption;

- the amount of work the CPU does, hence your electricity bill;

- to say nothing of the Greenhouse gases, the electronic failure rate, etc;

- let's not forget the complexity of the compiler and the possibility of bugs.

See: https://en.wikipedia.org/wiki/Man_or_boy_test

Unless pass-by-X and pass-by-Y have the same costs, somebody somewhere is going
to care about the difference. That was my point. I tried to express it
humorously rather than pedantically.


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-08 Thread Steve D'Aprano
On Fri, 8 Sep 2017 05:54 pm, Gregory Ewing wrote:

> Steve D'Aprano wrote:
>> py> class K: # defines an object
>> ... def __init__(self, x):
>> ... self.x = x
>> ... def append(self, value):
>> ... self.x.append(value)
>> ...
>> py> a = []
>> py> b = K(a)
>> py> a is b  # these are not the same object (they're different types)
>> False
>> py> b.append(99)  # but modifying b modifies a
>> py> a
>> [99]
> 
> You didn't mutate the object bound to b there,
> you mutated the one bound to b.x, which is
> also bound to a.

Of course I do -- I've mutated one of the parts of the whole, therefore the
whole is mutated too.

Would you argue that if I took a hammer to your computer's motherboard, smashing
it to bits, that I haven't damaged your computer?

My class K is just a minimal sketch of a class that uses dependency injection
and composition, but that's not critical. Any compound object which has
publicly visible mutable parts is subject to the same sort of false positive:

book = Book()
assert book.annotations == []
page = book.pages[15]
assert book is not page  # the whole is not the same as the part
page.annotate(
'Is this the right room for an argument?')  # but if you mutate the part
assert book.annotations == [15]  # the whole mutates too




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-08 Thread Rhodri James

On 08/09/17 13:45, Stefan Ram wrote:

Gregory Ewing  writes:
[a random integer will on average have ]

 infinitely many
digits -- despite every actual integer only having finitely
many digits!

   This is not possible because every integer has
   a finite number of digits (in base 10).


Surely an infinitely large integer has an infinite number of digits?

--
Rhodri James *-* Kynesim Ltd
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-08 Thread Ben Bacarisse
Steve D'Aprano  writes:

> On Fri, 8 Sep 2017 12:28 am, Chris Angelico wrote:
>
>> languages without mutable objects don't
>> really care whether they're pass-by-X or pass-by-Y.
>
> Only if you don't care about efficiency.
>
> Believe me, the first time you pass a five gigabyte array to a function using
> pass-by-value, on a machine with only six gigabytes of memory, you'll care.

I think your general idea to separate language semantics from
implementation details is a good one, but you've dropped it here.  A
language with call-by-value semantics need not copy large objects when
passing them to a function.  The program must behave *as if* there is a
copy but there need not actually be one.


-- 
Ben.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-08 Thread Gregory Ewing

Rustom Mody wrote:

2. is — machine representation, too fine to be useful


No, it's *not* machine representation. As I pointed out before,
it's part of the abstract semantics of Python.

And it's not "too fine to be useful". On the contrary, being
aware of which objects are the same and which aren't is vital
to writing Python programs that behave in the intended way.


3. graph (or topological) equality



3 captures pythonistas intuition of same better than 1 or 2


I don't think so, see below.


a = [1,2]
b = [a,a]
c = [[1,2],[1,2]]



p = [1,2]
q = [p,p]
r = [[1,2],[1,2]]



Now the pythonista understands that b and c may be math-= but have different 
structure
Whereas b is graph-equal to q
And c is graph-equal to r

However there is no available operation to show/see that distinction


Because usually it's not particularly important to know
whether two separate structures have the same topology.

On the other hand, it *is* important to know things
such as 'b[0] is b[1]' but 'c[0] is not c[1]', because
it makes a difference to what happens if you mutate
any of those.


The trouble is that graph-isomorphism is NP-complete so the crucial operation
cannot be reasonably implemented


We're fortunate that it's not actually a crucial
operation, then. :-)

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-08 Thread Marko Rauhamaa
Gregory Ewing :
> There is more leeway when it comes to immutable objects;
> implementations are free to cache and re-use them, so well-written
> code avoids depending on the result of "is" for immutable objects.

I definitely trust that:

   a = b
   assert a is b

even when b holds an immutable object.

Assignment, argument passing, return value passing and yield (to name a
few) must preserve identity.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-07 Thread Chris Angelico
On Fri, Sep 8, 2017 at 1:01 PM, Rustom Mody  wrote:
>
>> Can you show an actual false positive (two distinct objects for which `is`
>> returns True) or false negative (the same object given as both operands for
>> `is` nevertheless returns False)? In the absence of any actual bugs in the
>> definition, I maintain that it is sufficient.
>
> You are not paying attention — the example above I gave in which
> python arbitrarily hi-handedly, inconsistently manifests different behavior
> between integer 1 and tuple (1,2)

You started with the assumption that the tuple (1,2) is the same as
the tuple (1,2). This is a false assumption; they are equal, but they
are not identical. How does your mathematical model cope with this?

>>> x = 1
>>> y = 1.0
>>> x == y
True
>>> x is y
False

There is no way that a compliant Python implementation can give any
other results for these expressions. These values are equal but not
identical. It's the same with the integers and tuples in your example,
except that there, Python is permitted to optimize by using the same
object.

Stop thinking about mathematics and assuming that (a) it is the
perfect way to explain software, and (b) we all have the same basis
you do. Start thinking about programming languages from a different
basis... you might actually learn something. Or just read what Steve
and I have been saying.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-07 Thread Rustom Mody
On Friday, September 8, 2017 at 7:39:38 AM UTC+5:30, Steve D'Aprano wrote:
> On Fri, 8 Sep 2017 04:24 am, Rustom Mody wrote:
> 
> > On Thursday, September 7, 2017 at 6:52:04 PM UTC+5:30, Gregory Ewing wrote:
> >> Rustom Mody wrote:
> >> 
> >> > I said: In that case please restate the definition of 'is' from the 
> >> > manual
> >> > which invokes the notion of 'memory' without bringing in memory.
> >> 
> >> I don't know whether it's in the manual, but at least for
> >> mutable objects, there is a way to define the notion of
> >> "same object" that doesn't require talking about "memory":
> >> 
> >> Two names refer to the same object if and only if mutations
> >> made through one are visible through the other.
> > 
> > Seems a sensible comment!
> 
> 
> Except that it is wrong, or at least over-generalised. It is trivially easy to
> show false positives:
> 
> py> class K: # defines an object
> ... def __init__(self, x):
> ... self.x = x
> ... def append(self, value):
> ... self.x.append(value)
> ...
> py> a = []
> py> b = K(a)
> py> a is b  # these are not the same object (they're different types)
> False
> py> b.append(99)  # but modifying b modifies a
> py> a
> [99]
> 
> 
> Rustom, I've already given you the definitive answer to your question about 
> how
> to define `is` without talking about memory. You haven't replied or
> acknowledged it, so here is it again:
> 
> `is` compares the two operands for identity. 

Preamble… so far so good

> If the two operands are the same
> object, `is` returns True, if they are distinct objects, `is` returns False.

restated
a is b iff a is b

A more than usually egregious demo of the circularity of defining 
isness/sameness

Models are needed
Math is one possible model
Machines are another
Paper and pen — which Chris keeps referring to — is another

Remove all models and you have frank hopeless circularity

> 
> 
> This does require that we agree on "same object", which as you point out is 
> (in
> its full generality) a difficult thing to define. 

More than difficult, impossible in the fully abstract philosophical case
When concretized to specific models not necessarily
the fundamental circularity then pushed out to the model
1 + 2 = 3
Are these '3's on your and my screen same? Same font? Same time?


E.g. in the past I've raised
> the paradox of My Grandfather's Axe.

Dont see the relevance (here)

> 
> But the intuitive, common-sense notion of "same object" is, I think, 
> sufficient
> here. If you want to argue that it is *not* sufficient, I think it's up to you
> to demonstrate a problem with the definition.
> 

Its not that you cant raise philosophical problems if you want
But when concretized to (basic) math, there are no disputes
so the argument becomes obtuseness to no point

In the case of python data model every single interminable thread like this one,
obviously started by a noob asking something genuinely and indicating
a real confusion disproves your claim to obvious intuition and common sense

Just to reiterate: Someone asked a question
Its not clear what (s)he understood from what we have going on and on about for
100s of posts



> Can you show an actual false positive (two distinct objects for which `is`
> returns True) or false negative (the same object given as both operands for
> `is` nevertheless returns False)? In the absence of any actual bugs in the
> definition, I maintain that it is sufficient.

You are not paying attention — the example above I gave in which
python arbitrarily hi-handedly, inconsistently manifests different behavior
between integer 1 and tuple (1,2)

I am now dropping off this thread [more important things to do]
with this observation:

There are these strange wondrous things in the world called 'mothers'
They take bawling shiing peeing pieces of fleshy exasperation called 'babies'
And convert them into intelligent human beings

Dunno how they do it…

More easily: if I, knowing English, read a German-English dictionary its ok,
a well-founded action — learning unknown-German via known-English

But reading a 'normal' English-English dictionary like Webster, Oxford etc
is borderline infinite recursion…
And occasionally fails — ambiguities, grey areas
Still it mostly works… with enough good faith

However bootstrapping the whole process from absolute zero — the mothers' task 
— 
is frankly beyond my ken

Bare (pure-philosophical, model-less) identity/sameness is analogous

So… what you think is obvious and trivially intuitive — the bald fact of 
semantics and comprehension — is to me quite miraculous
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-07 Thread Rustom Mody
On Thursday, September 7, 2017 at 6:52:04 PM UTC+5:30, Gregory Ewing wrote:
> Rustom Mody wrote:
> 
> > I said: In that case please restate the definition of 'is' from the manual 
> > which 
> > invokes the notion of 'memory' without bringing in memory.
> 
> I don't know whether it's in the manual, but at least for
> mutable objects, there is a way to define the notion of
> "same object" that doesn't require talking about "memory":
> 
> Two names refer to the same object if and only if mutations
> made through one are visible through the other.

Seems a sensible comment!

[Aside from the fact that 'visible' is likely ill or circularly defined — my 
other comment to Stefan. But lets just ignore that for now and assume that 
'visible' has no grey/dispute areas]

> 
> Python has definite rules concerning when mutable objects
> will be the same or not, and every correct implementation
> must conform to them. In that sense it's a fundamental
> concept that doesn't depend on implementation.

I'd like to know what these rules are

> 
> There is more leeway when it comes to immutable objects;
> implementations are free to cache and re-use them, so
> well-written code avoids depending on the result of
> "is" for immutable objects.

Which sounds like saying that 'isness' of immutables is ill/un-defined
Not that I object if this is said
My objection is to the claim that the isness of python's is and the isness of
'conceptually-same' are the same.

I believe that your definition of same and the one I earlier gave are similar 
(same?? Not sure)

Repeating here for ease: (with some clarifications)

We say equivalence relation R is coarser than S is
xSy ⇒ xRy

So x is y  ⇒ x == y but not (necessarily) vice versa

However there are not 2 but 3 equivalence relations:
1. == — mathematical, too coarse to understand nuances of python semantics
2. is — machine representation, too fine to be useful
3. graph (or topological) equality which experienced pythonistas have 
internalized
in understanding when two data structures are same or different
[Roughly Anton's diagrams that are beyond my drawing capability!]


And yet pythonistas need 3 to understand python data structures
ie 3 captures pythonistas intuition of same better than 1 or 2

>>> a = [1,2]
>>> b = [a,a]
>>> c = [[1,2],[1,2]]
>>> b == c
True
>>> b is c
False
>>> p = [1,2]
>>> q = [p,p]
>>> r = [[1,2],[1,2]]
>>> q == r
True
>>> q is r
False
>>> b == q
True
>>> b == r
True
>>> b is q
False
>>> b is r
False

Now the pythonista understands that b and c may be math-= but have different 
structure
Whereas b is graph-equal to q
And c is graph-equal to r

However there is no available operation to show/see that distinction

The trouble is that graph-isomorphism is NP-complete so the crucial operation
cannot be reasonably implemented

To make it more clear
≡ is graph-equal, ie 2. The pythonista understands that
b ≢ c ## ≡ is finer than ==
Whereas
b ≡ r
ie ≡ is coarser than is

And b and r are python-equivalent without any memory relation in the sense
that no sequence of valid operations applied to b and to r will tell them apart

— sometimes called 'trace-equivalence'

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-07 Thread Steve D'Aprano
On Fri, 8 Sep 2017 02:24 am, Chris Angelico wrote:

> On Fri, Sep 8, 2017 at 1:30 AM, Steve D'Aprano
>  wrote:
>> On Fri, 8 Sep 2017 12:28 am, Chris Angelico wrote:
>>
>>> languages without mutable objects don't
>>> really care whether they're pass-by-X or pass-by-Y.
>>
>> Only if you don't care about efficiency.
>>
>> Believe me, the first time you pass a five gigabyte array to a function using
>> pass-by-value, on a machine with only six gigabytes of memory, you'll care.
[...]
> Right - but sharing (in whatever form) is a pure optimization, with no
> visible semantics.

Apart from the disk activity light on your PC, as it starts thrashing :-)



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-07 Thread Gregory Ewing

Steve D'Aprano wrote:

I think that these two increment procedures will be (more or less?) equivalent:

procedure increment(var n: integer);
  begin
n := n + 1
  end;

procedure increment2(p: intpointer);
  begin
p^ := p^ + 1
  end;


They are, with the proviso that, in standard Pascal, increment2
can only be applied to a heap-allocated instance of intpointer,
whereas increment can be applied to any variable of type
integer.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-07 Thread Marko Rauhamaa
Chris Angelico :
> *facepalm*
>
> I got nothing to say to you.

Then why say anything?


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Steve D'Aprano
On Wed, 6 Sep 2017 11:02 pm, Stefan Ram wrote:

> Chris Angelico  writes:
>>The 'is' operator tests if two things are the same thing.
> 
>   »Roughly speaking, to say of two things that they are
>   identical is nonsense, and to say of one thing that it
>   is identical with itself is to say nothing at all.«
> 
> Ludwig Wittgenstein, Tractatus Logico-Philosophicus (5.5303)

"Roughly speaking".

But to be more precise, it is meaningful.

"Was that you yourself I saw yesterday walking down the street, or your
doppelgänger?"

Or to put it another way...

Was the person I saw yesterday identical (in the identity sense) to the person I
am speaking to now?

We don't really use "is identical" (in the identity sense) to compare "two
distinct things" versus "one thing" -- we use it to compare two *operands* and
don't know which situation applies until after we get the answer.

If we already knew they were identical, we wouldn't need to ask.

The same applies to when we are making statements rather than asking questions
(making assertions about identity rather than questioning it). The point of
making the assertion is to pass on information that would otherwise by
ambiguous:

"There is that same (identity) cat again (not merely one that looks like it)."



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Steve D'Aprano
On Wed, 6 Sep 2017 10:11 pm, Rustom Mody wrote:

> On Wednesday, September 6, 2017 at 5:08:20 PM UTC+5:30, Steve D'Aprano wrote:
>> On Wed, 6 Sep 2017 07:13 pm, Rustom Mody wrote:
>> 
>> 
>> > Can you explain what "id" and "is" without talking of memory?
>> 
>> Yes.
>> 
>> id() returns an abstract ID number which is guaranteed to be an integer, and
>> guaranteed to be distinct for all objects which exist at the same time. When
>> an object ceases to exist, its ID number may be re-used.
>> 
>> `is` compares the two operands for identity. If the two operands are the same
>> object, `is` returns True, if they are distinct objects, `is` returns False.
> 
 a = (1,2)
 b = (1,2)
 a is b
> False
 x = 1
 y = 1
 x is y
> True
> 
> a seems to be as 'same' to b as x is to y
> Python seems to think otherwise
> 
> Evidently your ‘same’ is not the same as mine??

You are (intentionally, I think) being obtuse. I am confident that you know very
well that "the same" as a general English term has many meanings, including:

- same in identity ("the same man I saw yesterday");
- closely similar ("the curtains are the same colour as the carpets");
- equal ("I gave the children the same number of lollies each");
- unchanged ("his attitude is the same as ever");
- of like kind ("you are exactly the same as your mother");

while "the same object" has specifically the first meaning.

How do you know that two objects are the same object? It isn't because they are
equal, or that they look vaguely the same. "Equal" is not equivalent to "the
same object":

py> a, b = [], []  # they sure look the same...
py> a == b
True
py> a.append(None)  # insert None into a
py> None in b  # but they aren't the same object
False


The only way to find out if two objects are the same object is to ask Python --
and Python is under no obligation to comply with your naïve intuitions about
objects. As you are well aware, because we've told you many times, Python often
caches objects so that they are reused rather than being recreated from scratch
when needed -- and it is free to do so in implementation and version dependent
ways.



>> > In fact we have got so used to the term 'memory' that it actually seems
>> > strange when someone like Dijkstra grumbles at the anthropomorphism and
>> > asks why its not called 'store'.
>> 
>> And if it were called "store" (grocery store? shoe store? clothes store?)
>> Dijkstra would have grumbled at the metaphor and asked why it wasn't
>> called "memory".
> 
> Memory is an old (middle-English) word.
> Until say 1945 it could be used in sentences like the following
> “I have memories of walking in the woods with my dad”
> “Where are the eggs?”   “Oops! Totally slipped my memory… Sorry"
> “The Dalai Lama has memories of his past lives”

I don't understand why you say "until 1945". You can still use memory in those
ways even today.

> Are you using ‘memory’ in this kind of way?

Yes.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread breamoreboy
On Wednesday, September 6, 2017 at 1:12:22 PM UTC+1, Rustom Mody wrote:
> On Wednesday, September 6, 2017 at 5:08:20 PM UTC+5:30, Steve D'Aprano wrote:
> > On Wed, 6 Sep 2017 07:13 pm, Rustom Mody wrote:
> > 
> > 
> > > Can you explain what "id" and "is" without talking of memory?
> > 
> > Yes.
> > 
> > id() returns an abstract ID number which is guaranteed to be an integer, and
> > guaranteed to be distinct for all objects which exist at the same time. 
> > When an
> > object ceases to exist, its ID number may be re-used.
> > 
> > `is` compares the two operands for identity. If the two operands are the 
> > same
> > object, `is` returns True, if they are distinct objects, `is` returns False.
> 
> >>> a = (1,2)
> >>> b = (1,2)
> >>> a is b
> False
> >>> x = 1
> >>> y = 1
> >>> x is y
> True
> 
> a seems to be as 'same' to b as x is to y
> Python seems to think otherwise
> 
> Evidently your ‘same’ is not the same as mine??
> 

This shows your complete ignorance of Python.  One would often suggest putting 
the shovel down, but it is far too late for that.

Kindest regards.

Mark Lawrence.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Rhodri James

On 06/09/17 14:02, Stefan Ram wrote:

Chris Angelico  writes:

The 'is' operator tests if two things are the same thing.


   »Roughly speaking, to say of two things that they are
   identical is nonsense, and to say of one thing that it
   is identical with itself is to say nothing at all.«

 Ludwig Wittgenstein, Tractatus Logico-Philosophicus (5.5303)


Irrelevant.  We are talking about identity, not identicallity (to coin a 
word).  Or in plainer English, asking if two things are the same thing 
is not the same as asking if two things are identical.


--
Rhodri James *-* Kynesim Ltd
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Rustom Mody
On Wednesday, September 6, 2017 at 5:48:48 PM UTC+5:30, Chris Angelico wrote:
> On Wed, Sep 6, 2017 at 10:11 PM, Rustom Mody  wrote:
> > On Wednesday, September 6, 2017 at 5:08:20 PM UTC+5:30, Steve D'Aprano 
> > wrote:
> >> On Wed, 6 Sep 2017 07:13 pm, Rustom Mody wrote:
> >>
> >>
> >> > Can you explain what "id" and "is" without talking of memory?
> >>
> >> Yes.
> >>
> >> id() returns an abstract ID number which is guaranteed to be an integer, 
> >> and
> >> guaranteed to be distinct for all objects which exist at the same time. 
> >> When an
> >> object ceases to exist, its ID number may be re-used.
> >>
> >> `is` compares the two operands for identity. If the two operands are the 
> >> same
> >> object, `is` returns True, if they are distinct objects, `is` returns 
> >> False.
> >
>  a = (1,2)
>  b = (1,2)
>  a is b
> > False
>  x = 1
>  y = 1
>  x is y
> > True
> >
> > a seems to be as 'same' to b as x is to y
> > Python seems to think otherwise
> >
> > Evidently your ‘same’ is not the same as mine??
> 
> *facepalm*
> 
> I got nothing to say to you. Have you been on this list all this time
> and still don't understand that Python sometimes optimizes immutables?

Losing 'memory' of context Chris?
Let me erm… remind:

I said 'is' refers to "same in machine representation"

Greg disagreed: « "is" in Python has an abstract definition that
doesn't depend on machine representation.»

I said: In that case please restate the definition of 'is' from the manual 
which 
invokes the notion of 'memory' without bringing in memory.

Steven gave his explanation by dropping 'memory' and gave a definition

Which I showed does not match expected common sense

Sure you can bring in the notion (now!) of optimization if you like
But you cant have it both ways
- 'is' is a fundamental conceptual notion of sameness
- 'is' is a machine/implementation specific notion of sameness which changes 
  depending on machine/implementation specific decisions

Of course you can have a third hand… Its usually called sophistry

The trouble with sophistrizing is that you get caught in your own net:
You (and Steven) claim that references (and aliases such as pointers) can be
expunged from the language semantics.
If you do that the term 'memory' remains standalone without any semantics.
And when you make a bogus expulsion of that as well, extant behavior becomes
unexplainable…
Except with a… (which I share)


*facepalm*
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Rustom Mody
On Wednesday, September 6, 2017 at 4:03:40 PM UTC+5:30, ROGER GRAYDON CHRISTMAN 
wrote:
> On 5 Sep 2017 14:28:44,  (Dennis Lee Bier) wrote: 
> > On 5 Sep 2017 17:57:18 GMT,  
> >>  But what does "a C++ reference" refer to?
> >>
> 
> > Per Stroustrup (The C++ Programming Language 4th Ed, page 189)
> 
> > """
> > * ...> * A reference always refers to the object to which it was 
> > initialized.
> > * ...
> 
> > A reference is an alternative name for an object, an alias. ...
> > """
> 
> > {Hmmm, and I see that the syntax can be used outside of parameter
> > declaration -- which is the only place I'd seen it previously... either
> > this is a change from earlier standards, or my classes just didn't feel the
> > need to expose a non-parameter reference -- since, based upon the above
> > book, you can not declare a bare reference "variable"; it MUST be
> > initialized with a real object.}
> 
> I think I can say something about this, having been a teacherof the classes 
> you refer to.   I intentionally avoided reference variables.
> IMO, the 'good' use for declaring a new reference variable (i.e. not 
> parameter)would be when (1) the object to which you refer to is 
> time-consuming to access(2) you plan to refer to this object more then once, 
> and don't want to repeatthat time-consuming process, and (3) you really want 
> a reference, and not a copy.
> The first two years of programming courses really do not have a purposethat 
> meets all three, so can "didn't feel the need" is probably applicable.
> I intentionally avoided them because reference variables simply compoundthe 
> problem of aliasing, so unless you really limit your reference variableto a 
> very tight sandbox, you could be causing more headache than you save.
> I do admit to occasionally defining a method that returned a reference,such 
> as one that overloads the [] operator.   But even so, I would generallybe 
> reluctant to giving an outside client a direct access to my 
> database'sinternal structures.  (Thank you Python for separating __getitem__ 
> and __setitem__)
> Python doesn't eliminate aliasing, of course, since most assignment 
> operationscreate aliases.  But at least it's nice to know that aliasing 
> immutable valuesis harmless.   Hence my unit on building recursive data 
> structures entirelyout of tuples.

The realization that immutability is a significant virtue is now beginning 
to percolate mainstream programming
Ive seen it in recent C# books as a definite recommendation… Something like
- Use value types
- Use getters but no setters

And you have a good design

Python makes this hard by giving less status to immutable types than mutable 
ones
- set comprehensions exist not frozenset comprehensions
- Likewise tuples and lists
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Rustom Mody
On Wednesday, September 6, 2017 at 5:08:20 PM UTC+5:30, Steve D'Aprano wrote:
> On Wed, 6 Sep 2017 07:13 pm, Rustom Mody wrote:
> 
> 
> > Can you explain what "id" and "is" without talking of memory?
> 
> Yes.
> 
> id() returns an abstract ID number which is guaranteed to be an integer, and
> guaranteed to be distinct for all objects which exist at the same time. When 
> an
> object ceases to exist, its ID number may be re-used.
> 
> `is` compares the two operands for identity. If the two operands are the same
> object, `is` returns True, if they are distinct objects, `is` returns False.

>>> a = (1,2)
>>> b = (1,2)
>>> a is b
False
>>> x = 1
>>> y = 1
>>> x is y
True

a seems to be as 'same' to b as x is to y
Python seems to think otherwise

Evidently your ‘same’ is not the same as mine??




> 
> > In fact we have got so used to the term 'memory' that it actually seems
> > strange when someone like Dijkstra grumbles at the anthropomorphism and asks
> > why its not called 'store'.
> 
> And if it were called "store" (grocery store? shoe store? clothes store?)
> Dijkstra would have grumbled at the metaphor and asked why it wasn't
> called "memory".

Memory is an old (middle-English) word.
Until say 1945 it could be used in sentences like the following
“I have memories of walking in the woods with my dad”
“Where are the eggs?”   “Oops! Totally slipped my memory… Sorry"
“The Dalai Lama has memories of his past lives”

Are you using ‘memory’ in this kind of way?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Steve D'Aprano
On Wed, 6 Sep 2017 07:13 pm, Rustom Mody wrote:


> Can you explain what "id" and "is" without talking of memory?

Yes.

id() returns an abstract ID number which is guaranteed to be an integer, and
guaranteed to be distinct for all objects which exist at the same time. When an
object ceases to exist, its ID number may be re-used.

`is` compares the two operands for identity. If the two operands are the same
object, `is` returns True, if they are distinct objects, `is` returns False.



> In fact we have got so used to the term 'memory' that it actually seems
> strange when someone like Dijkstra grumbles at the anthropomorphism and asks
> why its not called 'store'.

And if it were called "store" (grocery store? shoe store? clothes store?)
Dijkstra would have grumbled at the metaphor and asked why it wasn't
called "memory".




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Gregory Ewing

Steven D'Aprano wrote:

But many (perhaps even most) people have no problem dealing with location 
as a metaphor, where being in two places (metaphorically) is no problem 
at all:


- I am in love, in trouble and in denial all at once.


Sometimes the word "in" implies physical location, sometimes
it doesn't.

Being a member of more than one list is a familiar enough
concept, for example, although one would probably say
"on a list" rather than "in a list".

However, "on a list" doesn't really conjure up an image
of physical location. We wouldn't picture ourselves standing
on a piece of paper; rather, we would imagine our name or
other piece of identifying information being written on
the paper.

Dare I say... we would think of a *reference* to us being
on the list? :-)



Even when the location is not a state of being but an actual physical 
place, we can be in multiple places at once:


- I am in my home, in Melbourne, and in Australia all at once.


That's only non-weird because there is a nesting relationship
between those locations. It doesn't extend to more general
topologies. For example, if your home is in Melbourne, then
being in your home and Australia but *not* in Melbourne
would be an interesting trick.


Being in two places at once is a common trope in both fantasy and science 
fiction (often involving time travel).


And they're interesting plot devices precisely because they
defy our physical intuition so much. If you're trying to
deconfuse someone about Python semantics, tying their brain
up in knots doesn't seem like a very productive approach!

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Chris Angelico
On Wed, Sep 6, 2017 at 7:13 PM, Rustom Mody  wrote:
> On Wednesday, September 6, 2017 at 12:51:25 PM UTC+5:30, Gregory Ewing wrote:
>> Rustom Mody wrote:
>> > 2. is — machine representation, too fine to be useful
>>
>> Disagree - "is" in Python has an abstract definition that
>> doesn't depend on machine representation.
>>
>> --
>> Greg
>
> There is this (AFAIAC sophistry) in the docs describing the data model
> https://docs.python.org/3/reference/datamodel.html
>
> | Every object has an identity, a type and a value. An object’s identity never
> | changes once it has been created; you may think of it as the object’s 
> address
> | in memory. The ‘is’ operator compares the identity of two objects; the id()
> | function returns an integer representing its identity.
>
> | CPython implementation detail: For CPython, id(x) is the memory address 
> where
> | x is stored.
>
> Can you explain what "id" and "is" without talking of memory?

Yes, easily. Just delete the "CPython implementation detail" section
and the "you may think of it" part from that quote and let the rest
stand alone. None of the rest of that document depends on memory
addresses.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Chris Angelico
On Wed, Sep 6, 2017 at 7:01 PM, Gregory Ewing
 wrote:
> Chris Angelico wrote:
>>
>> You can't do this with Python, since pointer arithmetic fundamentally
>> doesn't exist.
>
>
> Pointer arithmetic doesn't exist in Pascal either, yet
> Pascal most definitely has pointers as a distinct data
> type.
>
> Insisting that only pointer arithmetic counts as
> "manipulating" pointers seems a strange way of defining
> the word.

Understood. I'm withdrawing the assertion that pointer arithmetic is
essential, weakening the demand to the ability to:

1) Take the address of an object (yielding a pointer)
2) Move the pointer around as its own thing, eg pass it as a function parameter
3) Dereference the pointer, to read or write the original object

But you have to be able to prove that #2 is actually looking at the
pointer as its own entity. This has to be distinct from passing around
the object itself in some way.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-06 Thread Steven D'Aprano
On Tue, 05 Sep 2017 21:17:30 -0700, Rustom Mody wrote:

> Sure you can say with Steven that this can be 'explained' by saying an
> object can be in two places at one time.
> Others would then say 'Humpty-dumpty!' since you have removed the most
> basic intuition of objects and you are in effect saying that a python
> object means what you ordain it means without further ado/explanation

I have previously agreed that the "multiple places at once" metaphor is 
not to everyone's liking.

But many (perhaps even most) people have no problem dealing with location 
as a metaphor, where being in two places (metaphorically) is no problem 
at all:

- I am in love, in trouble and in denial all at once.

Even when the location is not a state of being but an actual physical 
place, we can be in multiple places at once:

- I am in my home, in Melbourne, and in Australia all at once.

Being in two places at once is a common trope in both fantasy and science 
fiction (often involving time travel). These are not niche genres: they 
are *extremely* popular. One of the Harry Potter movies involved Harry, 
Ron and Hermoine travelling backwards in time a few minutes to watch 
themselves. It's a moderately common trope in stories like Doctor Who, 
where the Doctor frequently interacts with his past (or future) self. I 
recently saw an episode of Dark Matter that used the trope.

Robert Heinlein, one of the greats of SF, wrote a number of classic time 
travel stories involving people being in multiple places at once. (In one 
of them, the protagonist has a sex change and becomes *both* his own 
grandfather and grandmother.)

An object being inside itself is rarer, but its been done at least twice 
that I know of in Doctor Who.

Don't underestimate people's ability to stretch the location metaphor 
beyond actual physical location. We do it all the time for virtual 
locations like IRC channels:

- I'm in #python, #ruby and #javascript all at once.

But if the metaphor isn't for you, I'm not saying you have to use it.



-- 
Steven D'Aprano
“You are deluded if you think software engineers who can't write 
operating systems or applications without security holes, can write 
virtualization layers without security holes.” —Theo de Raadt
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-05 Thread Rustom Mody
On Tuesday, September 5, 2017 at 10:45:45 PM UTC+5:30, Ned Batchelder wrote:
> On 9/5/17 1:02 PM, Steve D'Aprano wrote:
> > On Tue, 5 Sep 2017 11:37 pm, Gregory Ewing wrote:
> >
> >> Dennis Lee Bieber wrote:
> >>> Pascal, probably Modula-2, Visual BASIC are closer to the C++ reference
> >>> semantics, in that the definition of a function declares how the
> >>> argument(s) are passed.
> >> Well, sort of. In Pascal and Modula, and also VB I think,
> >> parameters are the only things that can be declared as having
> >> reference semantics, whereas references in C++ are first-class
> >> things that can be stored in any variable.
> > No, they aren't first-class. 
> 
> Did you mis-read Gregory's claim? He said, "references *in C++* are
> first-class things".  You seem to be talking below about Python things.

I think its mostly true of C++
And Steven did say:

(I don't know enough about C++ to distinguish between the last two opinions, but
I'm strongly leaning towards "not values at all".) 

So he seems to be talking of C++ (as analogous to python??)

But I dont see that any of it is relevant

Whether references are 
- first-class (Algol-68, pointers-in-C) or are simply
- second class (C++)
- invisible (python, lisp, ruby, javascript)

has little to do with what we are talking

The question is whether we need the *idea* of references
(modulo humpty-dumpty-fication)
to talk *about* the language; ie it needs to be there in the human/informal
ontology, even if the docs play word-games and try to avoid trigger-words
in honour of PC.

In my view its almost the defining quality of imperative languages that
the semantics of the language is not properly/fully comprehensive without
(something like) references.

[Replace "imperative language" with "assignment and mutation" if you like]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-05 Thread Chris Angelico
On Tue, Sep 5, 2017 at 11:11 PM, Gregory Ewing
 wrote:
> Steve D'Aprano wrote:
>>
>> The third entity is the reference linking the name to the object (the
>> arrow).
>> This isn't a runtime value in Python, nor is it a compile time entity that
>> exists in source code. It is pure implementation, and as such, exists
>> outside
>> of the Python domain.
>
>
> The fact that there is a connection between the name and the
> object is very much part of Python's abstract semantics.
>
> There are different ways to implement that connection, but
> *any* implementation of Python has to include *some*
> representation of it.

Sure. But let's suppose you're building a Python implementation on top
of a language that has a perfectly good implementation of dict already
built for you. Literally every other namespace can be represented with
a dictionary, and the name:value association is that reference. Is the
reference *itself* a runtime value? No; you can't pick it up and move
it around - all you'll do is dereference it and get the value itself.
(Or you'll work with the name, as a string. That can sometimes serve
as a pseudo-reference.) Is it a compile time entity? Not directly
(assignment statements imply them, but they aren't themselves the
references). So Steve's comment is still correct.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-05 Thread Gregory Ewing

Steve D'Aprano wrote:

On Tue, 5 Sep 2017 02:51 am, Stefan Ram wrote:

>

 I am assuming that there are two argument passing mechanismss
 in the languages mentioned by me (C, C++, VBA, C#, Java,
 JavaScript, and Python):

- pass by aliassing (reference)
- pass "as if by assignment"


That assumption is wrong.


How is it wrong? What parameter passing mechanism in any
of those languages is not either by aliasing or by
assignment?

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Chris Angelico
On Tue, Sep 5, 2017 at 1:36 AM, Dennis Lee Bieber  wrote:
> On Tue, 05 Sep 2017 00:20:25 +1000, Steve D'Aprano
>  declaimed the following:
>
>>(Of course this is silly. As all physicists know, there are no people, animals
>>or cars in the world, there are only quarks and electrons.)
>
> Quarks and Leptons and Bosons (Oh, my!)
>
>
> {I tend to forget the bosons}

Once we get quantum computing as a regular and normal thing, we'll
have to redefine duck typing.

If it quarks like a duck...

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Antoon Pardon
On 04-09-17 16:30, Steve D'Aprano wrote:
> On Tue, 5 Sep 2017 12:09 am, Antoon Pardon wrote:
> 
>> Op 04-09-17 om 15:26 schreef Steve D'Aprano:
>>> On Mon, 4 Sep 2017 08:52 pm, Antoon Pardon wrote:
>>>
 Op 04-09-17 om 12:22 schreef Stefan Ram:
> Rustom Mody  writes:
>>> Stefan Ram wrote:
 JavaScript and Python do not have references as values
>>> Yes, they do. The difference is that they don't have any
> ...
>> Its because reference (or pointer or ?) is central to python's semantics
>   If they are so central, then it should be easy to show
>   quotes from The Python Language Reference to support that
>   claim.
 The section about assignment talks about reference counts.
>>> Does that mean that IronPython and Jython aren't implementations of Python?
>>> They have no reference counts.
>>
>> I am not a lawyer
> 
> But you are a Python programmer.
> 
> You should be aware that reference counts are a property of the CPython
> implementation, not a language feature. Jython and IronPython, at the very
> least, are valid, conforming implementations of Python the language which have
> no reference counts. Therefore reference counts cannot be central to Python's
> semantics, since there are Python interpreters that don't use them.

It is not my responsibility that reference counts are mentioned in the
language referece. In how far mentioning reference counts in the language
reference makes IronPython or Jython not python is IMO food for lawyers.

I also didn't claim reference counts are essential to python's semantics.

-- 
Antoon Pardon
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Tue, 5 Sep 2017 02:51 am, Stefan Ram wrote:

> Steve D'Aprano  writes:
>>Sorry Stefan, that is the same trap that many others fall into. You are
>>assuming that there are exactly two evaluation conventions:
>>- pass by reference
>>- pass by value
>>and so if a language doesn't do one, it must do the other.
> 
>   I am assuming that there are two argument passing mechanismss
>   in the languages mentioned by me (C, C++, VBA, C#, Java,
>   JavaScript, and Python):
> 
> - pass by aliassing (reference)
> - pass "as if by assignment"


That assumption is wrong.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Rustom Mody
On Monday, September 4, 2017 at 9:13:43 PM UTC+5:30, Steve D'Aprano wrote:
> On Tue, 5 Sep 2017 01:17 am, Rustom Mody wrote:
> 
> > Anton gave a picture explaining why/how references are needed and to be
> > understood
> 
> Antoon gave a picture demonstrating one model of Python's semantics.
> 
> It's a nice model that has a lot going for it, in particular that it matches 
> the
> most obvious implementation. But it doesn't describe *Python* semantics, it
> describes an overlap between Python the language and the implementation of the
> Python interpreter.
> 
> In particular, consider the picture of a name binding to a value:
> 
> 
>  +-+
>  | |
>  |  5  |
>  | |
>  +-+
> ^
> |
>
> 
> 
> This picture has three entities, but only two of them exist in Python:
> 
> - the object 5;
> 
> - the name "x" (names are not values in Python at runtime, but they 
>   are entities which exist in Python source code at compile time).
> 
> The third entity is the reference linking the name to the object (the arrow).
> This isn't a runtime value in Python, nor is it a compile time entity that
> exists in source code. It is pure implementation, and as such, exists outside
> of the Python domain.

A common fallacy:
https://en.wikipedia.org/wiki/Begging_the_question

Python does not have references/pointers/whatever
∴ Python does not have references (or whatever you want to (not) call it)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread breamoreboy
On Monday, September 4, 2017 at 3:20:22 AM UTC+1, Chris Angelico wrote:
> On Mon, Sep 4, 2017 at 12:05 PM, Steve D'Aprano wrote:
> > On Mon, 4 Sep 2017 04:15 am, Stephan Houben wrote:
> >
> >> Needless to say, according to the definition in Plotkin's paper, Python
> >> is "call-by-value".
> >
> > According to Plotkin's definition, when you pass a value like a 100MB 
> > string:
> >
> > "This is a long string of text..."  # continues on for millions more 
> > characters
> >
> > does the interpreter make a copy of the 100MB string?
> >
> > If not, then it isn't pass (call) by value.
> 
> This is another proof that you can't divide everything into "pass by
> value" vs "pass by reference", unless you mess around with "passing a
> reference by value" or other shenanigans. In C, a string is not an
> entity; it's simply an array of characters. Arrays are never passed by
> value; yet everything in C is passed by value. So you pass a
> pointer... by value.
> 
> What would you define LISP's semantics as? Pass by value? Pass by
> reference? Pass by name? Pass by immutability? Pass the salt?
> 
> ChrisA

I can't say that I'm too bothered about all this what with "Practicality beats 
purity" and all that.  Still for the definitive guides to Python I always go 
back to http://effbot.org/zone/call-by-object.htm and 
https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/

Kindest regards.

Mark Lawrence.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Tue, 5 Sep 2017 01:17 am, Rustom Mody wrote:

> Anton gave a picture explaining why/how references are needed and to be
> understood

Antoon gave a picture demonstrating one model of Python's semantics.

It's a nice model that has a lot going for it, in particular that it matches the
most obvious implementation. But it doesn't describe *Python* semantics, it
describes an overlap between Python the language and the implementation of the
Python interpreter.

In particular, consider the picture of a name binding to a value:


 +-+
 | |
 |  5  |
 | |
 +-+
^
|
   


This picture has three entities, but only two of them exist in Python:

- the object 5;

- the name "x" (names are not values in Python at runtime, but they 
  are entities which exist in Python source code at compile time).

The third entity is the reference linking the name to the object (the arrow).
This isn't a runtime value in Python, nor is it a compile time entity that
exists in source code. It is pure implementation, and as such, exists outside
of the Python domain.

I'm not saying that we should never use this model. Its a good model. But we
should be clear that it is a model of the implementation, and it describes
entities which are not part of the Python language. We cannot do this:


 +-+
 | |
 |  5  |
 | |
 +-+
^
|
   
^
|
   


or any of the other things we can do in a language with references-as-values,
like C or Pascal.



[...]
> Roger Christman compressed my foo and bar into one baz
> 
> def baz(x,y):
>x += y
> 
> Which leaks or doesnt leak x-modifications depending on its type


Yes, I see that -- but I don't see the point of it. What conclusion do you draw
from that?





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Tue, 5 Sep 2017 12:59 am, Rustom Mody wrote:

> On Monday, September 4, 2017 at 7:50:39 PM UTC+5:30, Steve D'Aprano wrote:
>> On Mon, 4 Sep 2017 01:11 pm, Rustom Mody wrote:
>> > Simply put: pythonistas have no coherent/consistent sense of what python
>> > values are. And the endless parameter-passing-nomenclature arguments are
>> > just the fallout of that.
>> 
>> This is not a dispute unique to the Python community. Similar arguments take
>> place in the Java and Ruby communities, and I daresay many others.
> 
> Well good to know we agree on this [I would add lisp to this list since its
> the progenitor of this model]
> 
> And it is a primary factor for the desirability of transcending the imperative
> paradigm

This is completely unrelated to the imperative paradigm.

You just said it yourself: the question of function calling conventions applies
to functional languages like Lisp as well. It even applies to purely functional
languages like Haskell:

https://softwareengineering.stackexchange.com/questions/184586/devising-test-of-haskells-value-reference-semantics


I especially love that one of the top-rated answers says that Haskell
simultaneously:

- doesn't have references;
- therefore Haskell is call-by-value;
- except that it actually has call-by-reference semantics;
- except that it is actually call-by-name;
- except that it is actually call-by-need.


The imperative paradigm has nothing to do with this.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Rustom Mody
On Monday, September 4, 2017 at 8:37:45 PM UTC+5:30, Steve D'Aprano wrote:
> On Tue, 5 Sep 2017 12:34 am, Rustom Mody wrote:
> 
> > On Monday, September 4, 2017 at 5:58:18 PM UTC+5:30, ROGER GRAYDON CHRISTMAN
> > wrote:
> >> Or with just one function: >>> def baz(x,y):
> >>  x += y
> >> >>> a = 10
> >> >>> b = [10]
> >> >>> baz(a,a)
> >> >>> a
> >> 10
> >> >>> baz(b,b)
> >> >>> b[10, 10]
> > 
> > Ha Ha!  Lovely
> > 
> > [I was about to ask Chris if he is being serious about relating this to the
> > presence of '=' ]
> > 
> > However if you desugar the += into __iadd__ then someone may argue
> > the presence of the = is an optical illusion
> 
> I'm afraid I can't quite follow what people think this example actually
> demonstrates.

Anton gave a picture explaining why/how references are needed and to be 
understood

I pointed out that while that picture is fine (and necessary) as part
of the explanation, it does not properly address the central question
of this thread, viz How to understand parameter passing in python.
With this example:

>>> def foo(x): x += 2
>>> def bar(x): x.append(2)
>>> a=10
>>> b=[10]
>>> foo(a)
>>> a
10
>>> bar(b)
>>> b
[10, 2]
>>> 

Roger Christman compressed my foo and bar into one baz

def baz(x,y):
   x += y

Which leaks or doesnt leak x-modifications depending on its type
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Tue, 5 Sep 2017 12:34 am, Rustom Mody wrote:

> On Monday, September 4, 2017 at 5:58:18 PM UTC+5:30, ROGER GRAYDON CHRISTMAN
> wrote:
>> Or with just one function: >>> def baz(x,y):
>>  x += y
>> >>> a = 10
>> >>> b = [10]
>> >>> baz(a,a)
>> >>> a
>> 10
>> >>> baz(b,b)
>> >>> b[10, 10]
> 
> Ha Ha!  Lovely
> 
> [I was about to ask Chris if he is being serious about relating this to the
> presence of '=' ]
> 
> However if you desugar the += into __iadd__ then someone may argue
> the presence of the = is an optical illusion

I'm afraid I can't quite follow what people think this example actually
demonstrates.

Augmented assignment operators += etc. are explicitly defined as a form of
assignment, but objects are permitted to optimize the operation in terms of
in-place mutation as well.

And that is precisely what lists do.

Given lists b and c, as above, b += c is functionally equivalent to:

b.extend(c)
b = b

In this case, the assignment is a no-op, but that is not always the case. The
assignment is the cause of a notorious "WAT?" moment in Python:


py> t = ([], 0)
py> t[0] += [999]
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'tuple' object does not support item assignment
py> t
([999], 0)


In this case, the line t[0] += [999] is desugared into something like:

t[0].extend([999])  # succeeds
t[0] = t[0]  # fails


Of course it would be stupid if that were *literally* what Python did. Rather,
Python calls the __iadd__ method of the list, which is implemented something
like this:

def __iadd__(self, other):
self.extend(other)
return self

and attempts to bind the return result to the target:

temp = t[0].__iadd__([999])
t[0] = temp



The assignment is necessary to support types like tuples, ints, strings etc.
which don't perform an in-place modification.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Rustom Mody
On Monday, September 4, 2017 at 7:50:39 PM UTC+5:30, Steve D'Aprano wrote:
> On Mon, 4 Sep 2017 01:11 pm, Rustom Mody wrote:
> > Simply put: pythonistas have no coherent/consistent sense of what python
> > values are. And the endless parameter-passing-nomenclature arguments are 
> > just
> > the fallout of that.
> 
> This is not a dispute unique to the Python community. Similar arguments take
> place in the Java and Ruby communities, and I daresay many others.

Well good to know we agree on this [I would add lisp to this list since its 
the progenitor of this model]

And it is a primary factor for the desirability of transcending the imperative 
paradigm
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Mon, 4 Sep 2017 11:30 pm, Antoon Pardon wrote:

> Op 04-09-17 om 15:24 schreef Steve D'Aprano:
>> I accept that many people dislike, or do not understand, conceptual models
>> where objects can be in more than one location at once. For many people,
>> dropping into the implementation and talking about references is easier to
>> understand. But that doesn't make it essential.
>>
>> The semantics of Python is that we assign objects to names, not references to
>> objects to names. There's no "get reference" or "address of" operation in
>> Python. We write:
> 
> What does that mean assigning objects to names?

Would it help if I use the term "bind" instead?

All values in Python are objects. Assignment looks like this:

target = expression

and Python evaluates the expression on the right, producing an object, and then
binds it to the target in the left.

The target is often a simple name, like:

foo = 1


but if you want to be pedantic[1] the target can also be more complicated:

func(arg).foo[bar] = 1



The glossary unfortunately doesn't define either name binding or assignment:

https://docs.python.org/3/glossary.html


but the Language Reference describes name binding:

https://docs.python.org/3/reference/executionmodel.html#naming-and-binding


and Wikipedia has a good description of it:

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





[1] And why not, I would if I were in your position *wink*


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Tue, 5 Sep 2017 12:09 am, Antoon Pardon wrote:

> Op 04-09-17 om 15:26 schreef Steve D'Aprano:
>> On Mon, 4 Sep 2017 08:52 pm, Antoon Pardon wrote:
>>
>>> Op 04-09-17 om 12:22 schreef Stefan Ram:
 Rustom Mody  writes:
>> Stefan Ram wrote:
>>> JavaScript and Python do not have references as values
>> Yes, they do. The difference is that they don't have any
 ...
> Its because reference (or pointer or ?) is central to python's semantics
   If they are so central, then it should be easy to show
   quotes from The Python Language Reference to support that
   claim.
>>> The section about assignment talks about reference counts.
>> Does that mean that IronPython and Jython aren't implementations of Python?
>> They have no reference counts.
> 
> I am not a lawyer

But you are a Python programmer.

You should be aware that reference counts are a property of the CPython
implementation, not a language feature. Jython and IronPython, at the very
least, are valid, conforming implementations of Python the language which have
no reference counts. Therefore reference counts cannot be central to Python's
semantics, since there are Python interpreters that don't use them.

Analogy: we might say that spark plugs are essential, or central, to cars. But
since there are electric cars without spark plugs (and, in the early years of
automotive technology, steam-powered cars without spark plugs) that would be
wrong.





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Rustom Mody
On Monday, September 4, 2017 at 5:58:18 PM UTC+5:30, ROGER GRAYDON CHRISTMAN 
wrote:
> >Does a poor job AFAIAC of explaining the difference between foo and bar in
> foll def foo(x): x += 2
>  def bar(x): x.append(2)
>  a=10
>  b=[10]
>  foo(a)
>  a
> >10
>  bar(b)
>  b
> >[10, 2]
>  
> Or with just one function: >>> def baz(x,y):
>  x += y 
> >>> a = 10
> >>> b = [10]
> >>> baz(a,a)
> >>> a
> 10
> >>> baz(b,b)
> >>> b[10, 10]

Ha Ha!  Lovely

[I was about to ask Chris if he is being serious about relating this to the 
presence of '=' ]

However if you desugar the += into __iadd__ then someone may argue
the presence of the = is an optical illusion
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Mon, 4 Sep 2017 01:11 pm, Rustom Mody wrote:

> Earlier
> Ben Bacarisse wrote:
>> The core of the idea is actually what the value-set of Python programs is --
> 
> Yes! That!!

Indeed.

Given the assignment:

x = 1


then I think we all agree that the value of x is 1. So far so good.

But then, in order to force the round peg of Python's actual behaviour into the
square hole of "pass by value", some people insist that while the value of x is
indeed 1, as we agreed above, it is also, simultaneously, some invisible,
unknowable, implementation-dependent "reference" that we cannot access in any
way without leaving the domain of the language itself.

(E.g. by hacking the interpreter, using ctypes, or taking advantage of
implementation-dependent hooks which are strictly outside of the language
itself, such as debugging hooks.)

In a way, it is an example of reductionism gone mad, as if a chemist insisted
that there are no people, animals or cars in the world, there are only
molecules.

(Of course this is silly. As all physicists know, there are no people, animals
or cars in the world, there are only quarks and electrons.)



> Parameter-passing models and nomenclature is really a red-herring

No, they are very relevant. They are all connected. But you cannot agree on what
the parameter passing models mean if you cannot even agree on what your
language's values are.

If you want to believe that the value of x above is something other than 1, then
you can conclude anything you like. And who knows, maybe you'll even find an
implementation of Python where it is true.

Personally, I believe that the value of x is actually a series of cytosine,
guanine, adenine and thymine nucleobases, and some day when Python runs on a
DNA computer I'll be proven right.

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

*wink*



> Its the “== is id” mess that is at the base of the mess:

That is irrelevant.



> Simply put: pythonistas have no coherent/consistent sense of what python
> values are. And the endless parameter-passing-nomenclature arguments are just
> the fallout of that.

This is not a dispute unique to the Python community. Similar arguments take
place in the Java and Ruby communities, and I daresay many others.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Antoon Pardon
Op 04-09-17 om 15:26 schreef Steve D'Aprano:
> On Mon, 4 Sep 2017 08:52 pm, Antoon Pardon wrote:
>
>> Op 04-09-17 om 12:22 schreef Stefan Ram:
>>> Rustom Mody  writes:
> Stefan Ram wrote:
>> JavaScript and Python do not have references as values
> Yes, they do. The difference is that they don't have any
>>> ...
 Its because reference (or pointer or ?) is central to python's semantics
>>>   If they are so central, then it should be easy to show
>>>   quotes from The Python Language Reference to support that
>>>   claim.
>> The section about assignment talks about reference counts.
> Does that mean that IronPython and Jython aren't implementations of Python? 
> They
> have no reference counts.

I am not a lawyer

-- 
Antoon Pardon

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Mon, 4 Sep 2017 01:31 pm, Stefan Ram wrote:

> Steve D'Aprano  writes:
>>That makes arrays (and strings) in C a bit of an odd corner case, and an
>>exception to the usual rules, like unboxed machine types in Java. We should
>>acknowledge them, but as exceptional cases, and we should note that Python has
>>no similar exceptional cases. All values in Python are first-class, and all
>>are passed in precisely the same way.
> 
>   I look at the following "generic" (C, Java, Python, ...)
>   pseudocode program:
> 
> define f( x ):
>   x = 9;
>   return;
> 
>   ...
> 
> a = 2;
> f( a );
> print( a );
> 
>   My definition: When the assignment »x = 9« has an effect on »a«,
>   then it's »call by reference«. Otherwise, it's call by value.

Sorry Stefan, that is the same trap that many others fall into. You are assuming
that there are exactly two evaluation conventions:

- pass by reference
- pass by value

and so if a language doesn't do one, it must do the other.

This is a false dichotomy! There are many more than just two conventions:

- pass by value
- pass by reference
- pass by name
- pass by object reference (object sharing)
- pass by need
- pass by future
- pass by copy-restore

and more.

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


You are right that Python is not pass by reference. You cannot write a general
swap procedure in Python:

a = 1
b = 2
swap(a, b)
assert a == 2 and b == 1


like you can in Pascal:

procedure swap(var a:integer, var b: integer);
  var
tmp: integer;
  begin
tmp := a;
a := b;
b := tmp;
  end;


But that's not enough to prove that Python is pass by value. One way to
demonstrate that Python is pass by value is to show that passing an argument to
a function makes a copy of it:

def is_copy_made(argument, idnumber):
"""Decide whether the argument was copied or not."""
if id(argument) == idnumber:
print('IDs match, no copy was made')
else:
print('IDs are different, copy was made')

value = {}  # any object

is_copy_made(value, id(value))



Python will ALWAYS print "IDs match" (provided you pass the actual id of the
argument -- no cheating by passing some other id, or an arbitrary number).
Python doesn't copy values when you pass them to functions.

Hence Python is neither pass by reference nor pass by value.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Antoon Pardon
Op 04-09-17 om 15:24 schreef Steve D'Aprano:
> I accept that many people dislike, or do not understand, conceptual models 
> where
> objects can be in more than one location at once. For many people, dropping
> into the implementation and talking about references is easier to understand.
> But that doesn't make it essential.
>
> The semantics of Python is that we assign objects to names, not references to
> objects to names. There's no "get reference" or "address of" operation in
> Python. We write:

What does that mean assigning objects to names? 

>> Its because pointers have been de-first-classed (from C say, as a starting
>> point) that the disagreements arise: - One bunch feel that since they've been
>> de-first-classed they've been removed
> Pointers are not merely second-class values, like functions and procedures in
> Pascal, or strings in C. They're not values *at all*.
>
> Its not just that Python doesn't allow you to return a pointer from a 
> function,
> or pass a pointer to a function as argument. You cannot dereference a pointer
> either, or get a pointer to an object at all. (Although you can emulate
> pointers in Python using objects.)
>
>
> For more about first-class values, see this Stackoverflow thread:
>
> https://stackoverflow.com/questions/2578872/about-first-second-and-third-class-value
>
> We can quibble whether Pascal functions are first-, second- or 
> first-and-a-half
> class values, or whether "third-class" even makes sense, but pointers, and
> references, are not values of *any* class in Python.
>
>
>
>

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Mon, 4 Sep 2017 08:52 pm, Antoon Pardon wrote:

> Op 04-09-17 om 12:22 schreef Stefan Ram:
>> Rustom Mody  writes:
 Stefan Ram wrote:
> JavaScript and Python do not have references as values
 Yes, they do. The difference is that they don't have any
>> ...
>>> Its because reference (or pointer or ?) is central to python's semantics
>>   If they are so central, then it should be easy to show
>>   quotes from The Python Language Reference to support that
>>   claim.
> 
> The section about assignment talks about reference counts.

Does that mean that IronPython and Jython aren't implementations of Python? They
have no reference counts.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Mon, 4 Sep 2017 08:12 pm, Rustom Mody wrote:

> Its because reference (or pointer or …) is central to python's semantics
> that we need to use them to talk/explain/understand.

References are central to understanding the implementation of Python
interpreters. (Perhaps not *all* interpreters, but using references of some
sort is the most obvious and easy way to implement Python's semantics.)

Dropping down into the implementation level and talking about references is
often useful. But it is not essential -- one can explain a lot of code without
any reference to "reference" ( pun intended *wink* ) at all. If we're willing
to accept a conceptual model where Python objects are capable of being in two
or more locations at once, we can explain ALL Python code without needing
references.

I accept that many people dislike, or do not understand, conceptual models where
objects can be in more than one location at once. For many people, dropping
into the implementation and talking about references is easier to understand.
But that doesn't make it essential.

The semantics of Python is that we assign objects to names, not references to
objects to names. There's no "get reference" or "address of" operation in
Python. We write:

x = y

not 

x = 


The interpreter may (or may not) use references or pointers in order to
implement Python's object model, but strictly outside of the scope of Python
the language.



> Its because pointers have been de-first-classed (from C say, as a starting
> point) that the disagreements arise: - One bunch feel that since they've been
> de-first-classed they've been removed

Pointers are not merely second-class values, like functions and procedures in
Pascal, or strings in C. They're not values *at all*.

Its not just that Python doesn't allow you to return a pointer from a function,
or pass a pointer to a function as argument. You cannot dereference a pointer
either, or get a pointer to an object at all. (Although you can emulate
pointers in Python using objects.)


For more about first-class values, see this Stackoverflow thread:

https://stackoverflow.com/questions/2578872/about-first-second-and-third-class-value

We can quibble whether Pascal functions are first-, second- or first-and-a-half
class values, or whether "third-class" even makes sense, but pointers, and
references, are not values of *any* class in Python.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Steve D'Aprano
On Mon, 4 Sep 2017 06:16 pm, Gregory Ewing wrote:

> Stefan Ram wrote:
>>   JavaScript and Python do not have references as values
> 
> Yes, they do. 

No they don't. Python has ints, floats, strings, lists, tuples, dicts, etc as
values. It has no "reference" type, nor can you define your own. (You can
create a class and call it "reference", but that doesn't make it one.)

You cannot get a reference to either an object, or a name, in Python code. The
value of x here:

x = 1

is the int 1, not a reference to the int 1. Likewise:

y = x

the value of y is the int 1, not a reference to the name x.

Nor does Python have anything like Pascal's "pointer to" operator:

x := ^y;

or the equivalent in C:

x = 


nor does Python allow you to write functions with output parameters, like this
C++ code:


void square(int x, int& result) // result is a reference to an int
{
result = x * x;
}

square(3, y);  // now y has the value 9



Although Python can emulate something close to output parameters by passing a
mutable compound object as the pseudo-output, e.g. by using list slice
assignment:


def square(x, result):
assert isinstance(result, list)
result[:] = [x*x]


Nor does Python allow assignment to a function call, as you can do in C++ with
references. Nor can you implement pass-by-reference in Python, as you can do in
C++ with references:

void f_slow(BigObject x) { /* ... */ }  
void f_fast(const BigObject& x) { /* ... */ }


f_slow implements normal pass-by-value semantics, and makes a copy of the
argument passed as x; f_fast implements pass-by-reference semantics, and does
not.


Python has no values which are references. Perhaps you are talking about the
implementation of some Python interpreters, rather than the Python language
itself? If so, you should say so.



> The difference is that they don't have any 
> way of *not* having references as values, 

Of course it does, in the same way it has no way of using unicorns as values.
You can't use what doesn't exist. Since Python does not have references as one
of its first-class values, or as any value at all, you can't use them as
values. All values in Python are objects, not references.



> so there's less 
> need to use the word explicitly in that way -- most of
> the time it's just understood. Nevertheless, terms such
> as "object reference" and "reference to an object" do
> get used in relation to Python when clarity is needed.

Certainly they do. That has nothing to do with the question of whether Python
has references as values.

We use the terms "assignment target", "while loop" and "pass statement" in
Python too, but that doesn't make them values.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread ROGER GRAYDON CHRISTMAN
>Does a poor job AFAIAC of explaining the difference between foo and bar in
foll def foo(x): x += 2
 def bar(x): x.append(2)
 a=10
 b=[10]
 foo(a)
 a
>10
 bar(b)
 b
>[10, 2]
 
Or with just one function: >>> def baz(x,y):
 x += y 
>>> a = 10
>>> b = [10]
>>> baz(a,a)
>>> a
10
>>> baz(b,b)
>>> b[10, 10]




-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Antoon Pardon
Op 04-09-17 om 13:08 schreef Stefan Ram:
> Antoon Pardon  writes:
>> Op 04-09-17 om 12:22 schreef Stefan Ram:
>>> Rustom Mody  writes:
> Stefan Ram wrote:
>> JavaScript and Python do not have references as values
> Yes, they do. The difference is that they don't have any
 Its because reference (or pointer or ?) is central to python's semantics
>>> If they are so central, then it should be easy to show
>>> quotes from The Python Language Reference to support that
>>> claim.
>> The section about assignment talks about reference counts.
>   Yes, but this only matters for the garbage-collection
>   semantics, not for the main semantics of the assignment.

Yes it does, because it implies that an assignment works
with references. If the assignment didn't work with references
but would work by copying over the old value with the new
value, you wouldn't have reference counts nor garbage collection.
at this level.

-- 
Antoon Pardon

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Antoon Pardon
Op 04-09-17 om 12:22 schreef Stefan Ram:
> Rustom Mody  writes:
>>> Stefan Ram wrote:
 JavaScript and Python do not have references as values
>>> Yes, they do. The difference is that they don't have any
> ...
>> Its because reference (or pointer or ?) is central to python's semantics
>   If they are so central, then it should be easy to show
>   quotes from The Python Language Reference to support that
>   claim.

The section about assignment talks about reference counts.

-- 
Antoon Pardon

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Chris Angelico
On Mon, Sep 4, 2017 at 8:27 PM, Rustom Mody  wrote:
> That's fine as far as it goes
> But then you have people (Steven above) who feel that python passing has
> no exceptions (in parameter passing)
> Does a poor job AFAIAC of explaining the difference between foo and bar in 
> foll
>
 def foo(x): x += 2
 def bar(x): x.append(2)
 a=10
 b=[10]
 foo(a)
 a
> 10
 bar(b)
 b
> [10, 2]


It's all about assignment. In foo, you have an assignment statement;
in bar, you don't. The diagram showed the behaviour of assignment.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Rustom Mody
On Monday, September 4, 2017 at 3:35:54 PM UTC+5:30, Antoon Pardon wrote:
> Op 04-09-17 om 00:44 schreef Dennis Lee Bieber:
> > And is a limited theoretical study, heavy in mathematics and light in
> > implementation.
> >
> > Programming Languages: Design and Implementation (Terrence W Pratt,
> > 1975, Prentice-Hall) has a whole section (6-9 Subprograms with Parameters:
> > Parameter Transmission Techniques)... 
> >
> > """
> > Basic parameter Transmission Techniques
> >
> > Transmission by Value:  ... the actual parameter is evaluated at the point
> > of call. The /values/ of the actual parameter is then transmitted to the
> > subprogram and becomes the initial value associated with the corresponding
> > formal parameter. ...
> >
> > Transmission by Reference (Location or Simple Name): In transmission by
> > reference a pointer is transmitted, usually a pointer to a data location
> > containing the value. ... Any assignment to Y in SUB will change the value
> > of X back in the calling program.
> 
> IMO that depends on the semantics of the assignment statement. In an 
> environment
> where an assignment copies the value into the object the variable points to, 
> this
> is correct. However if assignment provides a new object that is now bound to 
> the
> variable, it is incorrect.
> 
> The diagram below tries to illustrate the two different assignment semantics:
> 
> BEFORE
>  +-+   +-+
>  | |   | |
>  |  5  |   |  7  |
>  | |   | |
>  +-+   +-+
> 
> ^ ^
> | |
>   
> 
> 
>  x = y
> AFTER
> 
> C style| Python style
>|
>  +-+   +-+ |  +-+
>  | |   | | |  | |
>  |  7  |   |  7  | |  |  7  |
>  | |   | | |--->  | |
>  +-+   +-+ |   /  +-+
>   /
> ^ ^  /   ^
> | | /|
>

That's fine as far as it goes
But then you have people (Steven above) who feel that python passing has
no exceptions (in parameter passing)
Does a poor job AFAIAC of explaining the difference between foo and bar in foll

>>> def foo(x): x += 2
>>> def bar(x): x.append(2)
>>> a=10
>>> b=[10]
>>> foo(a)
>>> a
10
>>> bar(b)
>>> b
[10, 2]
>>> 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Chris Angelico
On Mon, Sep 4, 2017 at 8:12 PM, Rustom Mody  wrote:
> On Monday, September 4, 2017 at 1:46:55 PM UTC+5:30, Gregory Ewing wrote:
>> Stefan Ram wrote:
>> >   JavaScript and Python do not have references as values
>>
>> Yes, they do. The difference is that they don't have any
>> way of *not* having references as values, so there's less
>> need to use the word explicitly in that way -- most of
>> the time it's just understood.
>
> Well then why these long threads that get nowhere ?

Because these threads are populated by people who know other
languages. You can explain Python's semantics with pencil and paper
(or, as I like to do it, with a deck of cards and some tetrapaks of
sugar) to someone who's never used C, and there's no confusion. The
concepts of "pass by value" and "pass by reference" are as irrelevant
as the precise semantics of decades-old CPUs or the replacement
frequency of valves.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Rustom Mody
On Monday, September 4, 2017 at 1:46:55 PM UTC+5:30, Gregory Ewing wrote:
> Stefan Ram wrote:
> >   JavaScript and Python do not have references as values
> 
> Yes, they do. The difference is that they don't have any
> way of *not* having references as values, so there's less
> need to use the word explicitly in that way -- most of
> the time it's just understood. 

Well then why these long threads that get nowhere ?

> Nevertheless, terms such
> as "object reference" and "reference to an object" do
> get used in relation to Python when clarity is needed.

Its because reference (or pointer or …) is central to python's semantics
that we need to use them to talk/explain/understand.
Its because pointers have been de-first-classed (from C say, as a starting 
point) that the disagreements arise:
- One bunch feel that since they've been de-first-classed they've been removed
And could/should not be mentioned
- The others feel that since the removal is ½-assed we need to talk of them 
anyway.
All thats gone is the '*' which has become implicit from C's explicit
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Antoon Pardon
Op 04-09-17 om 00:44 schreef Dennis Lee Bieber:
>   And is a limited theoretical study, heavy in mathematics and light in
> implementation.
>
>   Programming Languages: Design and Implementation (Terrence W Pratt,
> 1975, Prentice-Hall) has a whole section (6-9 Subprograms with Parameters:
> Parameter Transmission Techniques)... 
>
> """
> Basic parameter Transmission Techniques
>
> Transmission by Value:  ... the actual parameter is evaluated at the point
> of call. The /values/ of the actual parameter is then transmitted to the
> subprogram and becomes the initial value associated with the corresponding
> formal parameter. ...
>
> Transmission by Reference (Location or Simple Name): In transmission by
> reference a pointer is transmitted, usually a pointer to a data location
> containing the value. ... Any assignment to Y in SUB will change the value
> of X back in the calling program.

IMO that depends on the semantics of the assignment statement. In an environment
where an assignment copies the value into the object the variable points to, 
this
is correct. However if assignment provides a new object that is now bound to the
variable, it is incorrect.

The diagram below tries to illustrate the two different assignment semantics:

BEFORE
 +-+   +-+
 | |   | |
 |  5  |   |  7  |
 | |   | |
 +-+   +-+

^ ^
| |
  


 x = y
AFTER

C style| Python style
   |
 +-+   +-+ |  +-+
 | |   | | |  | |
 |  7  |   |  7  | |  |  7  |
 | |   | | |--->  | |
 +-+   +-+ |   /  +-+
  /
^ ^  /   ^
| | /|
   


-- 
Antoon Pardon.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Chris Angelico
On Mon, Sep 4, 2017 at 6:16 PM, Gregory Ewing
 wrote:
> Chris Angelico wrote:
>>
>> This is another proof that you can't divide everything into "pass by
>> value" vs "pass by reference"
>
>
> True, but that doesn't mean you should deny that something
> is pass-by-value when it actually is.
>
>> In C, a string is not an
>> entity; it's simply an array of characters. Arrays are never passed by
>> value;
>
>
> I think it's more accurate to say that arrays are never
> passed at all in C.

This is technically true; however, it's common to describe a function
as "accepting a string" as a parameter. What it actually accepts is a
pointer to char. Is that "passing an array by reference"? Not quite.
Is it "passing a pointer by value"? Technically correct, but useless.
Is it "passing a string by "? Technically incorrect, but
probably more useful

> A better name for pass-by-value would be "pass-by-assignment".
> Passing a parameter by value is equivalent to assigning it
> to a local name.

That's true in Python too though - parameter passing is equivalent to
assigning to a local name. And in C++, where you have actual
references, a reference parameter is equivalent to initializing a
local reference with the same result. I expect that "parameter passing
is equivalent to assignment" is true in the bulk of languages.

>> yet everything in C is passed by value. So you pass a
>> pointer... by value.
>
>
> Yes, because that's what happens when you assign an array
> in C.
>
> If it seems screwy, it's because assignment is screwy in
> C, not parameter passing.

Sure, if you define "screwy" as "different from Python". But that's
the exact problem that got us where we are.

>> What would you define LISP's semantics as? Pass by value? Pass by
>> reference? Pass by name? Pass by immutability? Pass the salt?
>
>
> Let's see... the expression being passed gets evaluated
> once at the point of call, and the result gets bound to
> a local name. Looks exactly like pass-by-value to me.

Oh, looks exactly like pass-by-name-binding to me, then. Nothing's
getting copied, so it can't be pass-by-value.

See how non-simple it is?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Gregory Ewing

Stefan Ram wrote:

  JavaScript and Python do not have references as values


Yes, they do. The difference is that they don't have any
way of *not* having references as values, so there's less
need to use the word explicitly in that way -- most of
the time it's just understood. Nevertheless, terms such
as "object reference" and "reference to an object" do
get used in relation to Python when clarity is needed.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-04 Thread Gregory Ewing

Chris Angelico wrote:

This is another proof that you can't divide everything into "pass by
value" vs "pass by reference"


True, but that doesn't mean you should deny that something
is pass-by-value when it actually is.


In C, a string is not an
entity; it's simply an array of characters. Arrays are never passed by
value;


I think it's more accurate to say that arrays are never
passed at all in C.

A better name for pass-by-value would be "pass-by-assignment".
Passing a parameter by value is equivalent to assigning it
to a local name.


yet everything in C is passed by value. So you pass a
pointer... by value.


Yes, because that's what happens when you assign an array
in C.

If it seems screwy, it's because assignment is screwy in
C, not parameter passing.


What would you define LISP's semantics as? Pass by value? Pass by
reference? Pass by name? Pass by immutability? Pass the salt?


Let's see... the expression being passed gets evaluated
once at the point of call, and the result gets bound to
a local name. Looks exactly like pass-by-value to me.


unless you mess around with "passing a
reference by value" or other shenanigans.


What on earth are you talking about? I didn't even use
the words "value" or "reference" in the previous paragraph.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-03 Thread Rustom Mody
On Monday, September 4, 2017 at 7:50:22 AM UTC+5:30, Chris Angelico wrote:
> On Mon, Sep 4, 2017 at 12:05 PM, Steve D'Aprano wrote:
> > On Mon, 4 Sep 2017 04:15 am, Stephan Houben wrote:
> >
> >> Needless to say, according to the definition in Plotkin's paper, Python
> >> is "call-by-value".
> >
> > According to Plotkin's definition, when you pass a value like a 100MB 
> > string:
> >
> > "This is a long string of text..."  # continues on for millions more 
> > characters
> >
> > does the interpreter make a copy of the 100MB string?
> >
> > If not, then it isn't pass (call) by value.
> 
> This is another proof that you can't divide everything into "pass by
> value" vs "pass by reference", unless you mess around with "passing a
> reference by value" or other shenanigans. In C, a string is not an
> entity; it's simply an array of characters. Arrays are never passed by
> value; yet everything in C is passed by value. So you pass a
> pointer... by value.
> 
> What would you define LISP's semantics as? Pass by value? Pass by
> reference? Pass by name? Pass by immutability? Pass the salt?

“Pass the logic"
“Oops…”
“You slob! You’ve messed my consistency-carpet."

Earlier 
Ben Bacarisse wrote:
> The core of the idea is actually what the value-set of Python programs is --

Yes! That!!
Parameter-passing models and nomenclature is really a red-herring
Its the “== is id” mess that is at the base of the mess:
Simply put: pythonistas have no coherent/consistent sense of what python values 
are. And the endless parameter-passing-nomenclature arguments are just the 
fallout of that.

Maybe that’s what Ben means by??

> the passing by value just drops out of that. 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-03 Thread Steve D'Aprano
On Mon, 4 Sep 2017 12:20 pm, Chris Angelico wrote:

> This is another proof that you can't divide everything into "pass by
> value" vs "pass by reference", unless you mess around with "passing a
> reference by value" or other shenanigans. In C, a string is not an
> entity; it's simply an array of characters. Arrays are never passed by
> value; yet everything in C is passed by value. So you pass a
> pointer... by value.

Indeed. And we say that in C, arrays are not first-class entities. We might say
that in C, arrays (and strings) are not actually values -- only the pointer to
the first slot in the array is a value.

The difference[1] between C and Python is that *top level Python code* abstracts
away the pointer passing that goes on behind the scenes inside the interpreter.
Your Python code treats strings and arrays (lists or tuples or even actual
arrays) as first class values, while C does not.

If you want a Python function to accept a string as argument, you simply declare
the parameter (with or without optional type hint), and pass the string as
needed. In C (as far as I understand it, correct me if I'm wrong) you cannot.
You must declare the parameter as a *pointer* type, and explicitly pass a
pointer to the start of the array, not the array itself.

That makes arrays (and strings) in C a bit of an odd corner case, and an
exception to the usual rules, like unboxed machine types in Java. We should
acknowledge them, but as exceptional cases, and we should note that Python has
no similar exceptional cases. All values in Python are first-class, and all are
passed in precisely the same way.



> What would you define LISP's semantics as? Pass by value? Pass by
> reference? Pass by name? Pass by immutability? Pass the salt?

My understanding is that LISP has more-or-less the same calling mechanism as
Python, only it had it long before Barbara Liskov gave a name to it when
describing CLU.






[1] What, only one? *wink*


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-03 Thread Chris Angelico
On Mon, Sep 4, 2017 at 12:05 PM, Steve D'Aprano
 wrote:
> On Mon, 4 Sep 2017 04:15 am, Stephan Houben wrote:
>
>> Needless to say, according to the definition in Plotkin's paper, Python
>> is "call-by-value".
>
> According to Plotkin's definition, when you pass a value like a 100MB string:
>
> "This is a long string of text..."  # continues on for millions more 
> characters
>
> does the interpreter make a copy of the 100MB string?
>
> If not, then it isn't pass (call) by value.

This is another proof that you can't divide everything into "pass by
value" vs "pass by reference", unless you mess around with "passing a
reference by value" or other shenanigans. In C, a string is not an
entity; it's simply an array of characters. Arrays are never passed by
value; yet everything in C is passed by value. So you pass a
pointer... by value.

What would you define LISP's semantics as? Pass by value? Pass by
reference? Pass by name? Pass by immutability? Pass the salt?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-03 Thread Steve D'Aprano
On Mon, 4 Sep 2017 04:15 am, Stephan Houben wrote:

> Needless to say, according to the definition in Plotkin's paper, Python
> is "call-by-value".

According to Plotkin's definition, when you pass a value like a 100MB string:

"This is a long string of text..."  # continues on for millions more characters

does the interpreter make a copy of the 100MB string?

If not, then it isn't pass (call) by value.


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-09-03 Thread Stephan Houben
Op 2017-08-17, Rustom Mody schreef :
> On Thursday, August 17, 2017 at 6:49:19 AM UTC+5:30, Mok-Kong Shen wrote:
>> Am 17.08.2017 um 02:41 schrieb Steve D'Aprano:
>> > By reference and by value are not the only two conventions.
>> > 
>> > Perhaps if you go back to the 1950s you might be able to argue that
>> > "reference" and "value" are the only two conventions, but
>> > alternatives have existed for many decades, since *at least* 1960
>> > when Algol introduced "call by name".

I'm a bit late to this discussion, but pelase allow me to add some (to
me at least) fascinating history to this.

In 1966, a very influential paper was published:
P.J. Landin, "The Next 700 Programming Languages"
See: https://www.cs.cmu.edu/~crary/819-f09/Landin66.pdf

In this paper, Landin decribes a "family of unimplemented computing
languages that is intended to span differences of application area by a
unified framework". He calls this language (or family of languages)
ISWIM. It is a language with Lisp-like semantics but "Algol-like"
(i.e. infix) syntax, dynamically typed, and he introduces the novel
idea to have "Indentation, used to indicate program structure." 

Sounds familiar to anybody? Yep, this is basically proto-Python.

Anyway, then there is a later paper (from 1974) by
G.D. Plotkin, "Call-by-name, call-by-value and the λ-calculus"
(see http://www.sciencedirect.com/science/article/pii/0304397575900171 ).

In this paper, Plotkin "examines the old question of the relationship
between ISWIM and the λ-calculus, using the distinction between
call-by-value and call-by-name." Yep, in 1974, what to call the calling
convention of proto-Python was already an "old question".

In this paper, Plotkin introduces the λV-calculus, the call-by-value
lambda-calculus, to formalize what it is what ISWIM (and Python) are
actually doing. This paper is, to the best of my knowledge, the closest
thing to an "official" definition of what call-by-value actually means.

Needless to say, according to the definition in Plotkin's paper, Python
is "call-by-value".

Stephan
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-24 Thread Ben Bacarisse
Steve D'Aprano  writes:


It took a while to reply, and when I got round it I could not find
anything new that seemed to be worth saying.  I think we've both stated
our positions quite well.  I don't think we will end up in agreement,
and whilst I can grumble and nit-pick as well as anyone, with the big
picture left to one side there only seem to be such details left to fuss
over.

I hope, therefore, that you will forgive me for not replying in full,
but I none the less do thank you for taking the time to talk these
points over in depth.


-- 
Ben.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-22 Thread Gregory Ewing

Dennis Lee Bieber wrote:

On Sat, 19 Aug 2017 20:59:16 +1000, Steve D'Aprano
 declaimed the following:


I'm not sure that the VIN defines the vehicle exactly... I wouldn't want to try
driving a VIN without the rest of the vehicle. The mileage is terrible...


... or phenomenal

Depends on how one interprets 0miles / 0gallons


Your fuel consumption is NaN at that point, leading to the
well-known disclaimer in car advertisements, "Your mileage
may not be equal to itself."

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-20 Thread Steve D'Aprano
On Sat, 19 Aug 2017 12:04 am, Ben Bacarisse wrote:

[...]
>> Look at Scott Stanchfield's extremely influential post. It is *not*
>> called:
>>
>> "Java is call by value where the value is an invisible object reference,
>> dammit!"
>>
>> http://javadude.com/articles/passbyvalue.htm
>>
>> and consequently people who don't read or understand the *entire* post in
>> full take away the lesson that
>>
>> "Java is call by value, dammit!"
> 
> I don't think this is a fair point.  You will run out of ideas if they
> are to be avoided because some people will get the wrong idea when
> reading part of a description of that idea applied to some other language.

I don't understand your point here. I'm saying that Scott Stanchfield
intentionally created a pithy, short and snappy one-sentence summary of his
position which is incorrect and misleading. He actually does know the
difference between call by value and "call by value where the value is not the
value but a reference or pointer to the value", because he clarifies the second
further down in his essay.

Python values are objects, not "references or pointers". We bind objects to
names:

x = [1, 2, 3]

and pass objects to functions, and return objects back from functions. There's
no way in Python to get a reference to a object instead of the object itself:

y = ptr to x

If there was, we could write the classic "swap" procedure that Scott talks
about:

def func(a, b):
ref1 = ptr to a
ref2 = ptr to b
c = a
ref1 -> b
ref2 -> c
return None


or something along those lines, I haven't spent the time to debug this
pseudo-code so I may have got the details wrong.


>> So how do we distinguish between languages like Java and Python and
>> those like C and Pascal which *genuinely* are call by value, and do
>> exhibit call by value semantics? For example, in Pascal, if you
>> declare an array parameter without specifying it as "var", the
>> compiler will copy the entire array. Java does not do that. Python
>> does not do that.
> 
> Well, I know how I do that but you are not a fan of that view.

The problem isn't people like you who understand the point being made. Of course
the CPython virtual machine is passing pointers around by value, but that's
actually not very interesting unless you care about the detailed implementation
of how the virtual machine operates.

Which I accept is interesting to some people, but it doesn't help us when we
want to reason about Python values (objects). Okay, Python copies a reference
to my object. So what? What does that tell me about the behaviour of my Python
code?

The problem is that your explanation is at the wrong abstraction level for most
purposes. Ultimately, all computers do is move electric currents around. But
that's not abstract enough to reason about, so we have a hierarchy of
abstractions:

- flipping bits
- copying bytes
- reading and writing values at memory locations
- copying references/pointers
- binding objects to names  <--- Python syntax works at this level

and so on. (I may have missed a few.)

I'll accept that say that are some aspects of Python's behaviour that need to be
explained at lower levels of abstraction. Sometimes we care about copying
bytes.

But as an explanation of the behaviour of Python code, in general we should talk
at the same abstraction level as the language itself. And if we drop down to a
lower level of abstraction, we should make it clear from the start, not as an
after thought halfway down the essay.

 
> I found it a helpful view because it covers a lot more than just
> argument passing by saying something about the set of values that Python
> expressions manipulate.  It may be wrong in some case (hence my
> question) but I don't think I've been led astray by it (so far!).

I will admit that I haven't spent a lot of time thinking about how the argument
passing abstractions apply to general expressions as opposed to function calls.
I don't think it matters, but I haven't thought about it in enough detail to be
sure.


>> C doesn't treat arrays as first class values, so you can't pass an array as
>> argument. You can only pass a pointer to the start of the array. But you can
>> declare arbitrarily big structs, and they are copied when you pass them to
>> functions. Java objects are not. Despite Scott's insistence that Java is
>> exactly the same as C, it isn't.
> 
> I'm not here to defend someone else's incorrect statements!  Clearly C
> is not the same as Java.  Equally clearly, C only passes arguments by
> value (I have no idea about Java).

To be pedantic, Java treats native unboxed machine values (like ints and floats)
the same as C, using classical call-by-value "copy the int when you pass it to
a function" semantics.

But for objects, including "boxed" ints and floats, the semantics are exactly
the same as Python. I maintain "call by (object) sharing" is the best term to
use, to avoid confusion with classic call-by-value semantics, and to avoid
misusing the term 

Re: A question on modification of a list via a function invocation

2017-08-19 Thread breamoreboy
On Saturday, August 19, 2017 at 11:59:41 AM UTC+1, Steve D'Aprano wrote:

> Consider that in my family, one of our most precious heirlooms is the axe of 
> my
> great-great-great grandfather, which we have passed down from eldest son to
> eldest son for generations.
> 
> The axe is now almost 200 years old. Of course, occasionally the handle has
> broken and we've had to replace it, and from time to time the axe head itself
> was so worn out that it had to be replaced, but apart from those repairs the
> axe is the same one that my great-great-great grandfather used almost two
> centuries ago.
> 
> https://plato.stanford.edu/entries/identity-time/
> 
> -- 
> Steve
> “Cheer up,” they said, “things could be worse.” So I cheered up, and sure
> enough, things got worse.

Rather like Trigger's roadsweeping broom 
https://www.youtube.com/watch?v=s1VNNbSYdt0

Kindest regards.

Mark Lawrence.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-19 Thread Rick Johnson
Steve D'Aprano wrote: 
> I'm not sure that the VIN defines the vehicle exactly... I
> wouldn't want to try driving a VIN without the rest of the
> vehicle. The mileage is terrible... Quoting Fredrik Lundh:
> well, I guess you can, in theory, value an artificial
> number assigned to an object as much as the object itself.
> "Joe, I think our son might be lost in the woods" "Don't
> worry, I have his social security number"

While i'll admit your story is quite funny, it's not
relevant to my example.

> but putting that aside, your car analogy glosses over a
> genuine paradox here. Consider that in my family, one of
> our most precious heirlooms is the axe of my great-great-
> great grandfather, which we have passed down from eldest
> son to eldest son for generations.  The axe is now almost
> 200 years old. Of course, occasionally the handle has
> broken and we've had to replace it, and from time to time
> the axe head itself was so worn out that it had to be
> replaced, but apart from those repairs the axe is the same
> one that my great-great-great grandfather used almost two
> centuries ago.

No it isn't.

You're conflating the "history of the axe" with the
"physical axe" itself -- two distinct and unrelatable
concepts -- one tangible, and one not.

Generally, an axe consists of a handle and a blade, and if
you replace the blade and the handle, you have a whole new
axe. The axe you _now_ hold is merely a symbolic
representation of the physical object that your great-great-
great... deep breath... grandpappy held in his hand many
centuries ago, and neither love nor nostalgia can overcome
the reality that your axe, and the axe of your, urm,
"distant relative", is not the same object anymore.

Unfortunately, while my "car example" did correctly mirror
many of the aspects of Python lists, i admit it was clumsily
of me to conflate "components" with "contents". And although
components can be added and removed (like contents), the
adding and removing of these components do affect the
overall "identity" of the car object, in a way that say,
groceries in the back seat or passengers would not. So for
that reason, it fails. 

With that in mind, a "basket full of apples" would be a
better representation of lists, as the basket is not defined
by its content. For instance, apples can be added, or taken
away, or even oranges can be placed inside, but it will
always be a unique basket. A unique object.

And how the basket is referenced, in this reguard, is
inconsequential. And whether we choose to uniquely identify
the basket by say, placing a serial number on it or giving
it a friendly name like: "Mr. Weaves", it will always be a
unique object, regardless of content.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-19 Thread Steve D'Aprano
On Sat, 19 Aug 2017 08:07 pm, Rick Johnson wrote:

> And why is that so difficult for you to understand? It has
> always seemed perfectly logical to me...
> 
> [A thought experiment]
> Consider automobiles as an example. Automobiles are
> constructed in factories, and they are machines that are
> made of many subcomponents, but we reference the entire
> "conglomeration of subcomponents" (a "car") as single unit,
> and each unit is given a serial number (aka: "Vehicle
> Identification Number"). Now image one day your car is
> wrecked, and your mechanic replaces a few (or all) of the
> subcomponents with new subcomponents... would he also modify
> the VIN? Of course not! Because the subcomponents do not
> define the vehicle. If we want a new vehicle, then we
> request one from the factory.

I'm not sure that the VIN defines the vehicle exactly... I wouldn't want to try
driving a VIN without the rest of the vehicle. The mileage is terrible...

Quoting Fredrik Lundh:

well, I guess you can, in theory, value an artificial number assigned
to an object as much as the object itself.

"Joe, I think our son might be lost in the woods"
"Don't worry, I have his social security number"



but putting that aside, your car analogy glosses over a genuine paradox here.
Consider that in my family, one of our most precious heirlooms is the axe of my
great-great-great grandfather, which we have passed down from eldest son to
eldest son for generations.

The axe is now almost 200 years old. Of course, occasionally the handle has
broken and we've had to replace it, and from time to time the axe head itself
was so worn out that it had to be replaced, but apart from those repairs the
axe is the same one that my great-great-great grandfather used almost two
centuries ago.

https://plato.stanford.edu/entries/identity-time/



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-19 Thread Rick Johnson
On Wednesday, August 16, 2017 at 4:07:14 PM UTC-5, Mok-Kong Shen wrote:
> The above shows that with , i.e. assigning
> single values to individual members of alist (with
> alist[0]=3 etc.) is "principally" different from assigning
> a whole list to alist (with alist=[30,60,90]). The first
> operation doesn't affect the connection between ss and
> alist, while the second separates the connection between ss
> and alist, as your diagram above clearly indicates.

And why is that so difficult for you to understand? It has
always seemed perfectly logical to me...

[A thought experiment]
Consider automobiles as an example. Automobiles are
constructed in factories, and they are machines that are
made of many subcomponents, but we reference the entire
"conglomeration of subcomponents" (a "car") as single unit,
and each unit is given a serial number (aka: "Vehicle
Identification Number"). Now image one day your car is
wrecked, and your mechanic replaces a few (or all) of the
subcomponents with new subcomponents... would he also modify
the VIN? Of course not! Because the subcomponents do not
define the vehicle. If we want a new vehicle, then we
request one from the factory.

So when you do this:

car = [1,2,3]

You are requesting a _new_ car from the factory. But when
you do this:

car[0] = 10
car[1] = 20
car[2] = 30
...

You are merely changing out subcomponents of an _existing_
car. And even if you exchange every component, the car will
never be a "factory new" car.
 
> Isn't this kind of convention/rule something that appears
> to be not quite natural/"logical" to the common users (non-
> experts)?

No.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Steve D'Aprano
On Sat, 19 Aug 2017 12:43 am, Stefan Ram wrote:

> Ben Bacarisse  writes:
>>Steve D'Aprano  writes:
>>>"Java is call by value, dammit!"
>>I don't think this is a fair point.  You will run out of ideas if they
>>are to be avoided because some people will get the wrong idea when
>>reading part of a description of that idea applied to some other language.
> 
>   You are trying to cool off the topic. An expression such as
>   "da...t!" should be avoided in a cold topic. But otherwise,
>   "Java is call by value." is just fine.

Apart from being technically wrong and deeply misleading, yes it is fine.

And "Java is call by value, dammit!" is not my words, it is (almost) the actual
title of the piece by Scott Stanchfield.

http://javadude.com/articles/passbyvalue.htm

(I made a mistake: Scott calls it "Pass-by-Value".)

The precise, exact, copy-and-paste title used by Scott for his essay is:

Java is Pass-by-Value, Dammit!




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Steve D'Aprano
On Fri, 18 Aug 2017 10:36 pm, Rustom Mody wrote:

>> So what abstraction do you think call by object sharing is making, and in
>> what way does it leak?
> 
> Data Dependency — also called coupling — is generally considered to be
> deleterious to software quality

Excessive coupling. You cannot avoid some coupling, nor would you want to. The
whole purpose of programming is to couple your input and your output.

But yes, excessive and inappropriate coupling between parts of your code that
shouldn't be coupled is THE big evil in software development.

> Python removes the frank pointers of C (like) languages
> It does nothing about aliasing

Doesn't it?

> Sharing-by-object is nothing more than the diginification of aliasing

Is it? How so?


In any case, I have to repeat my question since you didn't answer it.

What abstraction do you think call by object sharing is making, and in what way
does it leak?

You made a statement that it is a leaky abstraction, not that it is
insufficiently vigorous in rooting out coupling branch and stem. That's a
separate criticism.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Ben Bacarisse
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> Ben Bacarisse  writes:
>>Steve D'Aprano  writes:
>>>"Java is call by value, dammit!"
>>I don't think this is a fair point.  You will run out of ideas if they
>>are to be avoided because some people will get the wrong idea when
>>reading part of a description of that idea applied to some other language.
>
>   You are trying to cool off the topic. An expression such as
>   "da...t!" should be avoided in a cold topic. But otherwise,
>   "Java is call by value." is just fine.

I didn't say it.


-- 
Ben.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Chris Angelico
On Sat, Aug 19, 2017 at 2:06 AM, Stefan Ram  wrote:
> Chris Angelico  writes:
>>Wrong. Your parameter always contains an object. Sometimes that object
>>is an array, sometimes that object is null. Null is not the absence of
>>an object, any more than zero is the absence of a number, or black is
>>the absence of an image.
>
>   »The reference values (often just references) are
>   pointers to these objects, and a special null reference,
>   which refers to no object.«
>
> The Java Language Specification 8, section 4.3.1
>
>   (Maybe your are thinking of Python's »None«,
>   which is something different than Java's »null«.)

I'm thinking of the abstract concept of a "value". Java differentiates
between "reference values" and "primitive values", where numbers and
strings are not reference values. The point of the above sentence is
that "null" is a special kind of reference value, as opposed to being
a kind of primitive value. But whether something is a reference or
primitive type, it's still a "value" in the abstract sense, and can be
passed as a parameter to a function.

Python simplifies things a lot here. Every value is an object. None is
an object, 42 is an object, "spam" is an object, [1,2,3] is an object,
and dict is an object. "Value" and "object" become virtually
interchangeable. But even in Java, where some things are objects and
some are not, they are still all values.

So I was slightly wrong in my terminology (I said "object" when it
would have been more accurate to say "value"), but I stand by the gist
of what I said there.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Chris Angelico
On Sat, Aug 19, 2017 at 1:42 AM, Stefan Ram  wrote:
> Chris Angelico  writes:
>>On Sat, Aug 19, 2017 at 12:43 AM, Stefan Ram  wrote:
>>>{ final java.lang.Object object = new java.lang.Object();
>>>  java.lang.System.out.println( object ); }
> ...
>>   You pass the
>>object, not the address of the object.
>
>   Yes, it's true, sometimes you can see it this way. But then,
>   one can also look at
>
> public final class Main
> {
>   private static void method( final java.lang.Object parameter )
>   { if( parameter == null )
> java.lang.System.out.println( "Not received any object." ); }
>
>   public static void main( final java.lang.String[] args )
>   {
> method( java.lang.Math.random() > 0.5 ? args : null ); }}
>
>   Here the parameter contains an object only with a probability
>   of 50 %. How do you call that which is passed otherwise?

Wrong. Your parameter always contains an object. Sometimes that object
is an array, sometimes that object is null. Null is not the absence of
an object, any more than zero is the absence of a number, or black is
the absence of an image.

>   So, when one is writing »"abc".length()«, by /the language
>   reference/, »"abc"« is a "reference to an object", and not an
>   object.
>
>   Your description might be appropriate for Python, but it
>   cannot describe completely the behavior of the example Java
>   program given above and it does not use the terms as the
>   Java Language Reference is using them.

Yes, it's a reference to an object. But you are printing out the
object itself. Names refer to objects; objects get manipulated.

>   And when you speak of objects, then after
>
 class example( object ):
> ...   def __init__( self ):
> ... self.v = 1;
> ...
 example = example()
 a = example
 b = example
 a.v = 2
 b.v
> 2
>
>   you should say that the variables »a« and »b« now contain
>   the same object. I /can/ accept this, but some people cannot
>   accept the idea of the same object being in two places
>   (variables). (Yes, I know that one usually uses the idea of
>   "binding" to mitigate this.)

The names a and b now refer to the same object. Or are bound to the
same object. Either way.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Chris Angelico
On Sat, Aug 19, 2017 at 12:43 AM, Stefan Ram  wrote:
> Ben Bacarisse  writes:
>>Steve D'Aprano  writes:
>>>"Java is call by value, dammit!"
>>I don't think this is a fair point.  You will run out of ideas if they
>>are to be avoided because some people will get the wrong idea when
>>reading part of a description of that idea applied to some other language.
>
>   You are trying to cool off the topic. An expression such as
>   "da...t!" should be avoided in a cold topic. But otherwise,
>   "Java is call by value." is just fine.
>
>   The rest has nothing to do with calls, but with expressions.
>
>   What happens in Java (Python and JavaScript are similar),
>   when this piece of code is executed?
>
> { final java.lang.Object object = new java.lang.Object();
>   java.lang.System.out.println( object ); }
>
>   In C terms, the value of »new java.lang.Object()« is an
>   address. The evaluation of »object« in the next lines yields
>   an address. This address then is passed to println.
>
>   Python and JavaScript both want to be "higher-level" in this
>   regard and avoid words such as "address", they use other
>   means of description. Java is in between: it speaks of the
>   addresses, but calls them "references".

It doesn't matter. What happens, in any sane language, is that the
object gets printed out. (In C, you'd have to somehow tell the println
function that it's getting an object. In C++, that would be handled by
operator overloading in cout, or somesuch.) You aren't printing out
the object's address - you're printing out the object. You pass the
object, not the address of the object. Details of memory locations etc
are important if you care about the implementation, but that's all. In
the same way that "x = 1" means that x now has the value of 1, your
code snippet is going to print the value of the new object, one way or
another.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Grant Edwards
On 2017-08-17, Ben Bacarisse  wrote:

> What goes wrong when someone thinks of Python as passing by value but
> the value of an expression is an object reference?

What usually goes wrong is that people don't combined that thinking
with an understanding of what the "=" operator does.

-- 
Grant Edwards   grant.b.edwardsYow! HUMAN REPLICAS are
  at   inserted into VATS of
  gmail.comNUTRITIONAL YEAST ...

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-18 Thread Ben Bacarisse
Steve D'Aprano  writes:

> On Thu, 17 Aug 2017 11:37 pm, Ben Bacarisse wrote:
>
>> What goes wrong when someone thinks of Python as passing by value but
>> the value of an expression is an object reference?

This seems to be a hot-button topic so I'd like to try to cool it off a
bit.  To in that spirit I'll point out that I'm not advocating teaching
"the wrong way to think about things", I'm asking if that model,
universally applied, actually leads to misunderstanding Python.

> Lots.
>
> Because even if people *think* about call by value where the value is an
> invisible reference to the actual value, that's not how they talk, because 
> it's
> too hard.

People will drop the word reference (I prefer identity) on occasion but
then they are always going to take shortcuts.

> Look at Scott Stanchfield's extremely influential post. It is *not*
> called:
>
> "Java is call by value where the value is an invisible object reference,
> dammit!"
>
> http://javadude.com/articles/passbyvalue.htm
>
> and consequently people who don't read or understand the *entire* post in full
> take away the lesson that 
>
> "Java is call by value, dammit!"

I don't think this is a fair point.  You will run out of ideas if they
are to be avoided because some people will get the wrong idea when
reading part of a description of that idea applied to some other language.

> So how do we distinguish between languages like Java and Python and
> those like C and Pascal which *genuinely* are call by value, and do
> exhibit call by value semantics? For example, in Pascal, if you
> declare an array parameter without specifying it as "var", the
> compiler will copy the entire array. Java does not do that. Python
> does not do that.

Well, I know how I do that but you are not a fan of that view.

I found it a helpful view because it covers a lot more than just
argument passing by saying something about the set of values that Python
expressions manipulate.  It may be wrong in some case (hence my
question) but I don't think I've been led astray by it (so far!).

> C doesn't treat arrays as first class values, so you can't pass an array as
> argument. You can only pass a pointer to the start of the array. But you can
> declare arbitrarily big structs, and they are copied when you pass them to
> functions. Java objects are not. Despite Scott's insistence that Java is
> exactly the same as C, it isn't.

I'm not here to defend someone else's incorrect statements!  Clearly C
is not the same as Java.  Equally clearly, C only passes arguments by
value (I have no idea about Java).

> If we claim that Python is call by value, without specifying the
> proviso "if you consider the value to be the invisible reference to
> the actual value" every time, we risk misleading others into wrongly
> inferring that Python is "call by value" and you shouldn't pass big
> lists to functions because then they will be copied and that's
> inefficient.

True, though I obviously take issue with using a particularly
long-winded phrase.  See later for how Liskov does it with one short
word.

The core of the idea is actually what the value-set of Python programs
is -- the passing by value just drops out of that.  Talking about
object identities (or references) is not so very cumbersome.  You have
to talk about *something* like that explain the language, don't you?

> Or people will be confused by the behaviour of Python, and decide that maybe 
> it
> is only call by value when you pass an immutable object like a string or int,
> and is call by reference when you pass a mutable object like a list or dict.
> Many people have done that.

I'm not a fan of this notion that an idea is bad because it goes wrong
when people don't understand it.  I don't think any description of
Python's semantics can avoid that trap.

> Imagine this conversation:
>
> * * *
>
> "I was reviewing your code, and in module spam.py I don't understand what 
> value
> the x variable has."
>
> "I don't know. It's something implementation dependent."
>
> "What do you mean?"
>
> "It depends on the interpreter. In CPython the value will be a pointer.
> Something like an address 0x1234abcd."
>
> "But Python doesn't have pointers."
>
> "Okay, call it a reference then. Whatever the implementation uses to point to
> objects."
>
> "I don't care about the Python implementation, I want to know the value of x."
>
> "I told you. It's some unknown and unknowable reference or pointer to an
> object."
>
> "Okay. Given x=1, what's the value of x?"
>
> "How do I know? It depends on the implementation. Something like 0x93a80f16 I
> guess. Why do you care about the value?"
>
>
> * * * 
>
> Obviously this isn't going to happen. Nobody actually thinks like
> this.

No, I should hope not!

> Given
> x=1, we all agree that the value of x is 1, not some invisible, unknown,
> unknowable, implementation-dependent reference.
>
> Instead they have to juggle two mutually contradictory meanings of value in
> 

Re: A question on modification of a list via a function invocation

2017-08-18 Thread Rustom Mody
On Friday, August 18, 2017 at 8:37:43 AM UTC+5:30, Steve D'Aprano wrote:
> On Thu, 17 Aug 2017 11:19 pm, Rustom Mody wrote:
> 
> > What is called ‘call-by-object’ or ‘call-by-sharing’ etc is really an
> > acknowledgement of the fact that parameter passing in the OO world along 
> > with
> > permissible mutation of data-structures is inherently leaky
> 
> 
> Leaky of *what*?
> 
> What do you think the abstraction is that is leaky?
> 
> Call by value leaks. The abstraction is that the argument received by the
> function is independent from the value you pass in. But the leak happens when
> you pass an array with a billion items, and the compiler makes a copy of the
> entire array, and you wonder why you run out of memory.
> 
> Call by reference leaks. The abstraction is that the argument received by the
> function is the argument you pass to the function. Not just the same, in the
> sense of equal, but one-and-the-same. As in, "me myself and I" all refer to 
> the
> same person. But the leak happens when you try to pass a literal or a constant
> or the result of an expression, rather than a variable, and the compiler
> says "Uh uh, you can't do that!"
> 
> So what abstraction do you think call by object sharing is making, and in what
> way does it leak?

Data Dependency — also called coupling — is generally considered to be 
deleterious to software quality

| The   presenceof   pointers   causescomplexdata-dependence  
| relationships.   Because  of  pointers and  aliasing, it may not be possible 
to 
| identify unambiguously the variable that is actually defined (resp., used) at 
a 
| statement containing a definition (resp., use).

https://www.cc.gatech.edu/~orso/papers/orso.sinha.harrold.IWPC01.pdf

Python removes the frank pointers of C (like) languages
It does nothing about aliasing

Sharing-by-object is nothing more than the diginification of aliasing
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Steve D'Aprano
On Thu, 17 Aug 2017 11:37 pm, Ben Bacarisse wrote:

> What goes wrong when someone thinks of Python as passing by value but
> the value of an expression is an object reference?

Lots.

Because even if people *think* about call by value where the value is an
invisible reference to the actual value, that's not how they talk, because it's
too hard. Look at Scott Stanchfield's extremely influential post. It is *not*
called:

"Java is call by value where the value is an invisible object reference,
dammit!"

http://javadude.com/articles/passbyvalue.htm

and consequently people who don't read or understand the *entire* post in full
take away the lesson that 

"Java is call by value, dammit!"

So how do we distinguish between languages like Java and Python and those like C
and Pascal which *genuinely* are call by value, and do exhibit call by value
semantics? For example, in Pascal, if you declare an array parameter without
specifying it as "var", the compiler will copy the entire array. Java does not
do that. Python does not do that.

C doesn't treat arrays as first class values, so you can't pass an array as
argument. You can only pass a pointer to the start of the array. But you can
declare arbitrarily big structs, and they are copied when you pass them to
functions. Java objects are not. Despite Scott's insistence that Java is
exactly the same as C, it isn't.

If we claim that Python is call by value, without specifying the proviso "if you
consider the value to be the invisible reference to the actual value" every
time, we risk misleading others into wrongly inferring that Python is "call by
value" and you shouldn't pass big lists to functions because then they will be
copied and that's inefficient.

Or people will be confused by the behaviour of Python, and decide that maybe it
is only call by value when you pass an immutable object like a string or int,
and is call by reference when you pass a mutable object like a list or dict.
Many people have done that.

Imagine this conversation:

* * *

"I was reviewing your code, and in module spam.py I don't understand what value
the x variable has."

"I don't know. It's something implementation dependent."

"What do you mean?"

"It depends on the interpreter. In CPython the value will be a pointer.
Something like an address 0x1234abcd."

"But Python doesn't have pointers."

"Okay, call it a reference then. Whatever the implementation uses to point to
objects."

"I don't care about the Python implementation, I want to know the value of x."

"I told you. It's some unknown and unknowable reference or pointer to an
object."

"Okay. Given x=1, what's the value of x?"

"How do I know? It depends on the implementation. Something like 0x93a80f16 I
guess. Why do you care about the value?"


* * * 

Obviously this isn't going to happen. Nobody actually thinks like this. Given
x=1, we all agree that the value of x is 1, not some invisible, unknown,
unknowable, implementation-dependent reference.

Instead they have to juggle two mutually contradictory meanings of value in
their head, and try to guess which one is meant at any point. Sometimes the
value of x is 1, and sometimes it is the invisible reference, and because that
is usually implied rather than explicit, there's always room for confusion and
misunderstanding.

This whole thing is unnecessary. It is no easier to learn that:

"Python is call by value, where the value is an invisible object reference"

than it is to learn that:

"Python is call by object sharing".

Either way, you have to learn what it means, otherwise it might as well be
gobbledygook:

"Python is whargle bargle by wazit, where the wazit is fizzbit wacker p'toing".


The terminology has been around for forty years. It was invented by Barbara
Liskov, one of the pioneers of OOP, the same person responsible for the Liskov
Substitution Principle. So its not like it is some obscure term invented
by "just some guy on the internet".



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Steve D'Aprano
On Thu, 17 Aug 2017 11:19 pm, Rustom Mody wrote:

> What is called ‘call-by-object’ or ‘call-by-sharing’ etc is really an
> acknowledgement of the fact that parameter passing in the OO world along with
> permissible mutation of data-structures is inherently leaky


Leaky of *what*?

What do you think the abstraction is that is leaky?

Call by value leaks. The abstraction is that the argument received by the
function is independent from the value you pass in. But the leak happens when
you pass an array with a billion items, and the compiler makes a copy of the
entire array, and you wonder why you run out of memory.

Call by reference leaks. The abstraction is that the argument received by the
function is the argument you pass to the function. Not just the same, in the
sense of equal, but one-and-the-same. As in, "me myself and I" all refer to the
same person. But the leak happens when you try to pass a literal or a constant
or the result of an expression, rather than a variable, and the compiler
says "Uh uh, you can't do that!"

So what abstraction do you think call by object sharing is making, and in what
way does it leak?




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Ben Bacarisse
Steve D'Aprano  writes:

> On Thu, 17 Aug 2017 10:14 am, Ned Batchelder wrote:

>> For some reason, students have been taught that things can be either
>> call-by-reference or call-by-value. But those are not the only two
>> possibilities, and neither completely describes how Python works.

That's obviously a crying shame when it happens, but I don't think it's
universally true.  Neither my experience as a student nor as a teacher
bear this out.


> Indeed. The insistence on this false dichotomy of call by value versus by
> reference puzzles me, since alternatives go back to one of earliest, and most
> influential, programming languages: Lisp. Algol, another early and hugely
> influential language, used call by name.
>
> Its like there was an entire generation of cooks and chefs who insisted that
> there are only two ways of cooking food: steaming, and barbecuing, and came up
> with elaborate rationalisations for why frying, roasting, boiling etc are
> actually one of the two.

Obviously it's better (as Ned also said) to learn a language using its
own terms, but sometimes it can help to make the jump from one language
to another to think about it in other, less specific, jargon.

What goes wrong when someone thinks of Python as passing by value but
the value of an expression is an object reference?  (I'd rather avoid
the term "reference" altogether and talk, instead, about an object's
identity, but Python already uses that term.)

I know you address this exact question in relation to Java (sorry, I cut
it because I'm not commenting on it) but I don't know Java at all, and I
only know Python as a casual user so I can't evaluate how well the
arguments carry over.


-- 
Ben.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Rustom Mody
On Thursday, August 17, 2017 at 6:49:19 AM UTC+5:30, Mok-Kong Shen wrote:
> Am 17.08.2017 um 02:41 schrieb Steve D'Aprano:
> > On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote:
> > 
> >> I have earlier learned some other (older) programming languages. For
> >> these the formal parameters are either "by reference" or "by value".
> > 
> > By reference and by value are not the only two conventions.
> > 
> > Perhaps if you go back to the 1950s you might be able to argue that 
> > "reference"
> > and "value" are the only two conventions, but alternatives have existed for
> > many decades, since *at least* 1960 when Algol introduced "call by name".
> > 
> > Python's evaluation strategy has existed for at least 43 years since Barbara
> > Liskov named the calling convention used by CLU "call by sharing" in 1974.
> > 
> > (It actually is much older than CLU, it goes back all the way to Lisp.)
> > 
> > https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
> > 
> > 
> >> In the first case, any modification of the formal parameter
> > 
> > Technically, you cannot modify the formal parameter, because the formal
> > parameter is just a name unbound to any value. It's just the label in the
> > function definition. You need to have actually passed a value as argument to
> > the function before there is anything to modify.
> > 
> >> inside
> >> a function affects the corresponding actual parameter of a function
> >> call, while in the second case a copy of the actual parameter is
> >> passed into the function so that any modification of the formal
> >> parameter inside the function has no effect at all outside. This is
> >> extremely clear-cut in comparison to Python, isn't it?
> > 
> > Python (and Ruby, Scheme, Ocaml, etc) are very clear-cut too. Just 
> > different.
> > 
> > This may help:
> > 
> > http://import-that.dreamwidth.org/1130.html
> > 
> > 
> >> Anyway, while
> >> any new user of a programming language certainly can be expected to
> >> take good efforts to learn a lot of new stuffs, I suppose it's good
> >> for any practical programming language to minimize the cases of
> >> surprises for those that come from other programming languages.
> > 
> > Indeed. And call by value is surprising: why should passing a giant array 
> > of a
> > million values make a copy of the array just because I pass it to a 
> > function?
> > 
> > And call by reference is even more surprising: if I assign a value to a 
> > local
> > name inside a function, why should it modify names in the caller's 
> > namespace?
> > 
> > Python's evaluation strategy is the least surprising of all the calling
> > strategies I've used.
> 
> Sorry for my poor capacity to comprehend. I read in the web page you
> cited: "In Python, the parameters to a function or method are always
> local to that function or method. Any assignments to local variables
> inside the function only affect the local variable, not the caller's
> variable." But then why in my test2 the global list does get modified?
> (Would alist[0]=3 etc. be "in-place modification" while alist=[30,60,90]
> is deemed not an "in-place modification"? If yes, where is that term
> clearly defined? (That term is new for me.)

Let me offer you a non-standard (in the python world) view on the subject.
The fact that you are confused is good… it is in fact confusing!

What is called ‘call-by-object’ or ‘call-by-sharing’ etc is really an 
acknowledgement of the fact that parameter passing in the OO world along with
permissible mutation of data-structures is inherently leaky

Since this covers the large majority of modern languages, people wonder:
“Seriously?! Can ALL these languages be WRONG?”
Well… They are not wrong. Some things leak… Leakage is a fact of life

https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/
is written from a slightly different viewpoint but it applies here as well

And the best/only way you can come to grips with this is to understand
the pointer-patterns of linked data-structures

This is a bit of a delicate matter…
You dont need to know about machine addresses or allocation
But you do need to understand that the graphical or topological structure of 
b and c are different even if printing them shows no difference

>>> a = [1,2]
>>> b = [a,a]
>>> c = [[1,2],[1,2]]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Steve D'Aprano
On Thu, 17 Aug 2017 10:02 pm, Stefan Ram wrote:

> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>Python uses a reference-counting memory reclaimer, so the
>>reference count of the OEBEA now is 2.
> 
>   IIRC, the reference-counting memory reclaimer (RCMC) is not
>   required by the language specification. The language
>   specification allows other kinds of memory management. But a
>   certain widespread Python implementation uses an RCMC as its
>   default way to manage memory.


CPython uses *two* garbage collectors, a reference counter, plus a second one
which runs periodically to collect unused object cycles which can't be
collected by the ref counter. You can enable or disable the second one using
the gc module.

You are correct that reference counting is not required by the language.

Jython uses the JRE's native garbage collector, and IronPython uses the .Net
CLR's garbage collector. One major difference between their GC's and CPython's
is that objects in Jython and IronPython can be moved in memory.

PyPy can be built with different sorts of garbage collectors, mostly
experimental.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Chris Angelico
On Thu, Aug 17, 2017 at 6:25 PM, Larry Hudson via Python-list
 wrote:
> On 08/17/2017 12:18 AM, Larry Hudson wrote:
>>
>> On 08/16/2017 03:39 PM, Chris Angelico wrote:
>>>
>>> On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen
>
> ...
> Oops, I replied to Chris's post, but it was meant for the OP.  I should have
> replied to Mok-Kong Shen's post instead.  My bad.  Sorry for the confusion,
> Chris.
>
>

No harm, no foul. The tone of your text made it clear who you were addressing.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Larry Hudson via Python-list

On 08/17/2017 12:18 AM, Larry Hudson wrote:

On 08/16/2017 03:39 PM, Chris Angelico wrote:

On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen

...
Oops, I replied to Chris's post, but it was meant for the OP.  I should have replied to Mok-Kong 
Shen's post instead.  My bad.  Sorry for the confusion, Chris.


--
 -=- Larry -=-
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-17 Thread Larry Hudson via Python-list

On 08/16/2017 03:39 PM, Chris Angelico wrote:

On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen
 wrote:

I have earlier learned some other (older) programming languages. For
these the formal parameters are either "by reference" or "by value".
In the first case, any modification of the formal parameter inside
a function affects the corresponding actual parameter of a function
call, while in the second case a copy of the actual parameter is
passed into the function so that any modification of the formal
parameter inside the function has no effect at all outside. This is
extremely clear-cut in comparison to Python, isn't it? Anyway, while
any new user of a programming language certainly can be expected to
take good efforts to learn a lot of new stuffs, I suppose it's good
for any practical programming language to minimize the cases of
surprises for those that come from other programming languages.


Python has a data model that is neither of the above, but it's simpler
in that you have one pattern for everything. Whether you're looking at
function parameters, return values, assignment, loops, function
definitions, or anything else, the model is exactly the same. And that
model is: objects exist independently of names, and names refer to
objects. If you do "x = y", you're saying "figure out which object 'y'
means, and make the name 'x' refer to it". If you do "x[1] = y",
you're saying "figure out which object 'y' means, and tell the object
that 'x' means that it should make [1] refer to that object". So if
you have multiple names referring to the same object, any change you
ask that object to do will be seen by every other name that also
refers to it - because it's all about the object.

ChrisA



Here's another explanation, same concepts just stated differently, perhaps giving a different 
perspective.


In a "traditional" programming language, variables are created/assigned by:

Setting aside a chunk of memory to hold the data and associating the variable name with that 
memory.  And since this chunk is a fixed size, the data type that can be stored there is also 
fixed at that time as well.  This is static typing.


Assignment is done by storing the new data in that memory location, overwriting what was already 
there.  But it has to be the proper data type so it doesn't overrun the memory allocated for it.


Python does it in the opposite order:

The data is stored in memory (or already exists) and the variable name is associated with that 
memory.  Python calls this name binding.  It is possible, and common, that this memory (data) 
has multiple names bound to it.


Assignment is done by associating the name to a different data value (memory location).  This 
data may be newly created or it can be previously existing data.  (The old data may or may not 
be 'garbage collected' — depending on other factors.)  A key point here is that the name has no 
memory size/data type itself and can be bound to ANY data — this is dynamic typing.


Where things get confusing is when we consider mutable/immutable data.

If it is immutable (unchangeable:  ints, floats, strings, tuples...) the _practical_ result is 
that although the implementation details are different, the result of running the program is the 
same.


But for mutable data (changeable IN PLACE:  lists, dictionaries...) the results can be 
surprising from the viewpoint of other languages.  Since this (mutable) data can have multiple 
variable names bound to it, changing the value(s) through ANY of the names changes this data for 
ALL of the names bound to it.


The OP said...

>> I suppose it's good
>> for any practical programming language to minimize the cases of
>> surprises for those that come from other programming languages.

I see your point, but it's irrelevant.  Part of learning any new language is to learn where/how 
the new language handles things differently from your previous experience.  You MUST learn the 
new ways and forget (or at least modify) your previous knowledge.  It's simply a necessary part 
of learning a new language.  Expect it and live with it!


I hope this description gives you another viewpoint to consider.  Good luck on your journey to 
becoming a Pythonista!


concepts in general terms.  The details may be (and probably are) quite different.>


--
 -=- Larry -=-
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Steve D'Aprano
On Thu, 17 Aug 2017 12:24 pm, Stefan Ram wrote:

> Steve D'Aprano  writes:
>>On Thu, 17 Aug 2017 11:07 am, Stefan Ram wrote:
>>>So, when an argument is actually passed, then the parameter
>>>can be modified? It seems Mok-Kong Shen was writing about
>>>this case.
>>I would say that the argument is modified.
> 
>   I was thinking along these lines:
> 
 def function( parameter ):
> ... parameter = parameter + 1
> ... print( parameter )
> ...
 argument = 4
 function( argument )
> 5
 argument
> 4

Okay, you are talking about the *local variable* called "parameter". We can:

- mutate the *object* bound to that local variable;

- re-bind (reassign) a different object to that local variable.


I was talking about the *name* (an identifier) in the function declaration, a
literal piece of text appearing in your source code. In that sense, we can't do
anything to the parameter until the function is called and an argument is
passed in.

I see now that both ways of looking at this have some validity. The FAQ helps a
bit:

Parameters are defined by the names that appear in a function
definition, whereas arguments are the values actually passed
to a function when calling it.

https://docs.python.org/3/faq/programming.html#faq-argument-vs-parameter


so in your example the argument is certainly the int 4, the parameter is the
name (the identifier) in the function declaration, but how do we refer to the
local variable inside the function? Is it the parameter (an identifier) or an
argument (an object) or something else?

I think the terminology is inconsistent. For example, here:

https://chortle.ccsu.edu/java5/Notes/chap34A/ch34A_3.html


"formal parameter" is defined as the *identifier* but later on the same page
seems to use it to refer to the *local variable*.

I think that if we are talking about the local variable when we say "parameter",
it is okay to talk about it being re-bound, but if we're talking about the
identifier, it is not.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Steve D'Aprano
On Thu, 17 Aug 2017 11:07 am, Stefan Ram wrote:

> Steve D'Aprano  writes:
>>On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote:
>>>In the first case, any modification of the formal parameter
>>Technically, you cannot modify the formal parameter, because the formal
>>parameter is just a name unbound to any value. It's just the label in the
>>function definition. You need to have actually passed a value as argument to
>>the function before there is anything to modify.
> 
>   So, when an argument is actually passed, then the parameter
>   can be modified? It seems Mok-Kong Shen was writing about
>   this case.

I would say that the argument is modified.

https://docs.python.org/3/faq/programming.html#faq-argument-vs-parameter

"Parameters are defined by the names that appear in a function definition,
whereas arguments are the values actually passed to a function when calling
it."


See also:

https://docs.python.org/3/glossary.html#term-parameter

https://docs.python.org/3/glossary.html#term-argument



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Steve D'Aprano
On Thu, 17 Aug 2017 10:14 am, Ned Batchelder wrote:


> the name/value data model of
> Python is not some trivial detail that we could change to match some
> other language: it's a fundamental part of what makes Python what it is.

It is also an evaluation model which matches nearly all of the most popular
languages of the last two decades, including Java[1], Ruby, (I think) PHP, and
Javascript.


> For some reason, students have been taught that things can be either
> call-by-reference or call-by-value. But those are not the only two
> possibilities, and neither completely describes how Python works.
> 
> Learn Python for what it is.
> 
> --Ned.

Indeed. The insistence on this false dichotomy of call by value versus by
reference puzzles me, since alternatives go back to one of earliest, and most
influential, programming languages: Lisp. Algol, another early and hugely
influential language, used call by name.

Its like there was an entire generation of cooks and chefs who insisted that
there are only two ways of cooking food: steaming, and barbecuing, and came up
with elaborate rationalisations for why frying, roasting, boiling etc are
actually one of the two.




[1] Despite the obnoxious insistence of Java experts that it is "pass by value",
where the value they are talking about is not the actual value, but some
hidden, implementation-dependent pointer or reference to the value:

http://javadude.com/articles/passbyvalue.htm

In the words of the Effbot Fredrik 

well, I guess you can, in theory, value an artificial number 
assigned to an object as much as the object itself.

"Joe, I think our son might be lost in the woods"
"Don't worry, I have his social security number"


http://www.effbot.org/zone/call-by-object.htm


It absolutely astonishes me how the Java community abuse the term "call by
value" in this way, despite the confusion it causes, and despite knowing the
correct answer. Scott Stanchfield actually does know what is going on. Despite
the inflammatory title of his post, and the outright false comment right at the
start:

"Java is strictly pass-by-value, exactly as in C."

deep in the article linked above, he comes clean and writes:

"A correct statement would be /Object references are passed by value/."

[emphasis /.../ in original]

But the objects themselves are not, as would be required by pass-by-value
semantics. So he knows that the values, the objects themselves, are not copied
when you pass them to a function. Only the invisible references to the objects
are copied, but they are not the values anyone cares about. The example he
shows has precisely the same behaviour as the equivalent Python code.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Mok-Kong Shen

Am 17.08.2017 um 02:14 schrieb Ned Batchelder:

On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen wrote:

  Anyway, while
any new user of a programming language certainly can be expected to
take good efforts to learn a lot of new stuffs, I suppose it's good
for any practical programming language to minimize the cases of
surprises for those that come from other programming languages.

Which other languages? Should Python's functions act like C functions,
or like Haskell functions?  Should Python's strings act like C strings,
or Ruby strings? Should Python's syntax be like C syntax, or like Lisp
syntax? If languages can't be different from each other, then there's no
point in having different languages.  I agree that gratuitous
differences are, well, gratuitous, but the name/value data model of
Python is not some trivial detail that we could change to match some
other language: it's a fundamental part of what makes Python what it is.

For some reason, students have been taught that things can be either
call-by-reference or call-by-value. But those are not the only two
possibilities, and neither completely describes how Python works.

Learn Python for what it is.


Your last sentence is fine and certainly to be accepted. Is there a
good document with which one could well use to resolve problems like the
present one? (Earlier I learned a few programming languages from
their ISO standard documents, which was not easy but later turned out
to be quite profitable.)

M. K. Shen

expect that there be a good documen




--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Cameron Simpson

On 17Aug2017 02:49, Mok-Kong Shen  wrote:

I don't yet understand. Why (by which rule of the language reference)
should "alist=[30,60,90]" mean discarding the name's reference to the
[1,2,3] list?


Section 7.2: Simple statements: Assignment Statements.

It says:

 An assignment statement evaluates the expression list (remember that this can 
 be a single expression or a comma-separated list, the latter yielding a 
 tuple) and assigns the single resulting object to each of the target lists, 
 from left to right.


So this:

 alist=[30,60,90]

"evaluates the expression list" (that is the [30,60,90]) and assigns it.

So this creates a new list object [30,60,90]. This is independent of whatever 
is/was in "alist". Then the reference to that is assigned to the name "alist".  
Since a name references to a single object, necessarily the reference to what 
"alist" previously refered is discarded.


So before this statement, both "ss" and "alist" referered to the list [1,2,3].  
After the statement "ss" has not been changed, and still refers to the [1,2,3] 
list. But "alist" now points to the new list which was created by the right 
hand side of the assignment statement i.e. the new [30,60,90] list.


You might try inserting some print statements in your code. 


 print("ss = %s:%r, alist = %s:%r" % (id(ss), ss, id(alist), alist))

after every statement in your code to see these changes. The id() function 
returns Python's internal object id for each existing object - this is unique 
at any given time. If two names refer to the same object, the same id will be 
printed. So this will let you see directly when the names start pointing at 
different objects.


You can also go:

 print("alist[0] = %s:%r" % (id(alist[0]), alist[0]))

to see the internal things within lists and so forth.


What I conjecture is that in test2 the assignment
"alist[0], ..." can only have a proper meaning according to the syntacs
of Python if alist is meant to be the global alist.


There is no "global alist".


But then, since
now the name alist is known to be global, why then in the next line of
test2 the name is suddenly interpreted to be local?


There are two reasons for this. Firstly, "alist" is a function parameter.  That 
is a local name, always. Also, every python function definition is inspected 
for assignment statements.  Any assignment statement "x = ..." causes the name 
"x" to be a local variable. This is important, because it provided _reliable_ 
and predictable behaviour.



(Which rule of
the language reference says that?) That's what I currently continue to
wonder.


4.2. Naming and Binding.

4.2.1 starts "Names refer to objects. Names are introduced by name binding 
operations.  The following constructs bind names: formal parameters to 
functions, ...". So a function parameter is a name binding.


Then "if a name is bound in a block, it is a local variable of that block, 
unless declared as nonlocal or global." ("nonlocal" and "global" are explicit 
statements.) So a function parameter, which is a binding, causes that name to 
be local to the function.


Regarding the inspection side of things to which i alluded to earlier, under 
"4.2.2. Resolution of names" it says "If a name binding operation occurs 
anywhere within a code block, all uses of the name within the block are treated 
as references to the current block. This can lead to errors when a name is used 
within a block before it is bound. This rule is subtle. Python lacks 
declarations and allows name binding operations to occur anywhere within a code 
block. The local variables of a code block can be determined by scanning the 
entire text of the block for name binding operations."


Cheers,
Cameron Simpson  (formerly c...@zip.com.au)
--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Mok-Kong Shen

Am 17.08.2017 um 02:41 schrieb Steve D'Aprano:

On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote:


I have earlier learned some other (older) programming languages. For
these the formal parameters are either "by reference" or "by value".


By reference and by value are not the only two conventions.

Perhaps if you go back to the 1950s you might be able to argue that "reference"
and "value" are the only two conventions, but alternatives have existed for
many decades, since *at least* 1960 when Algol introduced "call by name".

Python's evaluation strategy has existed for at least 43 years since Barbara
Liskov named the calling convention used by CLU "call by sharing" in 1974.

(It actually is much older than CLU, it goes back all the way to Lisp.)

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



In the first case, any modification of the formal parameter


Technically, you cannot modify the formal parameter, because the formal
parameter is just a name unbound to any value. It's just the label in the
function definition. You need to have actually passed a value as argument to
the function before there is anything to modify.


inside
a function affects the corresponding actual parameter of a function
call, while in the second case a copy of the actual parameter is
passed into the function so that any modification of the formal
parameter inside the function has no effect at all outside. This is
extremely clear-cut in comparison to Python, isn't it?


Python (and Ruby, Scheme, Ocaml, etc) are very clear-cut too. Just different.

This may help:

http://import-that.dreamwidth.org/1130.html



Anyway, while
any new user of a programming language certainly can be expected to
take good efforts to learn a lot of new stuffs, I suppose it's good
for any practical programming language to minimize the cases of
surprises for those that come from other programming languages.


Indeed. And call by value is surprising: why should passing a giant array of a
million values make a copy of the array just because I pass it to a function?

And call by reference is even more surprising: if I assign a value to a local
name inside a function, why should it modify names in the caller's namespace?

Python's evaluation strategy is the least surprising of all the calling
strategies I've used.


Sorry for my poor capacity to comprehend. I read in the web page you
cited: "In Python, the parameters to a function or method are always
local to that function or method. Any assignments to local variables
inside the function only affect the local variable, not the caller's
variable." But then why in my test2 the global list does get modified?
(Would alist[0]=3 etc. be "in-place modification" while alist=[30,60,90]
is deemed not an "in-place modification"? If yes, where is that term
clearly defined? (That term is new for me.)

M. K. Shen
M. K. Shen
M. K.

--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Ben Finney
Mok-Kong Shen  writes:

> I don't yet understand. Why (by which rule of the language reference)
> should "alist=[30,60,90]" mean discarding the name's reference to the
> [1,2,3] list?

I think I understand that question, but I find it surprising.

What is your expectation of the following code?

foo = "spam"
foo = "beans"
print(foo)

What should ‘foo’ be bound to after the second assignment?

Your question seems to imply you expect that the ‘foo’ reference would
be bound to *both* of “"spam"” and “"beans"”, somehow. Is that right?
How would that work?

To answer the question: The semantics of an assignment statement are at
in the Python language reference.

Assignment statements are used to (re)bind names to values […]

If the target is an identifier (name): […] The name is rebound if it
was already bound.




A reference (a name is one kind of reference) can be bound to exactly
one object at any time.

> But then, since now the name alist is known to be global, why then in
> the next line of test2 the name is suddenly interpreted to be local?

The same section of the language reference discusses that.

In brief: The fact that the first use of a name, in the current scope,
is an assignment, means that the name is implicitly within that scope.

-- 
 \ “Pinky, are you pondering what I'm pondering?” “Uh, I think so, |
  `\ Brain, but we'll never get a monkey to use dental floss.” |
_o__)   —_Pinky and The Brain_ |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Ben Finney
Steve D'Aprano  writes:

> On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote:
>
> > I have earlier learned some other (older) programming languages. For
> > these the formal parameters are either "by reference" or "by value".
>
> By reference and by value are not the only two conventions.
>
> Perhaps if you go back to the 1950s you might be able to argue that
> "reference" and "value" are the only two conventions, but alternatives
> have existed for many decades, since *at least* 1960 when Algol
> introduced "call by name".

Indeed. I have had a lot of success helping people, who come to Python
with the baggage of that false dichotomy, by using Fredrik Lundh's term
“call by object” to describe the Python argument-pass semantics.

Python’s model is neither “call by value” nor “call by reference”
(because any attempt to use those terms for Python requires you to
use non-standard definitions of the words “-value” and
“-reference”). The most accurate description is CLU’s “call by
object” or “call by sharing“. Or, if you prefer, “call by object
reference“.



> This may help:
>
> http://import-that.dreamwidth.org/1130.html

That's a good one too, thank you for writing it. I just wish Dreamwidth
would present a URL with a slug derived from the article title, so that
it was easier to search the URLs in my history :-)

-- 
 \   “Some people have a problem, and they think “I know, I'll use |
  `\ Perl!”. Now they have some number of problems but they're not |
_o__) sure whether it's a string or an integer.” —Benno Rice, 2011 |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Mok-Kong Shen

Am 17.08.2017 um 01:58 schrieb Cameron Simpson:

On 17Aug2017 01:03, Mok-Kong Shen  wrote:

Am 17.08.2017 um 00:39 schrieb Chris Angelico:

On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen
 wrote:
Chris wrote:
objects exist independently of names, and names refer to
objects. If you do "x = y", you're saying "figure out which object 'y'
means, and make the name 'x' refer to it". If you do "x[1] = y",
you're saying "figure out which object 'y' means, and tell the object
that 'x' means that it should make [1] refer to that object". So if
you have multiple names referring to the same object, any change you
ask that object to do will be seen by every other name that also
refers to it - because it's all about the object.


I may have misunderstood you. But I don't think what you wrote
above would explain why the program below produces the output:

[1, 2, 3]
[3, 6, 9]

M. K. Shen
-

def test2(alist):
 alist[0],alist[1],alist[2]=3,6,9
 alist=[30,60,90]
 return


This is because "alist" in the function test2 is a _local_ variable. It 
is a reference to the same list whose reference was passed to the function.


So:

  alist[0],alist[1],alist[2]=3,6,9

This modifies the references within that list.

  alist=[30,60,90]

This makes the local name "alist" refer to a shiny new list [30,60,90], 
totally unrelated to the list whose reference was first passed in. 
Importantly, in the main program "ss" still refers to the original list, 
which now has references to the values 3, 6 and 9 in it.



def test3(alist):
 alist=[30,60,90]
 alist[0],alist[1],alist[2]=3,6,9
 return


This code first points "alist" to a new, unrelated, list. Then modifies 
the references inside that list. Put different values in this function 
(by using the same values as in test2 you can see whether changes came 
from one or the other) eg use 5,6,7 or something.



ss=[1,2,3]
test3(ss)
print(ss)
test2(ss)
print(ss)


So test3 first discards its reference to the [1,2,3] list, then modifies 
an unrelate new list. So "ss" is unchanged, still holding [1,2,3].


Then test modifies the original list (affecting what "ss" holds) and 
then points its local "alist" at something else (another shiny new 
list). But that doesn't change what "ss" refers to, so it now has [3,6,9].


I don't yet understand. Why (by which rule of the language reference)
should "alist=[30,60,90]" mean discarding the name's reference to the
[1,2,3] list? What I conjecture is that in test2 the assignment
"alist[0], ..." can only have a proper meaning according to the syntacs
of Python if alist is meant to be the global alist. But then, since
now the name alist is known to be global, why then in the next line of
test2 the name is suddenly interpreted to be local? (Which rule of
the language reference says that?) That's what I currently continue to
wonder.

M. K. Shen

M. K. Shen
to

--
https://mail.python.org/mailman/listinfo/python-list


Re: A question on modification of a list via a function invocation

2017-08-16 Thread Steve D'Aprano
On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote:

> I have earlier learned some other (older) programming languages. For
> these the formal parameters are either "by reference" or "by value".

By reference and by value are not the only two conventions.

Perhaps if you go back to the 1950s you might be able to argue that "reference"
and "value" are the only two conventions, but alternatives have existed for
many decades, since *at least* 1960 when Algol introduced "call by name".

Python's evaluation strategy has existed for at least 43 years since Barbara
Liskov named the calling convention used by CLU "call by sharing" in 1974.

(It actually is much older than CLU, it goes back all the way to Lisp.)

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


> In the first case, any modification of the formal parameter 

Technically, you cannot modify the formal parameter, because the formal
parameter is just a name unbound to any value. It's just the label in the
function definition. You need to have actually passed a value as argument to
the function before there is anything to modify.

> inside 
> a function affects the corresponding actual parameter of a function
> call, while in the second case a copy of the actual parameter is
> passed into the function so that any modification of the formal
> parameter inside the function has no effect at all outside. This is
> extremely clear-cut in comparison to Python, isn't it?

Python (and Ruby, Scheme, Ocaml, etc) are very clear-cut too. Just different.

This may help:

http://import-that.dreamwidth.org/1130.html


> Anyway, while 
> any new user of a programming language certainly can be expected to
> take good efforts to learn a lot of new stuffs, I suppose it's good
> for any practical programming language to minimize the cases of
> surprises for those that come from other programming languages.

Indeed. And call by value is surprising: why should passing a giant array of a
million values make a copy of the array just because I pass it to a function?

And call by reference is even more surprising: if I assign a value to a local
name inside a function, why should it modify names in the caller's namespace?

Python's evaluation strategy is the least surprising of all the calling
strategies I've used.




-- 
Steven D'Aprano
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


  1   2   >