Re: nonlocal fails ?

2019-11-24 Thread Peter J. Holzer
On 2019-11-23 18:18:16 -0500, Richard Damon wrote:
> On 11/23/19 4:18 PM, Peter J. Holzer wrote:
> > On 2019-11-14 20:29:01 -0500, Dennis Lee Bieber wrote:
> >>Instead, at a simple level (a common description invokes "Post-It"
> >> notes)
> >>
> >>x = y
> >>
> >> means /find/ the object (somewhere in memory) that has a note "y" stuck to
> >> it. Without moving the "y" note, attach an "x" note to that same object.
> >> The object now has two names bound to it. If the "x" note used to be
> >> attached to an object, the old object no longer has that name -- and if the
> >> object has NO names attached, it is garbage collected.
> > Frankly, I find that model very unsatisfying.
[... reasons elided ...]
> > It's much simpler to talk about references or pointers or whatever you
> > want to call them. You can nicely visualize them with arrows (or pieces
> > of string, if you want, but arrows have the advantage of having a
> > direction) and it describes directly and without any mental gymnastics
> > what is going on (on a conceptual level - actual implementations might
> > be somewhat different, as long as they behave the same).
> >
> 
> A post-it note analogy is a very good description to allow a
> non-technical person to understand how it works.

It may allow a non-technical person to understand how it doesn't work. I
doubt this is very useful.


> Yes, as presented, it doesn't handle the concept of scope of variables,
> but that starts to get into more complexity than you might want for a
> simple model,

Yeah, that's exactly the problem. In an attempt to avoid being
"technical", it becomes needlessly complex. There seems to be a
wide-spread notion that goes something like this: This is how it really
works, therefore it is technical, and non-technical people don't
understand technical stuff. Therefore we must make up another
explanation. It will be more complicated and it will be wrong, but
because it is wrong it is non-technical, therefore non-technical people
will understand it.


> To a non-techie, a 'Pointer' is either a breed of dog or an arrow
> pointing in a general direction.

Ok, I apparently wasn't thinking straight yesterday. The real world
analogy is of course the address. Everybody knows what an address is
(and non-technical people won't have all that cognitive baggage either
which can lead programmers down endless rabbit holes). Adresses work
slightly differently in different countries (and sometimes even
different communities in the same country), but the differences won't
matter here. Let's just assume the street/house number system as it is
common in many western countries (if you are Japanese, think of blocks
and buildings instead).

So our objects live in houses on a street. When an object is created it
just plops into existence in an empty house (And they never leave their
house until they die, so the poor things are a pretty lonely bunch).

You don't tack post-it notes to the house-doors. Instead you have a
notebook[1] (or rather a bunch of them). So when you write something like

 1  x = "spam"
 2  y = "eggs"
 3  z = x + y
 4  Ω = z
 5  x = "ham"

what happens is this: 
 1  You create a new object with the value "spam": Let's say this is now
in Basil Street 42
You write into your notebook: "x: Basil Street 42"
 2  You create a new object with the value "eggs" in Basil Street 3
You write into your notebook: "y: Basil Street 3"
 3  You look into your notebook for the notes "x" and "y", find the
adresses "Basil Street 42" and "Basil Street 3" there, go to those
addresses to ask the objects for their values, create a new combined
object from them ("spameggs"), put it into a free house (Basil
Street 23) and write that into your notebook: "z: Basil Street 23".
(Oof, that was quite a mouthful for such a short line)
 4  You look up the address of "z" in your notebook and copy it into the
entry for Ω: "Ω: Basil Street 23".
 5  You create yet another object ("ham") in Basil Street 52.
You cross out your entry for "x" and write a new entry "x: Basil
Street 52"
(At this point there is no entry for Basil Street 42 in your
notebook any more. Eventually the object at that house will notice
that nobody loves it any more and die out of desparation)

This is quite close to what really happens, it generalizes nicely (e.g,
if you call a function, you just hand it a new notebook with just the
parameters filled in; An object (e.g. a tuple or a dict) may itself
possess a notebook; etc.) and it doesn't use any terms (except object)
that the "non-technical person" won't be familiar with.


> The key is that you are showing something fundamentally different than a
> box to hold a value. If you show names as boxes with arrows in them,
> someone is going to ask how to get one name point to another name (re
> the discussion about is it call by value or call by reference)

Which is a legitimate question. The answer is that Python's inventors
though

Re: nonlocal fails ?

2019-11-23 Thread Chris Angelico
On Sun, Nov 24, 2019 at 10:19 AM Richard Damon  wrote:
> Yes, as presented, it doesn't handle the concept of scope of variables,
> but that starts to get into more complexity than you might want for a
> simple model, and it is simple to extend to handle it, either every
> scope gets a different color post-it note, or when you write the name of
> the variable, you include the scope.

Or you can try to describe a scope as like a notebook where you say "x
is Blue K12" where the thing is identified by a matching note (think
raffle tickets). Not sure how useful it'd be, but the concept does at
least scale. Recursion means setting down one notebook and picking up
another (with most/all of the same names).

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


Re: nonlocal fails ?

2019-11-23 Thread Richard Damon
On 11/23/19 4:18 PM, Peter J. Holzer wrote:
> On 2019-11-14 20:29:01 -0500, Dennis Lee Bieber wrote:
>>  Instead, at a simple level (a common description invokes "Post-It"
>> notes)
>>
>>  x = y
>>
>> means /find/ the object (somewhere in memory) that has a note "y" stuck to
>> it. Without moving the "y" note, attach an "x" note to that same object.
>> The object now has two names bound to it. If the "x" note used to be
>> attached to an object, the old object no longer has that name -- and if the
>> object has NO names attached, it is garbage collected.
> Frankly, I find that model very unsatisfying.
>
> It's not just that it doesn't describe any existing or even plausibly
> possible implementation or that it implies a complexity that isn't there
> (search for an object with a note attached to it?). It starts to break
> down even for simple cases: There may be several variables called "x" in
> a program. How does the system distinguish between multiple objects with
> an "x" note? What about objects which have no name, like members of a
> tuple or the return value of a function? Sure, you can come up with
> arcane rules to on how to label a post-it to reference an object
> referenced by the x parameter of the lamba on line 7 of the third
> recursive invocation of function foo within the method bar of the Gazonk
> class in the fred packagerbut called from Bobble ... (ok, I'll stop
> now). But why would you? 
>
> It's much simpler to talk about references or pointers or whatever you
> want to call them. You can nicely visualize them with arrows (or pieces
> of string, if you want, but arrows have the advantage of having a
> direction) and it describes directly and without any mental gymnastics
> what is going on (on a conceptual level - actual implementations might
> be somewhat different, as long as they behave the same).
>
> hp

A post-it note analogy is a very good description to allow a
non-technical person to understand how it works.

Yes, as presented, it doesn't handle the concept of scope of variables,
but that starts to get into more complexity than you might want for a
simple model, and it is simple to extend to handle it, either every
scope gets a different color post-it note, or when you write the name of
the variable, you include the scope.

To a non-techie, a 'Pointer' is either a breed of dog or an arrow
pointing in a general direction.

The key is that you are showing something fundamentally different than a
box to hold a value. If you show names as boxes with arrows in them,
someone is going to ask how to get one name point to another name (re
the discussion about is it call by value or call by reference)

-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-23 Thread Peter J. Holzer
On 2019-11-14 20:29:01 -0500, Dennis Lee Bieber wrote:
>   Instead, at a simple level (a common description invokes "Post-It"
> notes)
> 
>   x = y
> 
> means /find/ the object (somewhere in memory) that has a note "y" stuck to
> it. Without moving the "y" note, attach an "x" note to that same object.
> The object now has two names bound to it. If the "x" note used to be
> attached to an object, the old object no longer has that name -- and if the
> object has NO names attached, it is garbage collected.

Frankly, I find that model very unsatisfying.

It's not just that it doesn't describe any existing or even plausibly
possible implementation or that it implies a complexity that isn't there
(search for an object with a note attached to it?). It starts to break
down even for simple cases: There may be several variables called "x" in
a program. How does the system distinguish between multiple objects with
an "x" note? What about objects which have no name, like members of a
tuple or the return value of a function? Sure, you can come up with
arcane rules to on how to label a post-it to reference an object
referenced by the x parameter of the lamba on line 7 of the third
recursive invocation of function foo within the method bar of the Gazonk
class in the fred packagerbut called from Bobble ... (ok, I'll stop
now). But why would you? 

It's much simpler to talk about references or pointers or whatever you
want to call them. You can nicely visualize them with arrows (or pieces
of string, if you want, but arrows have the advantage of having a
direction) and it describes directly and without any mental gymnastics
what is going on (on a conceptual level - actual implementations might
be somewhat different, as long as they behave the same).

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-17 Thread Random832
On Sun, Nov 17, 2019, at 07:26, Richard Damon wrote:
> I am not sure about C#, but in C++, a base language for C#, you can not
> take the address of a variable of reference type, if you do, you get the
> objected referred to, not the reference. References are essentially
> constant pointers, and can not be re-seated to reference another object.

C# is not very closely related to C++, calling it "a base language" would be 
inaccurate IMO. It's much more similar to Java in many ways. In particular, its 
"reference types" have absolutely nothing to do with C++'s references. They're 
much more similar to Java or Python object types. The "ref" references used for 
call-by-reference arguments are much more similar to C++ references [and 
there's no analogous feature in Java], but somewhat more restricted (they can't 
be used as a member of a class, for example)

The ability to make a "ref" reference to a variable of reference type is 
analogous to being able to make a reference to a pointer in C++, even though 
C#/Java/Python object references are not really the same things as pointers due 
to e.g. not having pointer arithmetic, etc. (the C++ .NET compatibility layer 
calls these 'handles', and uses the ^ character for them. The "ref" variables 
themselves use a % character, since they have to be distinct from &-references 
due to their role in the .NET garbage collection system)

> I suppose one way at looking at Python's name binding system (maybe not
> entirely accurate) would be to say that all Python names act like
> references, but that assignment, rather than being applied to the
> referred to object, re-seat the reference to point to the new object. As
> such, you can't get a reference to the name, to let one name re-seat
> where another name refers to.

I guess if anything this discussion has proven to me that C#'s decision to use 
"reference" for two unrelated concepts in fact causes more confusion than I 
thought it would from the perspective of the amount of .NET experience I have. 
However, my point was that the basic idea of pass by reference, even if it 
should be called something else (if implemented in Python it would probably use 
cell objects as "references", with some other kind of wrapper object being 
needed to handle the case of the target not being a local variable) is not 
fundamentally inapplicable to Python just because of the object reference 
model. Call by cell? Call by getter/setter?

There's an old saying that one of the hardest problems in computer science is 
naming things.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-17 Thread Richard Damon
On 11/17/19 1:33 AM, Random832 wrote:
> On Fri, Nov 15, 2019, at 13:41, Dennis Lee Bieber wrote:
>>  C# documents those as something visible to the user at the language
>> level...
>> https://www.infoworld.com/article/3043992/a-deep-dive-value-and-reference-types-in-net.html
>> """
>> Types in Microsoft .Net can be either value type or reference type.
>> """
> I was strictly talking about how reference types work (which are just like 
> python or Java objects), and how that is completely distinct from the "ref" 
> of call-by-reference arguments which are also supported, and that both 
> features coexist just fine in the same language. The existence of value types 
> wasn't really relevant to my point.
>
> I'm not sure if you were left with the impression that you can't have a "ref" 
> argument that points to a variable of reference type (and which does *not* 
> point directly to the object), but that is false.

I am not sure about C#, but in C++, a base language for C#, you can not
take the address of a variable of reference type, if you do, you get the
objected referred to, not the reference. References are essentially
constant pointers, and can not be re-seated to reference another object.

I suppose one way at looking at Python's name binding system (maybe not
entirely accurate) would be to say that all Python names act like
references, but that assignment, rather than being applied to the
referred to object, re-seat the reference to point to the new object. As
such, you can't get a reference to the name, to let one name re-seat
where another name refers to.

-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-16 Thread Random832
On Fri, Nov 15, 2019, at 13:41, Dennis Lee Bieber wrote:
>   C# documents those as something visible to the user at the language
> level...
> https://www.infoworld.com/article/3043992/a-deep-dive-value-and-reference-types-in-net.html
> """
> Types in Microsoft .Net can be either value type or reference type.
> """

I was strictly talking about how reference types work (which are just like 
python or Java objects), and how that is completely distinct from the "ref" of 
call-by-reference arguments which are also supported, and that both features 
coexist just fine in the same language. The existence of value types wasn't 
really relevant to my point.

I'm not sure if you were left with the impression that you can't have a "ref" 
argument that points to a variable of reference type (and which does *not* 
point directly to the object), but that is false.

>   Similar to Java.

Well, Java doesn't have user-defined value types, but again, value types are 
beside the point.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-15 Thread Chris Angelico
On Sat, Nov 16, 2019 at 5:41 PM Gregory Ewing
 wrote:
>
> On 16/11/19 8:22 am, Chris Angelico wrote:
> > That's the typical sort of description you get from someone who mostly
> > understands Python's semantics, but is hung up on the idea that
> > everything is either call-by-value or call-by-reference, and is trying
> > to figure out which box Python fits into.
>
> Or they may have read the definition of "call by value" in the
> Algol60 report, which says that "The actual parameter expression
> is evaluated and the result is assigned to the formal parameter."
> Which is exactly what Python does...
>

This is 100% true, but actually just punts on the question of
"call-by-X". All the subtleties are bound up in this little bit:

> the result is **assigned** to the formal parameter

Which is actually a really REALLY good way to start peeling things
back. In Python - and in many many other languages - the semantics of
function calls can be summarized as assignment. You evaluate an
expression in the caller's context, and assign the result to a local
name in the callee's context. So far, C and Python both have the exact
same semantics.

So the real question is: What is assignment? And that's where
everything about name binding comes in. In C, that assignment operates
on a bit-copying level, cloning some value (which might be a pointer).
In Python, that same assignment operates as a name binding, giving the
target a reference to some particular object.

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


Re: nonlocal fails ?

2019-11-15 Thread Gregory Ewing

On 16/11/19 8:22 am, Chris Angelico wrote:

That's the typical sort of description you get from someone who mostly
understands Python's semantics, but is hung up on the idea that
everything is either call-by-value or call-by-reference, and is trying
to figure out which box Python fits into.


Or they may have read the definition of "call by value" in the
Algol60 report, which says that "The actual parameter expression
is evaluated and the result is assigned to the formal parameter."
Which is exactly what Python does...

(Notably, that definition doesn't contain the word "value" at all.
So people who argue about the meaning of "call by value" based
on the meaning of "value" are barking in the wrong direction.)

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


Re: nonlocal fails ?

2019-11-15 Thread Terry Reedy

On 11/15/2019 5:48 AM, R.Wieser wrote:


Closures are standard in functional languages and are less limited than
you seem to think.


I was talking about the "nonlocal" method of variable inheritance, not
closures.
You cannot really separate the two.  A 'nonlocal' declaration can only 
be used in a nested function, and when you do, the function becomes a 
closure (a function with a '__closure__' attribute that is not None).



--
Terry Jan Reedy

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


Re: nonlocal fails ?

2019-11-15 Thread Chris Angelico
On Sat, Nov 16, 2019 at 6:20 AM Luciano Ramalho  wrote:
>
> Re: the whole pass by reference discussion.
>
> I've seen Python's argument passing described as "call by value,
> except that all values are references". This makes sense, but is
> confusing.

That's the typical sort of description you get from someone who mostly
understands Python's semantics, but is hung up on the idea that
everything is either call-by-value or call-by-reference, and is trying
to figure out which box Python fits into.

> Michael Scott, in his textbook Programming Language Pragmatics (4e)
> terms the Python way "call by sharing". That is the same mode used in
> most OO languages that don't have pointers, including Ruby, SmallTalk,
> and Java (this applies to Java reference types; primitive types use
> call by value). Call by sharing means that each formal parameter of
> the function gets a copy of each reference in the arguments.
>

I don't think anyone's yet linked to this:

https://nedbatchelder.com/text/names1.html

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


Re: nonlocal fails ?

2019-11-15 Thread Luciano Ramalho
Re: the whole pass by reference discussion.

I've seen Python's argument passing described as "call by value,
except that all values are references". This makes sense, but is
confusing.

Michael Scott, in his textbook Programming Language Pragmatics (4e)
terms the Python way "call by sharing". That is the same mode used in
most OO languages that don't have pointers, including Ruby, SmallTalk,
and Java (this applies to Java reference types; primitive types use
call by value). Call by sharing means that each formal parameter of
the function gets a copy of each reference in the arguments.

Cheers,

Luciano


On Fri, Nov 15, 2019 at 3:58 PM Dennis Lee Bieber  wrote:
>
> On Fri, 15 Nov 2019 11:54:50 -0500, Richard Damon
>  declaimed the following:
>
> >
> >I remember in early FORTRAN being able to do something like this (its
> >been years since I have done this so syntax is probably a bit off)
> >
> >
> >
> >foo(1)
> >
> >and after that if you did
> >
> >j = 1
> >
> >then now j might have the value 2 as the constant 1 was changed to the
> >value 2 (this can cause great confusion)
> >
>
> It was a very early FORTRAN that did that, since literals were stored
> in general R/W memory and the address was passed. Later FORTRAN compilers
> would flag a section of memory for R/O and stored literals in that section
> -- so attempts at modification would result in an error.
>
> >later I believe they added the ability to specify by value and by
> >reference, and you weren't allowed to pass constants by reference,
>
> Many compilers added extensions for interfacing to other languages 
> (DEC
> is famous for %val(), %ref(), %descr() for controlling parameters, and
> %loc() external to parameters. %ref wasn't really useful in FORTRAN since
> that is the native method. %loc returned the address of the target item.
> %descr was a weird one -- things like character strings were passed by
> descriptor: first word was the address [standard reference model], second
> word encapsulated information like the length allocated to the string [not
> the length used, but the size of the memory allocation].
>
> Literals were still passed by reference -- just to read-only memory
> block. Otherwise the called function wouldn't know how to behave!
>
> subroutine xyz(parm)
> integer parm
>
> ...
>
> call xyz(1)
> call xyz(abc)
>
> if the first was passed by value and the second by reference, what was
> "parm" in the called function to do
>
>
> --
> Wulfraed Dennis Lee Bieber AF6VN
> wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/
>
> --
> https://mail.python.org/mailman/listinfo/python-list



-- 
Luciano Ramalho
|  Author of Fluent Python (O'Reilly, 2015)
| http://shop.oreilly.com/product/0636920032519.do
|  Technical Principal at ThoughtWorks
|  Twitter: @ramalhoorg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-15 Thread Bev In TX


> On Nov 15, 2019, at 11:11 AM, Python  wrote:
> 
> Richard Damon wrote:
> ...
>> then elsewhere you could do
>> foo(j)
>> and after that j is 2
>> you also could do
>> foo(1)
>> and after that if you did
>> j = 1
>> then now j might have the value 2 as the constant 1 was changed to the
>> value 2 (this can cause great confusion)
> 
> Wow! So fubar that such a feature should definitely makes its
> way into PHP!

I remember fixing a bug caused by this.
Bev in TX
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-15 Thread Richard Damon
On 11/15/19 12:21 PM, Random832 wrote:
> On Fri, Nov 15, 2019, at 11:47, Richard Damon wrote:
>> The issue with calling it a Reference, is that part of the meaning of a
>> Reference is that it refers to a Object, and in Python, Names are
>> conceptually something very much different than an Object. Yes, in the
>> implementation details, a name is basically a dictionary entry, so it
>> could be done, the question is should it.
> C# has basically the same issue and does fine calling its thing 'ref'. But 
> that's not really the point - my point was that the concept of being able to 
> have a function change the value of a variable specified by its caller 
> doesn't magically cease being applicable just because the value is a 
> "reference" and the variable is a "name binding".
>
> [Similarly, the fact that values are "references" to mutable objects doesn't 
> mean that python, or Java or C#, isn't call-by-value. The value is the 
> "reference" itself, the fact that it can be used to change data that exists 
> elsewhere is beside the point.]

My understanding is the C# is like the rest of the C* family that
defining a variable x in the code, binds the name x to a specific object
in memory at compile time. That name will ALWAYS refer to that object
and that object can be thought to have that name, and no others in the
same way. The object may be/have a reference to another variable. (C++
references are a bit different at the language level, a reference itself
isn't an object, and taking the address of the reference 'object' give
the address of the object that the reference refers to, C++ references
are still compile time bound to a single object, but that object still
has a concept of the name it was created through) (I will admit that I
don't really know C#, but going from what I understand it as)

This is NOT true in Python. A 'Variable Name' in Python is not
statically bound to given object, but every assignment rebind the name
to object mapping.

Python does NOT use call by value, because a key feature of call by
value is that the value being passed is copied, and the new copy is used
in the subroutine. Name bindings are NOT values, objects have values,
and the value of the object passed is NOT copied to somewhere else. It
is only by misunderstanding the language, and trying to define a name as
being some sort of pointer object that points to the 'real' value of
object that you can create such an idea. This is NOT the model Python is
defined with, and while it might help a bit when starting to understand
how things work, you do need to move from that 'wrong' understanding to
starting to think of it the way Python is defined, or many things in
Python won't make sense.

-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-15 Thread Random832
On Fri, Nov 15, 2019, at 11:47, Richard Damon wrote:
> The issue with calling it a Reference, is that part of the meaning of a
> Reference is that it refers to a Object, and in Python, Names are
> conceptually something very much different than an Object. Yes, in the
> implementation details, a name is basically a dictionary entry, so it
> could be done, the question is should it.

C# has basically the same issue and does fine calling its thing 'ref'. But 
that's not really the point - my point was that the concept of being able to 
have a function change the value of a variable specified by its caller doesn't 
magically cease being applicable just because the value is a "reference" and 
the variable is a "name binding".

[Similarly, the fact that values are "references" to mutable objects doesn't 
mean that python, or Java or C#, isn't call-by-value. The value is the 
"reference" itself, the fact that it can be used to change data that exists 
elsewhere is beside the point.]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-15 Thread Python

Richard Damon wrote:
...

then elsewhere you could do

foo(j)

and after that j is 2

you also could do

foo(1)

and after that if you did

j = 1

then now j might have the value 2 as the constant 1 was changed to the
value 2 (this can cause great confusion)


Wow! So fubar that such a feature should definitely makes its
way into PHP!



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


Re: nonlocal fails ?

2019-11-15 Thread Richard Damon
On 11/15/19 11:26 AM, Dennis Lee Bieber wrote:
> On Fri, 15 Nov 2019 12:56:02 +0100, "R.Wieser" 
> declaimed the following:
>
>> There are quite a number of languages where /every/ type of argument 
>> (including values) can be transfered "by reference".  Though some default to 
>> "by value", where others default to "by reference".
>>
>   Yes -- and in those languages the concept of value vs reference is
> visible at the source code level. In C, everything is passed by value --
> and the programmer uses & to pass (by value) the address of the argument,
> and uses * in the called function to dereference that address back to the
> data item itself. C++ added reference arguments (where the & is used in the
> function declaration) in which the compiler automatically applies the
> "address" and "dereference" operations.

There are languages where pass by reference is the default and not explicit.

I remember in early FORTRAN being able to do something like this (its
been years since I have done this so syntax is probably a bit off)


PROCEDURE foo(i)

i = 2

return


then elsewhere you could do

foo(j)

and after that j is 2

you also could do

foo(1)

and after that if you did

j = 1

then now j might have the value 2 as the constant 1 was changed to the
value 2 (this can cause great confusion)

later I believe they added the ability to specify by value and by
reference, and you weren't allowed to pass constants by reference,

-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-15 Thread Richard Damon
On 11/15/19 11:04 AM, Random832 wrote:
> On Fri, Nov 15, 2019, at 10:48, Richard Damon wrote:
>> On 11/15/19 6:56 AM, R.Wieser wrote:
>>> There are quite a number of languages where /every/ type of argument 
>>> (including values) can be transfered "by reference".  Though some default 
>>> to 
>>> "by value", where others default to "by reference".
>> It seems you are stuck in a programming model different than what Python
>> provides, In a very real sense, the terms call "By Reference" and "By
>> Value" don't apply to Python. Those concepts presume that a variable
>> name represents a bucket of bytes that holds some value, and call by
>> value copies those bytes into a new variable for the subroutine, and
>> call by Reference creates a pointer value back to original value, and
>> all uses of that parameter work indirect that pointer.
>>
>> That is NOT how Python works. In Python, in effect, every name in your
>> code is just a reference which points to some object (This is called
>> binding). Multiple names can point to the same object (or no names, at
>> which point the object is subject to being garbage collected). Names
>> themselves aren't objects, so you can't really make one name refer to
>> another, only to the same object that the other one does. (In actuality,
>> these collections of names are implemented basically in a Dictionary, so
>> using this sort of implementation details you can sort of get that
>> result, but I don't think that is defined to work in the language).
> Being abstractly typed objects rather than a bucket of bytes, and having the 
> values themselves be a kind of reference or pointer (though to immutable data 
> in some important cases), does not in fact change the meaning of the "call by 
> reference" concept or its applicability.
>
> It would be entirely reasonable, I think, in the python model, to provide a 
> way for making a variable a cell variable, passing the cell object around 
> explicitly, and having the called function automatically set/get the value 
> when the argument is accessed. I don't think it would solve the OP's problem, 
> since his talk about automatically "inheriting" the caller's variable of the 
> same name sounds a lot more like dynamic scope than call by reference.

It isn't hard to explicitly do this in Python. The caller just puts it
value into a 1 element list, and then the called function mutates that
list (setting parm[0] instead of parm). This appears to align with
standard Python idioms.

The issue with calling it a Reference, is that part of the meaning of a
Reference is that it refers to a Object, and in Python, Names are
conceptually something very much different than an Object. Yes, in the
implementation details, a name is basically a dictionary entry, so it
could be done, the question is should it.

I have learned many computer languages over the years, and can say that
while figuring out how to map constructs from one language to another
has some value to start, you really do want to learn how the language
really working in itself. There is an old saying that you can write
FORTRAN in any language, and in a real sense it is true, and applies to
many languages. In a general sense you can generally take a programming
style from language X, and use it in language Y, and often be able to
get a 'working' and 'valid' program, but your really should be using
language X structures and use them in language X, write language Y using
the normal style for language Y.

In general, if you want to write a 'x' program, use language x, not
language y. The major exception is if language x isn't available on the
platform, but Python is usually the fallback language to go to, that
will more likely be C or C++ as those are what are most often the first
languages that are brought to a platform. (So maybe learning how to
write Python is C is useful, but writing C in Python has less need),

-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-15 Thread Michael Torrie
On 11/15/19 5:28 AM, R.Wieser wrote:
> :-)  Although that is how we humans remember the effect of what we do, there 
> is no reason for a programming language to do it exactly like that.  And 
> sometimes they don't.

So, in effect he's saying not all languages use the classic variable
model, which you then agree with but then go on to insist that there
must be a way in Python to implement the classic, traditional language
variable model?  I don't understand your point.

> Which you can find back in any language which allows a "by reference" 
> passing of arguments to a procedure (and do remember how strings are often 
> /only/ passed as such).The caller often uses one name for the "value" 
> passed as an argument but in the procedure uses a different one - both 
> accessing the same contents.

Again, which isn't Python.  And come to that such mechanisms should be
used sparingly in languages which offer/require them.

> With some variation of "simple" I guess. :-)
> 
> Personally I think I would sooner go for a single-element tuple.

To each his own.  I rather suspect Python is not a good a fit for you.

Quite a few folks here have showed a lot of patience with your
questions, and posted very insightful and educational comments, which is
a part of the list that I enjoy very much and learn a great deal from.
But you seem to unwilling to internalize any of it.

However, I appreciate that you have kept the tone civil and polite.
Thank you.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-15 Thread Random832
On Fri, Nov 15, 2019, at 10:48, Richard Damon wrote:
> On 11/15/19 6:56 AM, R.Wieser wrote:
> > There are quite a number of languages where /every/ type of argument 
> > (including values) can be transfered "by reference".  Though some default 
> > to 
> > "by value", where others default to "by reference".
> 
> It seems you are stuck in a programming model different than what Python
> provides, In a very real sense, the terms call "By Reference" and "By
> Value" don't apply to Python. Those concepts presume that a variable
> name represents a bucket of bytes that holds some value, and call by
> value copies those bytes into a new variable for the subroutine, and
> call by Reference creates a pointer value back to original value, and
> all uses of that parameter work indirect that pointer.
> 
> That is NOT how Python works. In Python, in effect, every name in your
> code is just a reference which points to some object (This is called
> binding). Multiple names can point to the same object (or no names, at
> which point the object is subject to being garbage collected). Names
> themselves aren't objects, so you can't really make one name refer to
> another, only to the same object that the other one does. (In actuality,
> these collections of names are implemented basically in a Dictionary, so
> using this sort of implementation details you can sort of get that
> result, but I don't think that is defined to work in the language).

Being abstractly typed objects rather than a bucket of bytes, and having the 
values themselves be a kind of reference or pointer (though to immutable data 
in some important cases), does not in fact change the meaning of the "call by 
reference" concept or its applicability.

It would be entirely reasonable, I think, in the python model, to provide a way 
for making a variable a cell variable, passing the cell object around 
explicitly, and having the called function automatically set/get the value when 
the argument is accessed. I don't think it would solve the OP's problem, since 
his talk about automatically "inheriting" the caller's variable of the same 
name sounds a lot more like dynamic scope than call by reference.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-15 Thread Michael Torrie
On 11/15/19 4:56 AM, R.Wieser wrote:
>> Well I've only seen this done in languages where other mechanisms
>> for returning complex types are not present.
> 
> :-) Than you have not seen to many languages I'm afraid.

Careful there.


> If I would have wanted that, why would I post here with open questions ? 
> But yes, I often refer to how other languages work, in an attempt to get the 
> other to tell me whats so special/different about the current languages 
> solution for it.

Yes you can learn a certain amount about a language by doing such 1:1
transliteration exercises.  But you can only go so far.  For example
you'll never master such powerful concepts as generators, closures, list
comprehensions, and so forth by doing this.

I've found a far better way is to do a project in a language, either
something you've done already in another language, or something new.
Instead of doing a low-level transliteration, look at the problem at the
high level, and find out how the language at hand best works to solve
the problem. That's why I and others asked what problem you're trying to
solve.

Also you seem to be comparing traditional, compiled with statically- but
often weakly-typed languages such as C, C++, Pascal, etc, with Python,
which is an interpreted, dynamically-typed language. They are very
different beasts with different strengths and weaknesses and very
different performance characteristics.

The reason you're getting such push back is that over the years on this
list we've seen dozens of new users arrive at Python but never really
learn how to program in Python.  These users insisted on coding in Java,
C#, or C++ (or whatever) in Python.  Some resist strongly when we
suggest this is a recipe for failure.  It was an exercise in frustration
and most of them left thinking what a horrible, limited language Python
is, and unable to understand what makes Python so productive,
expressive, and powerful.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-15 Thread Richard Damon
On 11/15/19 6:56 AM, R.Wieser wrote:
> There are quite a number of languages where /every/ type of argument 
> (including values) can be transfered "by reference".  Though some default to 
> "by value", where others default to "by reference".

It seems you are stuck in a programming model different than what Python
provides, In a very real sense, the terms call "By Reference" and "By
Value" don't apply to Python. Those concepts presume that a variable
name represents a bucket of bytes that holds some value, and call by
value copies those bytes into a new variable for the subroutine, and
call by Reference creates a pointer value back to original value, and
all uses of that parameter work indirect that pointer.

That is NOT how Python works. In Python, in effect, every name in your
code is just a reference which points to some object (This is called
binding). Multiple names can point to the same object (or no names, at
which point the object is subject to being garbage collected). Names
themselves aren't objects, so you can't really make one name refer to
another, only to the same object that the other one does. (In actuality,
these collections of names are implemented basically in a Dictionary, so
using this sort of implementation details you can sort of get that
result, but I don't think that is defined to work in the language).

In the more classical languages, to draw a model of the variables you
have in memory, you take a big sheet of paper, put down each variable
name, and next to it a box where you put what value is stored in the
variable, and that value is intimately associated with that variable
name. You might have some objects being or containing
pointers/references and in that case you can represent it by an arrow
from the box representing the pointer to the object it is pointing to.
There may be some object that are created without a name (like on the
heap), but many of the objects are directly tied to a name.

In Python you do this differently. On one side of your paper, you put
your variable names, and on the other (perhaps a larger side) all the
values/objects you are working with. Each name gets an arrow to an
object to show what object it is currently bound to. Objects store the
values they hold, and some, like collections) also have arrows to other
objects they reference. An arrow always points to an object, never to a
name on the left side.

An assignment just changes what object a reference points to. If it is a
'top level' name being assigned to (as opposed to referring to a member
of an object or element of a collection), that is changing one of the
names on the left side of the page.

This difference in value model means you have to think about things
differently, and in a very real sense makes the terms 'by value' and 'by
reference' not applicable. You don't get values 'By Value', because you
didn't get a copy of the object reference, so if you mutate it, the
caller sees the change, but also it isn't by reference, as you can't
rebind the callers reference to point to a different object. This isn't
'Wrong' just 'Different'.

It takes some getting used to a different model, and I think it helps to
accept that it is different rather than trying to keep trying to
translate how Python does things into how some other language does it,
as the latter make you focus on the things it can't do, not the things
it can.

-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-15 Thread R.Wieser
Pieter,

> Do you mean, if Proc1() is called from Func1, it uses MyVar defined
>in Func1, and if it is called from Func2, it uses MyVar from Func2?

Yep.

> If that is what you mean, that would be dynamic scope.

Thanks for pointing that out (I've learned a new definition today! :-) ).

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-15 Thread R.Wieser
Dennis,

> The first thing one needs to learn is that Python does NOT follow the
> common post-office mailbox concept where
>
> x = y
>
> means the /value/ stored at location identified by "y" is /copied/ to the
> location identified by "x".

:-)  Although that is how we humans remember the effect of what we do, there 
is no reason for a programming language to do it exactly like that.  And 
sometimes they don't.

> means /find/ the object (somewhere in memory) that has a note "y"
> stuck to it. Without moving the "y" note, attach an "x" note to that
> same object.

Which you can find back in any language which allows a "by reference" 
passing of arguments to a procedure (and do remember how strings are often 
/only/ passed as such).The caller often uses one name for the "value" 
passed as an argument but in the procedure uses a different one - both 
accessing the same contents.

> In software engineering as I learned it, it is preferable to decouple

... not because its so good for us humans, but that way you can 
mathematically prove that the finished program should work as designed.

... which some languages (mostly the ones which allow only single results 
returned from a function) are starting to turn back from (allowing "by 
reference" access back in - its just too damn usefull).

> All depends upon the scope of those procedures.

I have no idea which circumstances you're hinting at.   But just take it 
that the scope is local - apart from that externally referenced value 
ofcourse.

> The simplest is to use a mutable object as a container at the
> module level.

With some variation of "simple" I guess. :-)

Personally I think I would sooner go for a single-element tuple.

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-15 Thread Chris Angelico
On Fri, Nov 15, 2019 at 11:01 PM R.Wieser  wrote:
>
> As for "complex types" ?   I don't think a(n ASCII) string can be considered
> any kind of a complex type, but most all languages I know of transfer them
> "by reference" only (though some fake "by value" by using a copy-on-write
> mechanism).

"Pass by value" and "pass by reference" become largely irrelevant when
your strings are immutable objects; so I would say that a large number
of languages have broadly "pass-by-value" semantics for strings,
treating them as first-class objects that are defined by value, not
identity.

> > In C you can either return a pointer to the string (and remember who's
> > responsibility it is to free the memory!), or you can allocate memory
> > yourself and pass the pointer to a function, like strcpy.
>
> Or pass a reference to an empty pointer, have the procedure allocate the
> memory and return the address of it in that pointer.

I don't know why you'd do that rather than simply return the new
pointer, but whatever. It's still a lot clunkier than simply returning
a string, which is what happens in all sane high-level languages.

> > In Python there is no similar equivalent,
>
> It looks like it
>
> > other than hacks involving passing in mutable objects
>
> The only "hack" I see here is to transfer /mutable/ object, instead of a
> non-mutable one.

Yes, Python has no concept of pass-by-reference. Python *always*
passes objects around, not variables. But everything that you could do
with "pass by reference" can be done by passing a mutable object, and
everything that you could do by passing mutable objects around can be
done by passing pointers to data structures, or (equivalently) passing
data structures by reference. There's no real difference.

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


Re: nonlocal fails ?

2019-11-15 Thread Chris Angelico
On Fri, Nov 15, 2019 at 9:16 PM R.Wieser  wrote:
>
> Chris,
>
> > That doesn't really answer the question.
>
> The problem is that you want to solve /this/ problem, while I'm looking for
> replies that are applicable to similar ones too.
>
> To be blunt about it: I consider solutions that only solve a single problem
> most always as a waste of my time (exceptions to the rule, yadayadayada).
> Solutions that I can expand and build upon are the ones I'm looking for
> (read: learn from).
>
> But as lot of people will respond like you and than pick something from the
> /supporting information/ and go off on a tangent with it that doesn't aim to
> answer /my/ question I have become rather carefull about what I post in
> regard to specifics.
>
> > The point of your new car isn't to push the pedal - it's to get you some
> > place.
>
> And thats your problem in a nutshell: You think in forms of "get you some
> place".
>
> What about just /learning how to drive/ ?
>

The purpose of a car is not to learn how to ride a bicycle. Yes, I am
thinking in terms of an ultimate goal, because the point of coding is
to achieve something. Maybe your goal *right now* is to learn rather
than to create, but surely the purpose of the learning is to be able
to achieve things later?

Rather than try to implement pass-by-reference semantics in Python,
figure out what abstract concept you're actually trying to implement.
Otherwise, all you'll do is come up with convoluted methods of
implementing some other language's semantics in Python, and then write
your code using that other language's idioms, and run it in a Python
interpreter. Far better to actually learn Python's semantics, and how
they can be used to represent your actual goals.

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


Re: nonlocal fails ?

2019-11-15 Thread R.Wieser
Michael,

> Well I've only seen this done in languages where other mechanisms
>for returning complex types are not present.

:-) Than you have not seen to many languages I'm afraid.

There are quite a number of languages where /every/ type of argument 
(including values) can be transfered "by reference".  Though some default to 
"by value", where others default to "by reference".

As for "complex types" ?   I don't think a(n ASCII) string can be considered 
any kind of a complex type, but most all languages I know of transfer them 
"by reference" only (though some fake "by value" by using a copy-on-write 
mechanism).

> In C you can either return a pointer to the string (and remember who's
> responsibility it is to free the memory!), or you can allocate memory
> yourself and pass the pointer to a function, like strcpy.

Or pass a reference to an empty pointer, have the procedure allocate the 
memory and return the address of it in that pointer.

And only the second one comes near to what I indicated I asked about: a 
mutable value stored outside the current procedure.

> In Python there is no similar equivalent,

It looks like it

> other than hacks involving passing in mutable objects

The only "hack" I see here is to transfer /mutable/ object, instead of a 
non-mutable one.

> Fair enough, but trying to do 1:1 transliterations isn't going to
> help you learn idiomatic Python.

If I would have wanted that, why would I post here with open questions ? 
But yes, I often refer to how other languages work, in an attempt to get the 
other to tell me whats so special/different about the current languages 
solution for it.

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-15 Thread R.Wieser
Terry,

> This is discouraged for anything very complex.

Complex things do not exist.  If you think you have something like it you've 
just not yet broken it down in its components yet. :-)

> This is the standard way in Python and other OO languages.  By 'excluded', 
> do you mean 'rejected', or 'tried that, what else is there?'

The latter.  Although I've pretty-much rejected the "global" method.

> Closures are standard in functional languages and are less limited than 
> you seem to think.

I was talking about the "nonlocal" method of variable inheritance, not 
closures.   I'm not going to comment (much) on the latter until I've had a 
chance to play with them.

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-15 Thread R.Wieser
Chris,

> That doesn't really answer the question.

The problem is that you want to solve /this/ problem, while I'm looking for 
replies that are applicable to similar ones too.

To be blunt about it: I consider solutions that only solve a single problem 
most always as a waste of my time (exceptions to the rule, yadayadayada). 
Solutions that I can expand and build upon are the ones I'm looking for 
(read: learn from).

But as lot of people will respond like you and than pick something from the 
/supporting information/ and go off on a tangent with it that doesn't aim to 
answer /my/ question I have become rather carefull about what I post in 
regard to specifics.

> The point of your new car isn't to push the pedal - it's to get you some 
> place.

And thats your problem in a nutshell: You think in forms of "get you some 
place".

What about just /learning how to drive/ ?

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-15 Thread Antoon Pardon
On 14/11/19 18:46, R.Wieser wrote:
> Jan,
>
>> So what you want to do is dynamic scope?
> No, not really.I was looking for method to let one procedure share a 
> variable with its caller - or callers, selectable by me.   And as a "by 
> reference" argument does not seem to exist in Python ...

If you start thinking about what kind of argument passing mechanisme
Python has,
you should first think about what kind of assignment semantics Python has.

In some sense all parameter passing in Python is by reference, but it is
the assignment
semantics that cause it to not have the effect people expect.

The preffered terminology is call by sharing, but if you mutate the
parameter it has the
same effect as call by reference.

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


Re: nonlocal fails ?

2019-11-15 Thread Pieter van Oostrum
"R.Wieser"  writes:

> Jan,
>
>> So what you want to do is dynamic scope?
>
> No, not really.I was looking for method to let one procedure share a 
> variable with its caller - or callers, selectable by me.   And as a "by 
> reference" argument does not seem to exist in Python ...
>
> And yes, I am a ware that procedures can return multiple results.  I just 
> didn'want to go that way (using the same variable twice in a single 
> calling).

Do you mean, if Proc1() is called from Func1, it uses MyVar defined in Func1, 
and if it is called from Func2, it uses MyVar from Func2?

If that is what you mean, that would be dynamic scope.
-- 
Pieter van Oostrum 
WWW: http://pieter.vanoostrum.org/
PGP key: [8DAE142BE17999C4]
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread Richard Damon
On 11/14/19 12:57 PM, R.Wieser wrote:
> Michael,
>
>> nonlocal does not share or use its *caller's* variables.  Rather it
>> reaches into the scope of the outer function where it was defined.
>> That's a very different concept than what you're proposing.
> Oh blimy!   You're right.Its an at compile-time thing, not a runtime 
> one.
>
> Thanks for the heads-up.
>
>> I know of no sane way that a function could work with the scope of
>> any arbitrary caller.
> The trick seems to be to emulate a "by reference" call, by using a mutable 
> object as the argument and stuff the value inside of it (IIRC a tuple with a 
> single element).

tuples are immutable, use a list or a dictionary.

>> What would happen if the caller's scope didn't have any
>> names that the function was looking for?
> Handle it the same as any other mistake, and throw an error ?
>
> Regards,
> Rudy Wieser
>
>

-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-14 Thread Richard Damon
On 11/14/19 1:43 PM, R.Wieser wrote:
> Richard,
>
>> Assuming that one language works like another is a danger
> Abitrarily redefining words and using misnomers is another ...  ("global" 
> and "nonlocal" respecivily if you wonder)
>
>> First, Python doesn't really have 'Variables' like a lot of other 
>> languages
>> (they don't hold a bag of bytes), as Python names don't hold values, but
>> are just references to objects which actually hold the value
> That's a principle as old as programming languages itself I believe.

There are at least two very different concepts that act like variables
in different languages. In a language like C, a variable is a 'bucket of
byte' that holds some value. If you assign the value of one variable to
another, that byte pattern is copied from one to another. That
representation might include a pointer to some other block (a pointer or
reference), but generally this is something explicit. In this sort of
language your names represent variables that actually hold values.

In Python, the name for your 'variable' doesn't actually hold the value
that is assigned to it, but instead the bucket of bytes associated with
the name is ALWAYS a pointer to a bucket of bytes that represents the
value. Multiple names are allowed to point to the same value object, so
assigning one name to another just copies that pointer, and they share
the same value object. You shouldn't really think of names as holding
'values' but the names are 'bound' to the value objects (which aren't
tied to a given name).

>
>> If the name is never bound to something, then the name will be also looked
>> for in the global namespace.
> Can you give an example of that ?I currently cannot wrap my head around 
> what you could be meaning there - anything I can imagine simply doesn't make 
> any sense ...
>
> Regards,
> Rudy Wieser
>
#This Function creates a local name and updates it. str will be created
locally and looked up locally

def useslocal():

    str = "String"

    str = str + " Added"


gstr = "Global"

# This function never binds a value to gstr, so it will look in the
'global' space to find the name

def useglobal():

   str = gstr + " Seen"


# This function include a binding to gstr, so it is only looked for
locally,

#so this use will create an error that it can't find gstr,

# even though it was defined in the global name space

def getserror():

    str = gstr + " Error"

    gstr = str

# This works because of the global statement, and updates the global

def workingglobal():

    global gstr

    str = gstr + " Error"

    gstr = str


-- 
Richard Damon

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


Re: nonlocal fails ?

2019-11-14 Thread Michael Torrie
On 11/14/19 2:16 PM, R.Wieser wrote:
> I think I did - though implicitily.   What do normal people use "by 
> reference" arguments for ?   Yep, that is what I wanted too.

Well I've only seen this done in languages where other mechanisms for
returning complex types are not present. For example in C.  Chris talked
about dealing with languages where strings are not first-class citizens,
for example.  In C you can either return a pointer to the string (and
remember who's responsibility it is to free the memory!), or you can
allocate memory yourself and pass the pointer to a function, like strcpy.

In Python there is no similar equivalent, other than hacks involving
passing in mutable objects and using those objects to save the state.
State is maintained either by returning everything from the function you
need to maintain state (in a tuple, for example), or by using OOP.
Another mechanism Python has for doing certain types of state keeping
between calls is the generator idea.

> I'm trying to learn how Python works, and for that I (ofcourse) compare it 
> to other languages.   What-and-how it does something different (or equal!) 
> in regard to them.

Fair enough, but trying to do 1:1 transliterations isn't going to help
you learn idiomatic Python.


> 1) Have value
> 2) use value in procedure 1
> 3) use updated value in procedure 2
> 4) use again updated value in procedure 1, 2 or maybe 3

A clear case for using an object and placing your procedures as methods
to the object.  Everything in Python is OO under the hood, even if you
are not forced to use a particular paradigm.  Even a module is an
object.  It's a sort of singleton really.  functions are like a static
method in other languages.  The beauty of Python's organization, though,
is you don't have to use a forced class structure as your namespace.
Modules and packages provide a nicer namespace than Java or C#'s method.
 But I digress.

> For the sake of learning I'm now going over all of the possibilities to see 
> if and how they work.  For that I've already excluded globals and the 
> practice of feeding the value as an argument to the procedure and than store 
> its result as the new one.  I've also excluded using a class object and put 
> the code in there, as well as faking a "by reference" passing by using a 
> tuple.   "nonlocal" looked to be another option, but it appears to be rather> 
> limited in its application.

Well be sure to add Python's classes and objects to your list of
possibilities.  And also explore generators (coroutines).


> In short, the /ways to the goal/ are (currently) important to me, not the 
> goal itself (I'm sure that apart from the "nonlocal" one all of the above 
> are viable, and I thus can get /something/ to work)
> 
> Yeah, I'm weird like that.  Sorry.

Okay I just was wondering if there is a particular task at hand.  Often
that's the best way to learn a language. You have a specific task you
want to accomplish, or program you need to write, and then find out the
best way to do it within the abilities and strengths of the language.

Years ago I was taught Prolog and man I fought that language because I
never really grasped the concepts and wanted to program in C or Pascal
instead of Prolog.  If I knew then what I know now I would have probably
had an easier time of it.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread Terry Reedy

On 11/14/2019 4:16 PM, R.Wieser wrote:


If you mentioned what problem you are trying to solve


1) Have value
2) use value in procedure 1
3) use updated value in procedure 2
4) use again updated value in procedure 1, 2 or maybe 3



For the sake of learning I'm now going over all of the possibilities to see
if and how they work.

 >  For that I've already excluded globals and the

practice of feeding the value as an argument to the procedure and than store
its result as the new one.


This is discouraged for anything very complex.


I've also excluded using a class object and put
the code in there,


This is the standard way in Python and other OO languages.  By 
'excluded', do you mean 'rejected', or 'tried that, what else is there?'



as well as faking a "by reference" passing by using a tuple.


One has to pass a mutable, such as list, set, dict, or user class instance.

"nonlocal" looked to be another option, but it appears to be rather

limited in its application.


Closures are standard in functional languages and are less limited than 
you seem to think.  But you have to enclose (nest) many or all of the 
functions that directly rebind 'val' (else one might as well use a 
global value).


def valclass(val):
def set(newval):  # For functions not defined within valclass.
nonlocal val
val = newval
def get()
return val
def proc1(args)
nonlocal val
...
dev proc2(args)
nonlocal val
...
return setval, getval, proc1, proc2
# return {'set':set, 'get':get, 'proc1':proc1, 'proc2':proc2}

setval, getval, proc1, proc2 = valclass(3)
# val = valclass(3)


In short, the /ways to the goal/ are (currently) important to me, not the
goal itself (I'm sure that apart from the "nonlocal" one all of the above
are viable, and I thus can get /something/ to work)



--
Terry Jan Reedy

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


Re: nonlocal fails ?

2019-11-14 Thread Chris Angelico
On Fri, Nov 15, 2019 at 8:21 AM R.Wieser  wrote:
>
> Michael,
>
> > I note that you didn't answer the question, what are you trying
> > to accomplish?
>
> I think I did - though implicitily.   What do normal people use "by
> reference" arguments for ?   Yep, that is what I wanted too.
>

That doesn't really answer the question. It's like you just bought a
self-driving car and then ask people how you push the accelerator
pedal. What are you trying to do? Well, what normal people use the
accelerator pedal for! Only, that's irrelevant. The point of your new
car isn't to push the pedal - it's to get you some place. Where are
you trying to get to?

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


Re: nonlocal fails ?

2019-11-14 Thread R.Wieser
Michael,

> I note that you didn't answer the question, what are you trying
> to accomplish?

I think I did - though implicitily.   What do normal people use "by 
reference" arguments for ?   Yep, that is what I wanted too.

> It looks to me like you're trying to write a program in a different
> language here, not Python.

I'm trying to learn how Python works, and for that I (ofcourse) compare it 
to other languages.   What-and-how it does something different (or equal!) 
in regard to them.

>Although come to that I can't think of very many reasons to do
> what you propose in any language.

I made propositions to its functioning ?And I was thinking that I just 
pointed out oddities in it ...

> If you mentioned what problem you are trying to solve

1) Have value
2) use value in procedure 1
3) use updated value in procedure 2
4) use again updated value in procedure 1, 2 or maybe 3

For the sake of learning I'm now going over all of the possibilities to see 
if and how they work.  For that I've already excluded globals and the 
practice of feeding the value as an argument to the procedure and than store 
its result as the new one.  I've also excluded using a class object and put 
the code in there, as well as faking a "by reference" passing by using a 
tuple.   "nonlocal" looked to be another option, but it appears to be rather 
limited in its application.

In short, the /ways to the goal/ are (currently) important to me, not the 
goal itself (I'm sure that apart from the "nonlocal" one all of the above 
are viable, and I thus can get /something/ to work)

Yeah, I'm weird like that.  Sorry.

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-14 Thread Chris Angelico
On Fri, Nov 15, 2019 at 7:19 AM Michael Torrie  wrote:
>
> On 11/14/19 10:57 AM, R.Wieser wrote:
> >> I know of no sane way that a function could work with the scope of
> >> any arbitrary caller.
> >
> > The trick seems to be to emulate a "by reference" call, by using a mutable
> > object as the argument and stuff the value inside of it (IIRC a tuple with a
> > single element).
>
> Right. You could pass in a dict as an argument. You could even pass in
> the caller's locals() dictionary.  I'm not sure I recommend the latter
> approach, however.

The locals() dict isn't guaranteed to be mutable. At the moment, there
are very very few actual language guarantees regarding changes to
locals(), but there's currently a WIP to define things a little more
tightly:

https://www.python.org/dev/peps/pep-0558/

Neither in the current wording nor in the proposed wording is any sort
of promise that you could pass locals() to another function and have
it usefully modify that.

> I'm coming more and more around to some of the ideas of functional
> programming.  Doing as you suggest, reaching back to the caller's
> variables, sounds extremely messy to me.  And very fragile, hard to
> test, and doesn't lend itself to easily extended functionality by
> chaining(think unix-style piping).
>
> I find Python's ability to return tuples virtually eliminates any need I
> have to "pass by reference."

Agreed. Or Python's ability to return strings. Most of the
pass-by-reference that I do in languages like SourcePawn is just to
get around the problem that strings aren't first-class values.

> I'm coming around to the idea that wherever possible, functions should
> have no side effects.  Those things that need side effects should be
> isolated so they are easy to maintain.  I believe they call this "push
> side effects to the edges."

Something like that. Ideally, a function should be pure - having no
side effects, being unaffected by external state, and having a return
value determined entirely by its arguments. Not every function can be
pure, of course (for instance, print() is most certainly NOT a pure
function), but the more of your functions that are pure, and the purer
your other functions are, the easier it is to reason about your code
and refactor things.

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


Re: nonlocal fails ?

2019-11-14 Thread Michael Torrie
On 11/14/19 10:57 AM, R.Wieser wrote:
> The trick seems to be to emulate a "by reference" call, by using a mutable 
> object as the argument and stuff the value inside of it (IIRC a tuple with a 
> single element).

I note that you didn't answer the question, what are you trying to
accomplish? In other words, what problem are you trying to solve.  It
looks to me like you're trying to write a program in a different
language here, not Python.  Although come to that I can't think of very
many reasons to do what you propose in any language.

If you mentioned what problem you are trying to solve, I'm sure folks
can suggest cleaner, more idiomatic ways of doing it in Python.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread Michael Torrie
On 11/14/19 10:57 AM, R.Wieser wrote:
>> I know of no sane way that a function could work with the scope of
>> any arbitrary caller.
> 
> The trick seems to be to emulate a "by reference" call, by using a mutable 
> object as the argument and stuff the value inside of it (IIRC a tuple with a 
> single element).

Right. You could pass in a dict as an argument. You could even pass in
the caller's locals() dictionary.  I'm not sure I recommend the latter
approach, however.

> Handle it the same as any other mistake, and throw an error ?

Sure.

I'm coming more and more around to some of the ideas of functional
programming.  Doing as you suggest, reaching back to the caller's
variables, sounds extremely messy to me.  And very fragile, hard to
test, and doesn't lend itself to easily extended functionality by
chaining(think unix-style piping).

I find Python's ability to return tuples virtually eliminates any need I
have to "pass by reference."

I'm coming around to the idea that wherever possible, functions should
have no side effects.  Those things that need side effects should be
isolated so they are easy to maintain.  I believe they call this "push
side effects to the edges."
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread Terry Reedy

On 11/14/2019 12:53 PM, Richard Damon wrote:


On Nov 14, 2019, at 12:20 PM, R.Wieser  wrote:

MRAB,


'nonlocal' is used where the function is nested in another function


The problem is that that was not clear to me from the description - nor is
it logical to me why it exludes the main context from its use.

Regards,
Rudy Wieser


Module ‘main’ content is already available via ‘global’, nonlocal was likely 
added later to get to enclosing function scope, which isn’t global, nor is it 
local.


Correct, and the addition was in two stages.  At first, automatically 
*accessing* non-locals was added.  Note that no declaration is needed, 
just as no declaration is needed to access globals.


>>> >>> f(3)
3

The 'nonlocal' keyward to *rebind* nonlocals, analogous to the 'global' 
keyword to rebind module globals, was added later, for 3.0, after 
considerable bikeshedding  on the new keyword.


The access mechanism is quite different.  Function f accesses globals 
through f.__globals__, which points to the global dict.  In CPython, at 
least, it accesses nonlocals through f.__closure__, a tuple of 'cells'.


>>> def f(a):
b = 'b outer'
def g():
nonlocal b
print(a, b)
b = 'b inner'
print(a, b)
print(g.__closure__)
g()


>>> f(0)
(, at 0x0277AAAF7880: str object at 0x0277AAB0DAB0>)

0 b outer
0 b inner
>>> print(f.__closure__)
None

Closures are used in functional programs, instead of classes, to create 
'groups' of functions than share 'group' variables.


--
Terry Jan Reedy


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


Re: nonlocal fails ?

2019-11-14 Thread Chris Angelico
On Fri, Nov 15, 2019 at 5:46 AM R.Wieser  wrote:
>
> Richard,
>
> > Assuming that one language works like another is a danger
>
> Abitrarily redefining words and using misnomers is another ...  ("global"
> and "nonlocal" respecivily if you wonder)

Every language that has a concept of "global" still has some sort of
limitation on it. If you look up that word in a dictionary, it won't
say "within the currently-running program" or anything. Yet, we
programmers are quite happy for global variables in one program to be
isolated from another - in fact, I think you'd be seriously
disconcerted if that were NOT the case. Is that "arbitrarily
redefining" the word global?

> > First, Python doesn't really have 'Variables' like a lot of other
> > languages
> > (they don't hold a bag of bytes), as Python names don't hold values, but
> > are just references to objects which actually hold the value
>
> That's a principle as old as programming languages itself I believe.

True, and it's also largely irrelevant here, so let's move on.

> > If the name is never bound to something, then the name will be also looked
> > for in the global namespace.
>
> Can you give an example of that ?I currently cannot wrap my head around
> what you could be meaning there - anything I can imagine simply doesn't make
> any sense ...
>

def foo():
x = 1
print("x is", x)

Inside this function, you have one local name (x), and one name
reference that isn't local (print). When the function looks for print,
it looks in the globals, and then in the built-ins.

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


Re: nonlocal fails ?

2019-11-14 Thread R.Wieser
Richard,

> Assuming that one language works like another is a danger

Abitrarily redefining words and using misnomers is another ...  ("global" 
and "nonlocal" respecivily if you wonder)

> First, Python doesn't really have 'Variables' like a lot of other 
> languages
> (they don't hold a bag of bytes), as Python names don't hold values, but
> are just references to objects which actually hold the value

That's a principle as old as programming languages itself I believe.

> If the name is never bound to something, then the name will be also looked
> for in the global namespace.

Can you give an example of that ?I currently cannot wrap my head around 
what you could be meaning there - anything I can imagine simply doesn't make 
any sense ...

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-14 Thread Richard Damon

> On Nov 14, 2019, at 12:56 PM, R.Wieser  wrote:
> 
> Jan,
> 
>> So what you want to do is dynamic scope?
> 
> No, not really.I was looking for method to let one procedure share a 
> variable with its caller - or callers, selectable by me.   And as a "by 
> reference" argument does not seem to exist in Python ...
> 
> And yes, I am a ware that procedures can return multiple results.  I just 
> didn'want to go that way (using the same variable twice in a single 
> calling).
> 
> Regards,
> Rudy Wieser

Watch out about thinking about ‘Variables’ because Python doesn’t really have 
them. In one sense EVERYTHING in Python is by reference, as names are just 
references bound to objects.

If you are pass a mutable object to a function, and the function uses the 
parameter that was bound to the object to mutate the object, that same object 
referenced in the caller has changed. (Note that strings, number, and tupples 
are not mutable, but lists, dictionaries and most class objects are).

The key is that the function should use assignment to the parameter name to try 
and change the object, but use mutating methods on the object to change it.

Thus if the caller creates a list and binds it to a name, and passes that to 
the function, then the function can manipulate the list (things like parm[0] = 
5) and that change will be see by the caller. The function just needs to be 
careful not to do a parm = statement that would rebind the name and thus lose 
the reference to the callers object.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread Rhodri James

On 14/11/2019 17:11, R.Wieser wrote:

Rhodri,


MyVar is a global here, so nonlocal explicitly doesn't pick it up.

I do not agree with you there (the variable being global).  If it where than
I would have been able to alter the variable inside the procedure without
having to resort to a "global" override (an override which is only valid for
the context its used in by the way, not anywhere else)

Than again, that is how it works in a few other languages, so I might have
been poisonned by them.:-)


You have been.

  # This is at the top level of a module
  # I.e. it's a global variable
  my_global_variable = 5

  # You can read globals from within a function without declaring them
  def show_my_global():
print(my_global_variable)

  # If you try setting it, you get a local instead
  def fudge_my_global(n):
my_global_variable = n

  show_my_global()  # prints '5'
  fudge_my_global(2)
  show_my_global()  # prints '5'

  # If you read the variable before setting it, you get an exception
  def mess_up_my_global(n):
print(my_global_variable)
my_global_variable = n

  mess_up_my_global(2) # UnboundLocalError!

  # ...because it must be a local because of the assignment, but it
  # doesn't have a value at the time print() is called.

  # To do it right, declare you want the global from the get go
  def love_my_global(n):
global my_global_variable
print("It was ", my_global_variable)
my_global_variable = n

  love_my_global(3) # prints 'It was 5'
  show_my_global()  # prints '3'

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


Re: nonlocal fails ?

2019-11-14 Thread R.Wieser
Michael,

> nonlocal does not share or use its *caller's* variables.  Rather it
> reaches into the scope of the outer function where it was defined.
> That's a very different concept than what you're proposing.

Oh blimy!   You're right.Its an at compile-time thing, not a runtime 
one.

Thanks for the heads-up.

> I know of no sane way that a function could work with the scope of
> any arbitrary caller.

The trick seems to be to emulate a "by reference" call, by using a mutable 
object as the argument and stuff the value inside of it (IIRC a tuple with a 
single element).

> What would happen if the caller's scope didn't have any
> names that the function was looking for?

Handle it the same as any other mistake, and throw an error ?

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-14 Thread Richard Damon
> 
> On Nov 14, 2019, at 12:20 PM, R.Wieser  wrote:
> 
> MRAB,
> 
>> 'nonlocal' is used where the function is nested in another function
> 
> The problem is that that was not clear to me from the description - nor is 
> it logical to me why it exludes the main context from its use.
> 
> Regards,
> Rudy Wieser

Module ‘main’ content is already available via ‘global’, nonlocal was likely 
added later to get to enclosing function scope, which isn’t global, nor is it 
local.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread R.Wieser
Jan,

> So what you want to do is dynamic scope?

No, not really.I was looking for method to let one procedure share a 
variable with its caller - or callers, selectable by me.   And as a "by 
reference" argument does not seem to exist in Python ...

And yes, I am a ware that procedures can return multiple results.  I just 
didn'want to go that way (using the same variable twice in a single 
calling).

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-14 Thread Richard Damon
On Nov 14, 2019, at 12:18 PM, R.Wieser  wrote:
> 
> Rhodri,
> 
>> MyVar is a global here, so nonlocal explicitly doesn't pick it up.
> 
> I do not agree with you there (the variable being global).  If it where than 
> I would have been able to alter the variable inside the procedure without 
> having to resort to a "global" override (an override which is only valid for 
> the context its used in by the way, not anywhere else)
> 
> Than again, that is how it works in a few other languages, so I might have 
> been poisonned by them. :-)
> 
> Regards,
> Rudy Wieser

Assuming that one language works like another is a danger. It really pays to 
learn the base concepts of a language if you are going to be using it.

First, Python doesn’t really have ‘Variables’ like a lot of other languages 
(they don’t hold a bag of bytes), as Python names don’t hold values, but are 
just references to objects which actually hold the value (this can be important 
when several names all reference the same object, that means that if you mutate 
the object through one name they all see the change)

Also, for name lookup, the Python Compiler looks to see if the name is bound to 
an object (via assignment, etc) in the function, if so the name is by default 
local, (changeable by using a global or non local statement). If the name is 
never bound to something, then the name will be also looked for in the global 
namespace.

Yes, this is different than many other languages.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread R.Wieser
MRAB,

> 'nonlocal' is used where the function is nested in another function

The problem is that that was not clear to me from the description - nor is 
it logical to me why it exludes the main context from its use.

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-14 Thread R.Wieser
Rhodri,

> MyVar is a global here, so nonlocal explicitly doesn't pick it up.

I do not agree with you there (the variable being global).  If it where than 
I would have been able to alter the variable inside the procedure without 
having to resort to a "global" override (an override which is only valid for 
the context its used in by the way, not anywhere else)

Than again, that is how it works in a few other languages, so I might have 
been poisonned by them. :-)

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-14 Thread Michael Torrie
On 11/14/19 7:15 AM, R.Wieser wrote:

> Too bad though, it means that procedures that want to share/use its callers 
> variables using nonlocal can never be called from main.  And that a caller 
> of a procedure using nonlocal cannot have the variable declared as global 
> (just tested it).

nonlocal does not share or use its *caller's* variables.  Rather it
reaches into the scope of the outer function where it was defined.
That's a very different concept than what you're proposing.

I know of no sane way that a function could work with the scope of any
arbitrary caller.  Remember that even inner functions can be returned
and called from anywhere, even other functions or modules.  What would
happen if the caller's scope didn't have any names that the function was
looking for?

What are you trying to accomplish?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread Jan Erik Moström

On 14 Nov 2019, at 15:15, R.Wieser wrote:

Too bad though, it means that procedures that want to share/use its 
callers
variables using nonlocal can never be called from main.  And that a 
caller
of a procedure using nonlocal cannot have the variable declared as 
global

(just tested it).


So what you want to do is dynamic scope? 
https://www.geeksforgeeks.org/static-and-dynamic-scoping/


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


Re: nonlocal fails ?

2019-11-14 Thread R.Wieser
Jan,

> The nonlocal statement causes the listed identifiers to refer to 
> previously bound variables in the nearest **enclosing scope excluding 
> globals**.

I read that too, but didn't get from it that the main scope is excluded (I 
assumed the"excluding globals" was ment at as such declared variables) . 
Thanks the clarification.

Too bad though, it means that procedures that want to share/use its callers 
variables using nonlocal can never be called from main.  And that a caller 
of a procedure using nonlocal cannot have the variable declared as global 
(just tested it).

Regards,
Rudy Wieser


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


Re: nonlocal fails ?

2019-11-14 Thread Rhodri James

On 14/11/2019 13:06, R.Wieser wrote:

Hello all,

I've just tried to use a "nonlocal MyVar" statement in a procedure
defenition, but it throws an error saying "Syntax error: no binding for
nonlocal 'MyVar' found.

According to platform.python_version() I'm running version 3.8.3

Why am I getting that error ? (already googeled ofcourse)

Testcode:
- - - - - - - - - - - -
Def Proc1()
 nonlocal MyVar
 MyVar = 5

MyVar = 7
Proc1()
print(MyVar)
- - - - - - - - - - - -
I've also tried moving "MyVar = 7" to the first line, but that doesn't
change anything.  Using "global MyVar" works..


The Language Reference says 
(https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement):


"The nonlocal statement causes the listed identifiers to refer to 
previously bound variables in the nearest enclosing scope *excluding 
globals.*"  (my emphasis.)


MyVar is a global here, so nonlocal explicitly doesn't pick it up.

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


Re: nonlocal fails ?

2019-11-14 Thread MRAB

On 2019-11-14 13:06, R.Wieser wrote:

Hello all,

I've just tried to use a "nonlocal MyVar" statement in a procedure
defenition, but it throws an error saying "Syntax error: no binding for
nonlocal 'MyVar' found.

According to platform.python_version() I'm running version 3.8.3

Why am I getting that error ? (already googeled ofcourse)

Testcode:
- - - - - - - - - - - -
Def Proc1()
 nonlocal MyVar
 MyVar = 5

MyVar = 7
Proc1()
print(MyVar)
- - - - - - - - - - - -
I've also tried moving "MyVar = 7" to the first line, but that doesn't
change anything.  Using "global MyVar" works..


In section 7.13 of the Help it says:

"""The nonlocal statement causes the listed identifiers to refer to 
previously bound variables in the nearest enclosing scope excluding 
globals."""


'nonlocal' is used where the function is nested in another function and 
you want to be able to bind to the variables in the enclosing function.


In your code, there's no enclosing function. Instead, you want to be 
able to bind to the module's global variables. For that, you should use 
'global' instead.


def Proc1():
global MyVar
MyVar = 5

MyVar = 7
Proc1()
print(MyVar)
--
https://mail.python.org/mailman/listinfo/python-list


Re: nonlocal fails ?

2019-11-14 Thread Jan Erik Moström

On 14 Nov 2019, at 14:06, R.Wieser wrote:


I've also tried moving "MyVar = 7" to the first line, but that doesn't
change anything.  Using "global MyVar" works..


Try

def outer():
MyVar = 10
def Proc1():
nonlocal MyVar
MyVar = 5
Proc1()

MyVar = 7
outer()
print(MyVar)

From the documentation

The nonlocal statement causes the listed identifiers to refer to 
previously bound variables in the nearest **enclosing scope 
excluding globals**. This is important because the default behavior 
for binding is to search the local namespace first. The statement allows 
encapsulated code to rebind variables outside of the local scope besides 
the global (module) scope.


Names listed in a nonlocal statement, unlike those listed in a global 
statement, must refer to pre-existing bindings in an enclosing scope 
(the scope in which a new binding should be created cannot be determined 
unambiguously).


Names listed in a nonlocal statement must not collide with pre-existing 
bindings in the local scope.

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


nonlocal fails ?

2019-11-14 Thread R.Wieser
Hello all,

I've just tried to use a "nonlocal MyVar" statement in a procedure 
defenition, but it throws an error saying "Syntax error: no binding for 
nonlocal 'MyVar' found.

According to platform.python_version() I'm running version 3.8.3

Why am I getting that error ? (already googeled ofcourse)

Testcode:
- - - - - - - - - - - -
Def Proc1()
nonlocal MyVar
MyVar = 5

MyVar = 7
Proc1()
print(MyVar)
- - - - - - - - - - - -
I've also tried moving "MyVar = 7" to the first line, but that doesn't 
change anything.  Using "global MyVar" works..

Regards,
Rudy Wieser



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