Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-21 Thread Kirill Balunov
пн, 20 авг. 2018 г. в 17:23, Steven D'Aprano :

> On Sun, Aug 19, 2018 at 06:18:56PM +0300, Kirill Balunov wrote:
> [...]
> [Kirill]
> > Let me disagree with you. While CPython is only one of the
> implementations
> > of the Python language, it is the most common one and defacto is
> considered
> > as a standard.
>
> Not in this case. If CPython intended this to be the language behaviour,
> it should specify that limitation instead of merely giving a doc warning
> that changes "may not" affect the local variables.
>
> In fact, the warning in the docs is too strong. Modifying locals()
> inside a class or module scope is allowed, and works fine. It is only
> functions which is problematic.
>
>
I think I was pretty clear, that I only spoke about `locals` behavior
inside functions and all its derivatives. At least I tried :) Talking about
class and module, as for me, modifying `locals()`
inside a class or module scope is allowed but is far from the right way to
do.

The phrase `may not affect` is the worst phrase for deterministic system.
Your program may work or may not work correctly depending on the underlying
Python implementation, but you would not know about this because there will
be no error and no warning. Good luck fixing such bugs.


>
> > Therefore, all the others, to be compliant, try to replicate
> > all subtleties and features of the basic implementation - CPython.
>
> Implementations are expected to obey the documented behaviour (unless
> given special dispensation to break the rules, which I think has
> happened once or twice with MicroPython). For behaviour which isn't
> dpcumented, it is true that implementations *often* try to copy CPython,
> but that's not mandatory and there are exceptions.
>
>
I think you are talking about recent discussion of MicroPython's `dict`
implementation (that the order is not guaranteed?) It is a necessary trade
off for them given their niche (if I understand correctly the explanation
given by Paul Sokolovsky).


> [...]
>
> Users of CPython frequently rely on CPython implementation details. Why
> do you think Jython and IronPython users will be different?
>
>
Hmm, what do you mean? It seems to me that everything happens the other way
round. For example, recent attempts of numpy to make numpy more PyPy
friendly. In fact, I do not know anyone who specifically rely on CPython
implementation details in their production code.

with kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-20 Thread Rhodri James

On 20/08/18 17:16, Chris Barker via Python-ideas wrote:

On Mon, Aug 20, 2018 at 7:21 AM, Steven D'Aprano
wrote:


* Introducing a warning makes it clear that this is not a de facto
   language standard, but a mere implementation detail subject to
   change if somebody comes up with a better optimization for locals.


defacto standards are sub-optimum -- the docs say "may not" -- that seems
really sketchy to me.


On the contrary, it is well defined in international standards usage. 
"May" and "may not" indicate that behaviour is optional, so shouldn't be 
relied on.


--
Rhodri James *-* Kynesim Ltd
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-20 Thread Chris Angelico
On Tue, Aug 21, 2018 at 2:16 AM, Chris Barker via Python-ideas
 wrote:
> On Mon, Aug 20, 2018 at 7:21 AM, Steven D'Aprano 
> wrote:
>>
>> * Introducing a warning makes it clear that this is not a de facto
>>   language standard, but a mere implementation detail subject to
>>   change if somebody comes up with a better optimization for locals.
>
>
> defacto standards are sub-optimum -- the docs say "may not" -- that seems
> really sketchy to me.
>
> Even if there is no change to the implementation of cPython, I'd like to see
> the behavior clearly defined -- if I pass a object returned by "locals()" to
> a function, and that function modifies that object -- will, or will not, the
> local namespace be altered? Saying it "may" be altered is kind of crazy!
> Does that mean the same code will have a different effect if run in two
> different (compliant) implementations of Python? That sure seems like a bad
> idea...

If you do the wrong thing, a compliant Python is allowed to do one of
two things. It's no different from anything else that's been defined
as the wrong thing - opening a file and then dropping it on the floor
(might close it promptly, might not), testing integers by identity ("x
is 5"), etc, etc. The language is well-enough-defined that you can be
confident that locals()["x"]=1 will EITHER change x to 1 OR have no
significant effect.

If you truly want to mandate that every Python implementation
absolutely perfectly imitate CPython, what is the point of other
implementations? Or a language spec? They'd just be refactorings of
CPython.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-20 Thread Chris Barker via Python-ideas
On Mon, Aug 20, 2018 at 7:21 AM, Steven D'Aprano 
wrote:

> * Introducing a warning makes it clear that this is not a de facto
>   language standard, but a mere implementation detail subject to
>   change if somebody comes up with a better optimization for locals.
>

defacto standards are sub-optimum -- the docs say "may not" -- that seems
really sketchy to me.

Even if there is no change to the implementation of cPython, I'd like to
see the behavior clearly defined -- if I pass a object returned by
"locals()" to a function, and that function modifies that object -- will,
or will not, the local namespace be altered? Saying it "may" be altered is
kind of crazy! Does that mean the same code will have a different effect if
run in two different (compliant) implementations of Python? That sure seems
like a bad idea...


> more so, I do not believe that anyone will rely or use such a feature.
>

well, this thread exists because someone wanted to do something like that
-- i.e. manipulate the calling namespace from within a function. I
suggested that passing locals() in might work -- it didn't work (in
cPython), but if it HAD worked in whatever implementation the OP is using,
then, yes, someone would now be relying on that feature.

-CHB


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-20 Thread Jonathan Fine
Hi

I've created new thread
===
Documentation of locals()
https://mail.python.org/pipermail/python-ideas/2018-August/052843.html

Summary: There's prior art in bug.python.org relating to off-thread
topic discussion of locals(). Suggest work on closing open
documentation issues relating to locals().

[...]

I suggest that those that have time, energy and interest focus on
closing the open locals() documentation issues. Such documentation
would, I think, provide an excellent starting point for any proposals
to change behaviour. There are 13 open issues with 'locals' in the
title.
===

Perhaps the discussion of locals() here could be moved to the new thread.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-20 Thread Chris Angelico
On Tue, Aug 21, 2018 at 12:21 AM, Steven D'Aprano  wrote:
> On Sun, Aug 19, 2018 at 06:18:56PM +0300, Kirill Balunov wrote:
>
> [...]
>> > > e) It leaves a room for a future changes (In fact, in some situations I
>> > > would like to have this possibility).
>
> [Chris]
>> > Related to (e) is that there is room for other implementations to
>> > permit changes to locals(), and furthermore, a fully-compliant Python
>> > implementation may use an actual dictionary for locals, and simply
>> > return that. (That CPython doesn't is an implementation detail for the
>> > sake of performance.) Requiring that it be a proxy would impose
>> > unnecessary cost on the implementation, without benefiting any
>> > compliant use.
>
> I would like to see CPython locals() return a mapping object which
> raises a warning when you mutate it.

That, I can get behind. Requiring it to be a proxy would IMO be a bad
idea; but the warning here would be a CPython implementation detail.
OTOH, warnings are easy to miss. But on the gripping hand, if more of
Python and CPython raised warnings when odd things or
implementation-specific things were done, it would encourage people to
develop with warnings active.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-20 Thread Steven D'Aprano
On Sun, Aug 19, 2018 at 06:18:56PM +0300, Kirill Balunov wrote:

[...]
> > > e) It leaves a room for a future changes (In fact, in some situations I
> > > would like to have this possibility).

[Chris]
> > Related to (e) is that there is room for other implementations to
> > permit changes to locals(), and furthermore, a fully-compliant Python
> > implementation may use an actual dictionary for locals, and simply
> > return that. (That CPython doesn't is an implementation detail for the
> > sake of performance.) Requiring that it be a proxy would impose
> > unnecessary cost on the implementation, without benefiting any
> > compliant use.

I would like to see CPython locals() return a mapping object which 
raises a warning when you mutate it.

* Currently, assignments to locals() simply do the wrong thing (modify
  the dict but fail to modify the local namespace) silently; such errors 
  should never pass silently.

* It should be a warning, not an error, since there are use-cases for
  modifying the local dict without caring about the namespace; in those
  cases we can simply silence the warning or ignore it.

* Introducing a warning makes it clear that this is not a de facto 
  language standard, but a mere implementation detail subject to
  change if somebody comes up with a better optimization for locals.

- Other implementations should be permitted to use local namespaces
  which are read/write (that's a Quality Of Implementation issue).

- Given that uses of locals() inside a function are already restricted
  and presumably uncommon, the extra cost of a warning is unlikely
  to be meaningful.


[Kirill]
> Let me disagree with you. While CPython is only one of the implementations
> of the Python language, it is the most common one and defacto is considered
> as a standard.

Not in this case. If CPython intended this to be the language behaviour, 
it should specify that limitation instead of merely giving a doc warning 
that changes "may not" affect the local variables.

In fact, the warning in the docs is too strong. Modifying locals() 
inside a class or module scope is allowed, and works fine. It is only 
functions which is problematic.


> Therefore, all the others, to be compliant, try to replicate
> all subtleties and features of the basic implementation - CPython.

Implementations are expected to obey the documented behaviour (unless 
given special dispensation to break the rules, which I think has 
happened once or twice with MicroPython). For behaviour which isn't 
dpcumented, it is true that implementations *often* try to copy CPython, 
but that's not mandatory and there are exceptions.

PyPy is probably the alternate implementation which tries the hardest to 
duplicate CPython, but even PyPy has differences:

http://doc.pypy.org/en/latest/cpython_differences.html

including a few things which the PyPy developers believe is a bug in 
CPython.

This list of differences between Jython and CPython is terribly out of 
date, but I haven't found anything more recent:

http://www.jython.org/archive/21/docs/differences.html


> And even
> more so, I do not believe that anyone will rely or use such a feature.

Users of CPython frequently rely on CPython implementation details. Why 
do you think Jython and IronPython users will be different?



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-19 Thread Kirill Balunov
вс, 19 авг. 2018 г. в 17:51, Chris Angelico :

> On Mon, Aug 20, 2018 at 12:43 AM, Kirill Balunov
>  wrote:
> >
> [...]
> > I have the same feeling and already have asked the same question before
> > https://mail.python.org/pipermail/python-list/2018-February/731241.html.
> The
> > main take away was that it is the CPython implementation detail and that
> > `MappingProxy` type was introduced only in 3.3. I still do not find these
> > arguments convincing. On the other hand with the current status quo -
> > `locals` returns `dict` inside a function, we have only advantages:
> >
> > a) `locals` always returns a dict and is consistent in all places. (To be
> > consistent is always good.)
> >
> > b) This type of question occurs every 6 months (there is always a topic
> to
> > talk about at ML).
> >
> > c) When someone encounters this behavior first time, he thinks that he
> found
> > a bug <- There was no error but nothing happened (gives an opportunity to
> > study the internal details of the CPython implementation, the average
> level
> > increases. Everyone also tries to find a way, something like "I believe,
> > there must be a way, because Python is so dynamic" which theoretically
> > allows you to make even more new discoveries.).
> >
> > d) This is considered by some as a way not to leak the CPython
> > implementation details. (Here I have no comments, let it be on the
> > conscience of others.)
> >
> > e) It leaves a room for a future changes (In fact, in some situations I
> > would like to have this possibility).
>
> Related to (e) is that there is room for other implementations to
> permit changes to locals(), and furthermore, a fully-compliant Python
> implementation may use an actual dictionary for locals, and simply
> return that. (That CPython doesn't is an implementation detail for the
> sake of performance.) Requiring that it be a proxy would impose
> unnecessary cost on the implementation, without benefiting any
> compliant use.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/


Let me disagree with you. While CPython is only one of the implementations
of the Python language, it is the most common one and defacto is considered
as a standard. Therefore, all the others, to be compliant, try to replicate
all subtleties and features of the basic implementation - CPython. And even
more so, I do not believe that anyone will rely or use such a feature.

I'm not saying that this change should be a part of the Python language
specification. I just said that this is already implied by the
implementation of CPython3 and if you make it more clear with
`MappingProxy` type it will be a net win in my eyes.

With kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-19 Thread Chris Angelico
On Mon, Aug 20, 2018 at 12:43 AM, Kirill Balunov
 wrote:
>
> чт, 16 авг. 2018 г. в 22:37, Chris Barker via Python-ideas
> :
>>
>>
>> I wonder why locals doesn't return a Mapping Proxy, or other read-only
>> mapping object?
>>
>> If it's not guaranteed to be THE locals dict, and changes *may* not affect
>> the real one (but may), a read-only object seems like much safer idea.
>>
>> -CHB
>>
>
> I have the same feeling and already have asked the same question before
> https://mail.python.org/pipermail/python-list/2018-February/731241.html. The
> main take away was that it is the CPython implementation detail and that
> `MappingProxy` type was introduced only in 3.3. I still do not find these
> arguments convincing. On the other hand with the current status quo -
> `locals` returns `dict` inside a function, we have only advantages:
>
> a) `locals` always returns a dict and is consistent in all places. (To be
> consistent is always good.)
>
> b) This type of question occurs every 6 months (there is always a topic to
> talk about at ML).
>
> c) When someone encounters this behavior first time, he thinks that he found
> a bug <- There was no error but nothing happened (gives an opportunity to
> study the internal details of the CPython implementation, the average level
> increases. Everyone also tries to find a way, something like "I believe,
> there must be a way, because Python is so dynamic" which theoretically
> allows you to make even more new discoveries.).
>
> d) This is considered by some as a way not to leak the CPython
> implementation details. (Here I have no comments, let it be on the
> conscience of others.)
>
> e) It leaves a room for a future changes (In fact, in some situations I
> would like to have this possibility).

Related to (e) is that there is room for other implementations to
permit changes to locals(), and furthermore, a fully-compliant Python
implementation may use an actual dictionary for locals, and simply
return that. (That CPython doesn't is an implementation detail for the
sake of performance.) Requiring that it be a proxy would impose
unnecessary cost on the implementation, without benefiting any
compliant use.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-19 Thread Kirill Balunov
чт, 16 авг. 2018 г. в 22:37, Chris Barker via Python-ideas <
python-ideas@python.org>:

>
> I wonder why locals doesn't return a Mapping Proxy, or other read-only
> mapping object?
>
> If it's not guaranteed to be THE locals dict, and changes *may* not affect
> the real one (but may), a read-only object seems like much safer idea.
>
> -CHB
>
>
I have the same feeling and already have asked the same question before
https://mail.python.org/pipermail/python-list/2018-February/731241.html.
The main take away was that it is the CPython implementation detail and
that `MappingProxy` type was introduced only in 3.3. I still do not find
these arguments convincing. On the other hand with the current status quo -
`locals` returns `dict` inside a function, we have only advantages:

a) `locals` always returns a dict and is consistent in all places. (To be
consistent is always good.)

b) This type of question occurs every 6 months (there is always a topic to
talk about at ML).

c) When someone encounters this behavior first time, he thinks that he
found a bug <- There was no error but nothing happened (gives an
opportunity to study the internal details of the CPython implementation,
the average level increases. Everyone also tries to find a way, something
like "I believe, there must be a way, because Python is so dynamic" which
theoretically allows you to make even more new discoveries.).

d) This is considered by some as a way not to leak the CPython
implementation details. (Here I have no comments, let it be on the
conscience of others.)

e) It leaves a room for a future changes (In fact, in some situations I
would like to have this possibility).

But if seriously, I think that the present situation is pretty weird
especially when there is already the `MappingProxy` type. When it's not
allowed and does not work  (I'm only talking about the functions), it's
better to raise early, instead of be silent until the last.

With kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-17 Thread Abe Dillon
Is "Ban" a class of morphemes or just a single morpheme? I would think
subclasses of Morpheme would be "Bound" and "Unbound" then there might be
subclasses of Bound and so on.

[Jacob Solinsky]

> now I understand that the best way to do that would just be to macro
> expand an often repeated segment of code.


This is also referred to as "functional decomposition" (if I understand you
correctly).

You can usually write a method as a sequence of steps you need to take,
then implement those steps in re-usable helper functions with descriptive
names.

My guess is that you'd want the morpheme class to be fairly simple and
leave a bunch of the joining logic to the Verb. I would make a morpheme
object's "morph" method take in some context (perhaps previous and next
morpheme and stress or something) and output a morphed version of the
morpheme without changing any internal state. That way, the "ban" morpheme
is always the "ban" morpheme no matter what.

It might also be easier to use dictionaries to look up morphemes based on
tense and other context. There are a lot of ways that data-structures and
coding practices can clean up code.



On Fri, Aug 17, 2018 at 4:13 PM, Jacob Solinsky 
wrote:

> The code does the following 2 things:
> A Verb class assembles the necessary morphemes in order in accordance with
> the verb's subject, object, mode, grmamatical order, tense and polarity.
>
> If all of the morphemes' default forms were mashed together at this point
> a valid Ojibwe verb form would not be produced
>
> The code in the mutate methods of each morphene transforms a sequence like
> gi-bizindaw-in-si-in-w-in-m-ban
> into
> gi-bizindoo--si-n-oo-n-inini-mwaa-ban
> gibizindoosinoonininimwaaban
>
> A third piece of code creates thousands of verb instances and populates a
> web form to show every conjugated form of a given verb, though that is not
> important here.
>
> The mutation of each morpheme is dependent on the type and form of the
> preceding and following morpheme, occasionally requiring even more
> information from the parent verb.
>  As most morphemes' mutation method are unique, the subclasses of Morpheme
> for the most part override the Morphems superclass's mutate implementation.
> However, it would reduce my code's current redundancy if I could place
> something like a macro expansion at the beginning of each mutate method's
> internal code, as there is a piece of code used to set up each mutate
> method's local variable space that I copied and pasted many times.
>
> The code I wrote already functions fine, it is just that while I was
> writing I was thinking to myself how convenient it would be if I could
> "jump to" functions, and now I understand that the best way to do that
> would just be to macro expand an often repeated segment of code.
>
> On Fri, 17 Aug 2018, 15:24 Abe Dillon,  wrote:
>
>> Jacob, can you please describe in greater detail *what* you're trying to
>> accomplish with your morpheme code? Not *how* you wish to accomplish it,
>> but *what* the code is supposed to do?
>>
>> I've looked into other projects that try to model morphemes and similar
>> language constructs to get a better idea of the problem space (NLTK
>> , TextBlob
>> , PyGlot
>> ,
>> etc.) and it looks like machine learning is often employed for
>> morpheme-related tasks. It may be that the rules for identifying and
>> manipulating morphemes are inherently so complex that they don't lend
>> themselves to elegant codification. That's usually the case for fields in
>> which people turn to machine learning.
>>
>> It may also be a case where functional decomposition would help. The
>> examples you've given aren't really sufficient to understand the problem.
>> It could be a legitimate deficiency in Python's feature set, or it may be
>> that Python already has features that could serve you better, or it may be
>> that the problem is inherently difficult to codify in an elegant way.
>>
>> Without a concrete use-case, it's nearly impossible to justify adding a
>> new feature to Python. This discussion is unlikely to lead to any
>> meaningful action otherwise.
>>
>> On Thu, Aug 16, 2018 at 4:37 PM, Jacob Solinsky 
>> wrote:
>>
>>> So when getx is executed inside a let form, if it tries to read/write
>>> the value of X it interacts with the X entry in the let form's symbol table
>>> before moving to find X in the global environment, right? That is similar
>>> to what I was trying to accomplish in python, but with the local symbol
>>> table of the calling function rather than a let form.
>>>
>>> I think the way a "jump to" function rather than a "call function" would
>>> be implemented would be by removing the prologue and epilogue of the
>>> function's compiled code. Something vaguely like this:
>>>
>>> def foo(a,b):
>>> c = bar(d =3)%
>>> return c+2
>>>
>>> def bar(d)
>>>  a += 2
>>> 

Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-17 Thread Chris Barker - NOAA Federal via Python-ideas
By the way— really kludgy, doesn’t exec() do what you want here:

Note


The default *locals* act as described for function locals()
 below:
modifications to the default *locals* dictionary should not be attempted.
Pass an explicit *locals*dictionary if you need to see effects of the code
on *locals* after function exec()
 returns.


Though great still may not effect the current local namespace.


But I’d be really surprised if there were no way to modify the local
namespace — you can mess with pretty much anything else in Python.


-CHB



Sent from my iPhone

On Aug 17, 2018, at 12:46 PM, Chris Barker  wrote:

On Thu, Aug 16, 2018 at 12:37 PM, Chris Angelico  wrote:

>
> I've no idea what interpreter you're using, but it doesn't work for me.
>

That was in iPython, with python3.6.2 -- I wouldn't have expected it to be
different in this case though -- really odd.

OK -- tired again, and it indeed it failed -- so I'm really confused. You
can see my console output -- it did indeed work at least once.



> You've changed a cached dictionary but haven't actually created a local
>

which still makes me wonder WHY locals() returns a writable dict...

-CHB


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-17 Thread Jacob Solinsky
The code does the following 2 things:
A Verb class assembles the necessary morphemes in order in accordance with
the verb's subject, object, mode, grmamatical order, tense and polarity.

If all of the morphemes' default forms were mashed together at this point a
valid Ojibwe verb form would not be produced

The code in the mutate methods of each morphene transforms a sequence like
gi-bizindaw-in-si-in-w-in-m-ban
into
gi-bizindoo--si-n-oo-n-inini-mwaa-ban
gibizindoosinoonininimwaaban

A third piece of code creates thousands of verb instances and populates a
web form to show every conjugated form of a given verb, though that is not
important here.

The mutation of each morpheme is dependent on the type and form of the
preceding and following morpheme, occasionally requiring even more
information from the parent verb.
 As most morphemes' mutation method are unique, the subclasses of Morpheme
for the most part override the Morphems superclass's mutate implementation.
However, it would reduce my code's current redundancy if I could place
something like a macro expansion at the beginning of each mutate method's
internal code, as there is a piece of code used to set up each mutate
method's local variable space that I copied and pasted many times.

The code I wrote already functions fine, it is just that while I was
writing I was thinking to myself how convenient it would be if I could
"jump to" functions, and now I understand that the best way to do that
would just be to macro expand an often repeated segment of code.

On Fri, 17 Aug 2018, 15:24 Abe Dillon,  wrote:

> Jacob, can you please describe in greater detail *what* you're trying to
> accomplish with your morpheme code? Not *how* you wish to accomplish it,
> but *what* the code is supposed to do?
>
> I've looked into other projects that try to model morphemes and similar
> language constructs to get a better idea of the problem space (NLTK
> , TextBlob
> , PyGlot
> ,
> etc.) and it looks like machine learning is often employed for
> morpheme-related tasks. It may be that the rules for identifying and
> manipulating morphemes are inherently so complex that they don't lend
> themselves to elegant codification. That's usually the case for fields in
> which people turn to machine learning.
>
> It may also be a case where functional decomposition would help. The
> examples you've given aren't really sufficient to understand the problem.
> It could be a legitimate deficiency in Python's feature set, or it may be
> that Python already has features that could serve you better, or it may be
> that the problem is inherently difficult to codify in an elegant way.
>
> Without a concrete use-case, it's nearly impossible to justify adding a
> new feature to Python. This discussion is unlikely to lead to any
> meaningful action otherwise.
>
> On Thu, Aug 16, 2018 at 4:37 PM, Jacob Solinsky 
> wrote:
>
>> So when getx is executed inside a let form, if it tries to read/write the
>> value of X it interacts with the X entry in the let form's symbol table
>> before moving to find X in the global environment, right? That is similar
>> to what I was trying to accomplish in python, but with the local symbol
>> table of the calling function rather than a let form.
>>
>> I think the way a "jump to" function rather than a "call function" would
>> be implemented would be by removing the prologue and epilogue of the
>> function's compiled code. Something vaguely like this:
>>
>> def foo(a,b):
>> c = bar(d =3)%
>> return c+2
>>
>> def bar(d)
>>  a += 2
>>  e = 4
>>  return a + b + d +e
>>
>> foo(7, 2)
>>
>> Here would be the symbol table
>>
>> Scope Foo
>> __
>> a: fp - 1
>> b: fp - 2
>> d: fp - 3
>> e: fp - 5
>> c: fp - 4
>>
>> The interpreter would have to recognize that bar was being jumped to
>> rather than called and thus inject bar's arguments and variable
>> declarations and return value (if assigned to) into foo's stack frame.
>>
>> The translation of the above code would be this (I apologize for the
>> strange pseudoassembly, I don't know any of those languages on a more than
>> cursory level. The below code is obviously very slow, each variable read
>> from the memory and written to memory at every step, with no storage of
>> local variables in registers.) The "return c+2" statement is changed from a
>> return into a c += 2 assignment in the calling function.
>>
>> PUSH fp, returnregister # preserve old value in return register
>> PUSH -1(fp), 7 # load a
>> PUSH -2(fp),  2 # load b
>> PUSH -3(fp), 3 # load d
>> PUSH -4(fp), 0 # initialize c
>> ADDI -1(fp), -1(fp), 2 # a += 2
>> PUSH -5(fp), 4 # load e
>> ADD -4(fp), -1(fp), -2(fp) # c = a + b + d + e
>> ADD -4(fp), -4(fp), -5(fp) # c = a + d + d + e continued
>> ADDI returnregister, -4(fp), 2 # return c + 2
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> On Thu, 16 Aug 2018, 14

Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-17 Thread Abe Dillon
Jacob, can you please describe in greater detail *what* you're trying to
accomplish with your morpheme code? Not *how* you wish to accomplish it,
but *what* the code is supposed to do?

I've looked into other projects that try to model morphemes and similar
language constructs to get a better idea of the problem space (NLTK
, TextBlob ,
PyGlot
,
etc.) and it looks like machine learning is often employed for
morpheme-related tasks. It may be that the rules for identifying and
manipulating morphemes are inherently so complex that they don't lend
themselves to elegant codification. That's usually the case for fields in
which people turn to machine learning.

It may also be a case where functional decomposition would help. The
examples you've given aren't really sufficient to understand the problem.
It could be a legitimate deficiency in Python's feature set, or it may be
that Python already has features that could serve you better, or it may be
that the problem is inherently difficult to codify in an elegant way.

Without a concrete use-case, it's nearly impossible to justify adding a new
feature to Python. This discussion is unlikely to lead to any meaningful
action otherwise.

On Thu, Aug 16, 2018 at 4:37 PM, Jacob Solinsky 
wrote:

> So when getx is executed inside a let form, if it tries to read/write the
> value of X it interacts with the X entry in the let form's symbol table
> before moving to find X in the global environment, right? That is similar
> to what I was trying to accomplish in python, but with the local symbol
> table of the calling function rather than a let form.
>
> I think the way a "jump to" function rather than a "call function" would
> be implemented would be by removing the prologue and epilogue of the
> function's compiled code. Something vaguely like this:
>
> def foo(a,b):
> c = bar(d =3)%
> return c+2
>
> def bar(d)
>  a += 2
>  e = 4
>  return a + b + d +e
>
> foo(7, 2)
>
> Here would be the symbol table
>
> Scope Foo
> __
> a: fp - 1
> b: fp - 2
> d: fp - 3
> e: fp - 5
> c: fp - 4
>
> The interpreter would have to recognize that bar was being jumped to
> rather than called and thus inject bar's arguments and variable
> declarations and return value (if assigned to) into foo's stack frame.
>
> The translation of the above code would be this (I apologize for the
> strange pseudoassembly, I don't know any of those languages on a more than
> cursory level. The below code is obviously very slow, each variable read
> from the memory and written to memory at every step, with no storage of
> local variables in registers.) The "return c+2" statement is changed from a
> return into a c += 2 assignment in the calling function.
>
> PUSH fp, returnregister # preserve old value in return register
> PUSH -1(fp), 7 # load a
> PUSH -2(fp),  2 # load b
> PUSH -3(fp), 3 # load d
> PUSH -4(fp), 0 # initialize c
> ADDI -1(fp), -1(fp), 2 # a += 2
> PUSH -5(fp), 4 # load e
> ADD -4(fp), -1(fp), -2(fp) # c = a + b + d + e
> ADD -4(fp), -4(fp), -5(fp) # c = a + d + d + e continued
> ADDI returnregister, -4(fp), 2 # return c + 2
>
>
>
>
>
>
>
>
>
>
>
> On Thu, 16 Aug 2018, 14:44 Jonathan Fine,  wrote:
>
>> Hi Jacob
>>
>> I'm finding the python-ideas list a bit noisy, so I'm sending this
>> off-list.
>>
>> I've found
>>
>> https://www.gnu.org/software/emacs/manual/html_node/elisp/
>> Dynamic-Binding.html
>> https://www.gnu.org/software/emacs/manual/html_node/elisp/
>> Variable-Scoping.html
>>
>> Please confirm that this is at least close to what you want, to be
>> able to program your problem efficiently.
>>
>> Meanwhile, I'm thinking about how your algorithm might be expressed in
>> Python.
>>
>> --
>> Jonathan
>>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-17 Thread Chris Barker via Python-ideas
On Thu, Aug 16, 2018 at 12:37 PM, Chris Angelico  wrote:

>
> I've no idea what interpreter you're using, but it doesn't work for me.
>

That was in iPython, with python3.6.2 -- I wouldn't have expected it to be
different in this case though -- really odd.

OK -- tired again, and it indeed it failed -- so I'm really confused. You
can see my console output -- it did indeed work at least once.



> You've changed a cached dictionary but haven't actually created a local
>

which still makes me wonder WHY locals() returns a writable dict...

-CHB


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-17 Thread Jonathan Fine
Jacob Solinsky wrote:

> So when getx is executed inside a let form, if it tries to read/write the
> value of X it interacts with the X entry in the let form's symbol table
> before moving to find X in the global environment, right?

The context for this is two (very useful) URLs I sent him off list:

https://www.gnu.org/software/emacs/manual/html_node/elisp/Dynamic-Binding.html
https://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-17 Thread Brice Parent



Le 16/08/2018 à 20:34, Steven D'Aprano a écrit :

On Thu, Aug 16, 2018 at 10:31:28AM +0200, Brice Parent wrote:


If I understand well the need (I'm unsure I've had it myself), it would
be easier to be able to import the function in the active context, like
this:

def foo(a):
     return a + c

def bar(a, c):
     return foo(a)

def bazz(a, c):
     import __file__.foo
     return foo(a)

[...]

I'm not saying the syntax is the one that should be used (__file__
possibly not existing may be a problem), not even saying that we should
have this. I'm just showing a way to do the same thing with an easier
(to me) syntax.

The problem isn't that __file__ doesn't exist, it is that import DOES
exist and does something completely unsuitable:

[...]
That's what I was trying to say: I'm not proposing a syntax or any 
specific solution.
It was more about graphically explaining that I found more explicit 
(that word again...) to import (or copy, or insert) the target function 
inside the active scope than to have it done when you call the function 
itself.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Stephen J. Turnbull
Jacob Solinsky writes:

 > I think the way a "jump to" function rather than a "call function" would be
 > implemented would be by removing the prologue and epilogue of the
 > function's compiled code. Something vaguely like this:

First, let me apologize for pointing you at Ruby blocks.  They don't
quite do what I thought they did; they're more like Python's
"nonlocal" than Lisp's "dynamic scope".  I'm pretty sure you would
need something else added to Python.  (But see below.)  If you're not
a Ruby programmer and don't necessarily want to be one, I'd say wait
for someone who is to say I'm wrong before pushing them.

Second, it seems to me that the kind of "DRY" you're looking for is
just as well implemented by a macro facility.  You might want to look
at MacroPy.

tl;dr here

I'm not very experienced with Ruby, so I'll post the snippets that
convinced me that Ruby's blocks don't DTRT.  Maybe somebody else can
correct my code to get the job done, in which case you might have a
reason to advocate blocks for Python.

Steve

Code:

The problem is that blocks have nonlocal access (as defined in Python
3) to the scope in which they are defined, not somehow imposing
dynamic access on that scope.

def preamble
# assign local variables
end

def mutate
preamble do
# do stuff with preamble's locals
end
end

doesn't work because the block can see mutate's locals but not
preamble's.

So I think

def mutate
def worker
yield
# do stuff with mutate's locals
end
worker do
# assign local variables
end
end

works (untested), but it's just a complicated way to write

def mutate
# assign local variables
# do stuff with mutate's locals
end

while

def worker
yield
# do stuff with mutate's locals
end

def mutate
worker do
# assign local variables
end
end

does not work: worker can't access the local variables of mutate
because they're a scope it can't see.


-- 
Associate Professor  Division of Policy and Planning Science
http://turnbull.sk.tsukuba.ac.jp/ Faculty of Systems and Information
Email: turnb...@sk.tsukuba.ac.jp   University of Tsukuba
Tel: 029-853-5175 Tennodai 1-1-1, Tsukuba 305-8573 JAPAN
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Jacob Solinsky
So when getx is executed inside a let form, if it tries to read/write the
value of X it interacts with the X entry in the let form's symbol table
before moving to find X in the global environment, right? That is similar
to what I was trying to accomplish in python, but with the local symbol
table of the calling function rather than a let form.

I think the way a "jump to" function rather than a "call function" would be
implemented would be by removing the prologue and epilogue of the
function's compiled code. Something vaguely like this:

def foo(a,b):
c = bar(d =3)%
return c+2

def bar(d)
 a += 2
 e = 4
 return a + b + d +e

foo(7, 2)

Here would be the symbol table

Scope Foo
__
a: fp - 1
b: fp - 2
d: fp - 3
e: fp - 5
c: fp - 4

The interpreter would have to recognize that bar was being jumped to rather
than called and thus inject bar's arguments and variable declarations and
return value (if assigned to) into foo's stack frame.

The translation of the above code would be this (I apologize for the
strange pseudoassembly, I don't know any of those languages on a more than
cursory level. The below code is obviously very slow, each variable read
from the memory and written to memory at every step, with no storage of
local variables in registers.) The "return c+2" statement is changed from a
return into a c += 2 assignment in the calling function.

PUSH fp, returnregister # preserve old value in return register
PUSH -1(fp), 7 # load a
PUSH -2(fp),  2 # load b
PUSH -3(fp), 3 # load d
PUSH -4(fp), 0 # initialize c
ADDI -1(fp), -1(fp), 2 # a += 2
PUSH -5(fp), 4 # load e
ADD -4(fp), -1(fp), -2(fp) # c = a + b + d + e
ADD -4(fp), -4(fp), -5(fp) # c = a + d + d + e continued
ADDI returnregister, -4(fp), 2 # return c + 2











On Thu, 16 Aug 2018, 14:44 Jonathan Fine,  wrote:

> Hi Jacob
>
> I'm finding the python-ideas list a bit noisy, so I'm sending this
> off-list.
>
> I've found
>
>
> https://www.gnu.org/software/emacs/manual/html_node/elisp/Dynamic-Binding.html
>
> https://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html
>
> Please confirm that this is at least close to what you want, to be
> able to program your problem efficiently.
>
> Meanwhile, I'm thinking about how your algorithm might be expressed in
> Python.
>
> --
> Jonathan
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Chris Angelico
On Fri, Aug 17, 2018 at 5:32 AM, Chris Barker via Python-ideas
 wrote:
> hmm -- made me think that generators are doing something different here --
> and indeed they are. If you use regular functions:
>
> In [30]: def local_modifying(loc):
> ...: """
> ...: adds a "fred" key to the dict passed in
> ...: """
> ...: print("locals passed in:", loc)
> ...: loc['fred'] = 5
> ...: print("locals after adding", loc)
> ...:
>
> In [31]: def test_locals():
> ...: """
> ...: a simple local namespace to use
> ...: """
> ...: a = 1
> ...: b = 2
> ...: local_modifying(locals())
> ...: # does "fred" exist?
> ...: print(locals())
> ...: # and we can access it the usual way
> ...: print("fred:", fred)
> ...:
> In [32]: test_locals()
> locals passed in: {'b': 2, 'a': 1}
> locals after adding {'b': 2, 'a': 1, 'fred': 5}
> {'b': 2, 'a': 1, 'fred': 5}
> fred: 5
>
> It seems you CAN modify the locals dict passed in, and the change will show
> up in the enclosing scope.
>
> But it sounds like that is not guaranteed by the language.

I've no idea what interpreter you're using, but it doesn't work for me.

>>> test_locals()
locals passed in: {'a': 1, 'b': 2}
locals after adding {'a': 1, 'b': 2, 'fred': 5}
{'a': 1, 'b': 2, 'fred': 5}
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 11, in test_locals
NameError: name 'fred' is not defined

You've changed a cached dictionary but haven't actually created a local.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Chris Barker via Python-ideas
one more thought:

given that:


> > The contents of this dictionary should not be modified; changes may not
>> affect the values of local and free variables used by the interpreter.
>>
>
> and:
> """
> locals()
>
> Update and return a dictionary representing the current local symbol table.
>

I wonder why locals doesn't return a Mapping Proxy, or other read-only
mapping object?

If it's not guaranteed to be THE locals dict, and changes *may* not affect
the real one (but may), a read-only object seems like much safer idea.

-CHB

-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Chris Barker via Python-ideas
On Thu, Aug 16, 2018 at 10:33 AM, Jonathan Fine  wrote:

> >> there
> >> are times where I have really wanted to access the caller's environment,
> >> not the environment where my function was defined.
>
> > what am I missing? can't you get that by passing locals() in to a
> function?
>
> I think this will fail when values are changed. According to
> https://docs.python.org/3/library/functions.html#locals
> > The contents of this dictionary should not be modified; changes may not
> affect the values of local and free variables used by the interpreter.
>

and:
"""
locals()

Update and return a dictionary representing the current local symbol table.
Free variables are returned by locals() when it is called in function
blocks, but not in class blocks.

"""

it a dictionary *representing* the current local symbol table, so not the
actual symbol table -- which surprised me, I thought that is was -- and
sometimes it appears to be -- see later example:

> To finish, here's an interactive example of changing the value of
locals().

>
> >>> def f(a=1): loc = locals(); yield loc; yield a
> >>> it = f()
> >>> ctx = next(it)
> >>> ctx
> {'a': 1}  ## This surprised me.
>

me too I would have thought "loc" would be in there.


> >>> def f(a=1): loc = locals(); yield locals(); yield a
> >>> it = f()
> >>> ctx = next(it)
> >>> ctx
> {'a': 1, 'loc': {...}}
>

now "loc is there"


> >>> ctx['a'] = 3
> >>> ctx['loc']['a'] = 5
> >>> next(it) ## Is it 1 or 3 or 5?
> 1  ## The value of 'a' hasn't changed.


hmm -- made me think that generators are doing something different here --
and indeed they are. If you use regular functions:

In [30]: def local_modifying(loc):
...: """
...: adds a "fred" key to the dict passed in
...: """
...: print("locals passed in:", loc)
...: loc['fred'] = 5
...: print("locals after adding", loc)
...:

In [31]: def test_locals():
...: """
...: a simple local namespace to use
...: """
...: a = 1
...: b = 2
...: local_modifying(locals())
...: # does "fred" exist?
...: print(locals())
...: # and we can access it the usual way
...: print("fred:", fred)
...:
In [32]: test_locals()
locals passed in: {'b': 2, 'a': 1}
locals after adding {'b': 2, 'a': 1, 'fred': 5}
{'b': 2, 'a': 1, 'fred': 5}
fred: 5

It seems you CAN modify the locals dict passed in, and the change will show
up in the enclosing scope.

But it sounds like that is not guaranteed by the language.

-CHB


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Steven D'Aprano
On Thu, Aug 16, 2018 at 09:34:57AM -0700, Chris Barker wrote:
> On Thu, Aug 16, 2018 at 1:28 AM, Steven D'Aprano 
> wrote:
> 
> > there
> > are times where I have really wanted to access the caller's environment,
> > not the environment where my function was defined.
> >
> 
> what am I missing? can't you get that by passing locals() in to a function?

I want to pull in the caller's environment, not require the caller to 
push their environment in to me.

Most of the time I just want read-access to the environment, but if I 
need to modify it, and the OP needs to do that, modifying locals() is 
unreliable. In general, it just silently fails, because locals() 
returns a copy of the local namespace.


def spam(d):
d['a'] = 'spam'

def eggs():
a = 'ham'
spam(locals())
print(a)

Running that under CPython prints "ham", not "spam".

(To be precise, writing to locals() works when you are in the module 
scope, or a class body, but not a function body. That's a CPython 
implementation detail; IronPython and Jython may behave differently.)



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Steven D'Aprano
On Thu, Aug 16, 2018 at 10:31:28AM +0200, Brice Parent wrote:

> If I understand well the need (I'm unsure I've had it myself), it would 
> be easier to be able to import the function in the active context, like 
> this:
> 
> def foo(a):
>     return a + c
> 
> def bar(a, c):
>     return foo(a)
> 
> def bazz(a, c):
>     import __file__.foo
>     return foo(a)
[...]
> I'm not saying the syntax is the one that should be used (__file__ 
> possibly not existing may be a problem), not even saying that we should 
> have this. I'm just showing a way to do the same thing with an easier 
> (to me) syntax.

The problem isn't that __file__ doesn't exist, it is that import DOES 
exist and does something completely unsuitable:

def bazz(a, c):
   # Make the *name* foo a local
   foo = globals()['__file__'].foo  # (roughly)
   return foo(a)

But this doesn't change the scoping rules used when calling foo. It 
still runs using lexical scope, which means the a+c line in foo() 
still refers to the global variable c.

What we would need is a completely different command, not "import", 
perhaps "load":

def bazz(a, c):
foo = load('foo')
return foo(a)

which would be equivalent to this pseudocode:

def bazz(a, c):
get the source code of foo (hopefully still available!)
foo = compile(source code as inner function)
call foo

or possibly:

def bazz(a, c):
make a copy of foo and its bytecode
change all(?) the LOAD_GLOBAL bytecode to LOAD_DEREF
call the modified copy of foo


Both implementations seem clunky, fragile and likely to be slow to me.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Stephen J. Turnbull
Jacob Solinsky writes:

 > What I had hoped to do was use a preamble code block to collect all of the
 > most common queries called by the mutate function in the local namespace,
 > for example
 > 
 > C = 'bpgkdtszSZjCmnywh'
 > M = 'mn'
 > 
 > 
 > class Morpheme:
 > #stuff
 > 
 > def preamble(self):
 > 
 > ps = self.precedingmorpheme.form
 > ss = self.succeedingmorpheme.form
 > ssc = re.match(f'^[{C}]', self.succedingmorpheme.form) #Whether or not
 > the following morpheme is consonant initial
 > ssm = re.match(f'[{M}]$', self.precedingmorpheme.form) #Whether or not
 > the preceding morpheme is nasal final
 > 
 > these local variables are used quite often in the mutate methods, of which
 > there are several dozen, so storing them by default saves a lot of
 > typing.

What you're asking for is basically a "Ruby block", AFAICS.  This has
been requested many times, but most of the senior Pythonistas consider
that it leads to a very high risk of unreadable and/or buggy code at
no gain in power (there are several ways to efficiently accomplish
what you want to do, you just don't like them[1]), and few cases where
it's more readable/less buggy.  I think if you search "ruby block
site:mail.python.org" you'll probably bring up the threads.  You won't
find a lot of encouraging discussion, I'm afraid.

What I would do in your case is

class Morpheme:
class Preamble:
def __init__(self, m):# "m" for "morpheme"
self.ps = m.precedingmorpheme.form
self.ss = m.succeedingmorpheme.form
self.ssc = re.match(f'^[{C}]', m.succedingmorpheme.form)
self.ssm = re.match(f'[{M}]$', m.precedingmorpheme.form)
def mutate():
p = self.Preamble(self)
# use p.ps, p.ss, etc

It's a little less efficient, of course, because of overhead managing
the Preamble objects.

Another possibility would be to use properties, so that instead of
*storing* these temporary variables on the Morpheme, they would be
computed on the fly:

class Morpheme:
@property
def ps(self):
return self.precedingmorpheme.form
@property
def ss(self):
return self.succeedingmorpheme.form
@property
def ssc(self):
return re.match(f'^[{C}]', self.succeedingmorpheme.form)
@property
def ssm(self):
return re.match(f'[{M}]$', self.precedingmorpheme.form)

and so on.  Then you can access them with "self.ps" etc in the mutate
method.  This might be considered elegant (although verbose in the
Morpheme definition) if these properties are usually used only once
per mutate call, and "expensive" properties like ssc and ssm are never
called more than once.  (If they are called multiple times, it's easy
to create a cache.)  Of course property accesses do add method call
overhead, but they look nicer than method call syntax.  On the other
hand, if "many" properties are expensive, and "most" mutate methods
use only a few of these, you could save runtime this way, since the
expensive methods are called only as-needed.

I don't understand the "need default value in __init__" issue, since
"inject" implied to me that you initialize before use.  But if that's
a problem for ordinary attributes, I presume it'll be more annoying
with properties because you have to write a method for it.  So I don't
know if this is helpful at all.

Footnotes: 
[1]  "I don't like it" is a sufficient reason to propose a change.
I'm simply saying you have the *power* to do what you want.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Stephen J. Turnbull
tl;dr A pedantic note on dynamic binding.

Steven D'Aprano writes:

 > The most common language today that uses dynamic scoping is probably 
 > Emacs Lisp.

AFAIK all Common-Lisp-ish languages implement dynamic scoping:
anything defvar'd is dynamically-scoped.

 > Although dynamic scoping is very powerful, it is also harder 
 > to implement correctly (so I believe)

In fact, lexical scoping is harder to do correctly because you need to
know what you're doing (determine whether a name is in the lexical
scope).  (Old) Emacs Lisp-style dynamic scoping (everything is
dynamically scoped) is (conceptually) easy to implement correctly (but
inefficiently!) simply by using a stack of bindings and doing all
accesses by searching that stack top to bottom for a relevant binding.
It's a pain in the butt to use *correctly* because every such binding
can affect anything else in your program and any libraries you import.
That's why Common Lisp and modern Emacs Lisp are lexically-scoped.[1]
It's not that much harder to implement the dynamic scoping of defvars;
you just have to add a check for the symbol being a defvar at binding
time, and if not put it in the local namespace.

It's true (as you write later in the thread) that Richard Stallman is
still enamoured of dynamic scoping.  The nicest thing I can say about
Richard is that he has enormous capacity to hold huge complex
structures in his head.  The next nicest thing I can say about Richard
is that he's an anomoly.  If his enthusiasm for dynamic scoping is
correct, it's a "stopped clock right twice a day" phenomenon.  What's
good for Richard may be *convenient* for the rest of us when hacking
up one-offs, but I firmly believe that if *we* want to write reliable,
nearly correct software for complex systems, dynamic scoping should be
used sparingly at most.

After 2 decades of maintaining Emacsen, I'd go so far as to say that
Python's "global" and "nonlocal" declarations are distinctly
preferable to Lisp's "defvar" and "special" declarations where
Python's much more restricted constructs can do the job.

 > It is generally considered that dynamic scoping is equivalent to
 > the exclusive use of global variables

That depends on your definition of "equivalent" and "global".  At
least psychologically, they can be very different regardless of the
definition of "variable".  In (old) Emacs Lisp, defun, lambda, and let
all appear to define local variables, but they don't.  They define
local bindings of global variables, which affect any function called
recursively from the function that does the binding that uses those
variables as globals.

And in any Lisp, it is in principle[2] impossible to write a correct
program using dynamic scope if you import another module, because even
if you've checked that module and there are no free occurrances of a
given name at write-time, the module could be updated to use a free
variable by that name before you run it and you will shadow its
expected binding at run-time.  To be safe, you need to implement
lexical scope!  In languages where "global" names are bound to memory
locations at compile time, like C, or in Python where "global" means
module scope, you don't have this problem.  Sure, in C you can declare
a variable "extern" or in Python you can import a name from another
module, but that solves the problem: without an *explicit* declaration
of that kind you know you can't affect another module.

The point, of course, is not so much the "in principle" hazard, but
rather the need to determine what the scope of a given binding *could*
be and to check large extents of source code for bugs due to
unexpected shadow bindings of free variables in order to be sure your
program is correct, and that there is no restriction in principle on
how large that extent might be.

Steve


Footnotes: 
[1]  Technically, I think Emacs still defaults to dynamic scope and
you have to turn lexical scope on with a pragma.

[2]  Again, technically, you can use dynamic scope safely in Common
Lisp by interning your dynamic variables in a package, and so
restricting their scope to your module plus any other modules that
deliberate import those names.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Jonathan Fine
Hi Jacob

I really like your previous post. I find it really helps me understand
what you want. You wrote

> I wanted the called, jumped to function to change state in the caller.
> From what I tried to do, passing locals() cannot accomplish this. I have
> made it happen in other languages though.
> In the R language, one can do this

> foo = function(){
>localenv = environment()
>eval(bar, environment = localenv)

> The above code captures the environment of the calling function and
> executes the called function as if the calling function's local environment
> was the global environment.

So in a nutshell, you'd like to be able to write code like this, but in Python?

> bar doesn't have to be a function, it can be any
> valid R expression captured with the expr() function, and everything in R is
> an expression thus allowing for the full usage code blocks.

This Python can already do. Any Python expression can be turned into a
function, simply by prefixing it with 'lambda:'.

> Outside of
> lisp-like languages this feat seems to usually be impossible though.

I'm an Emacs user, so I know Lisp. But R is new to me. But this URL
tells me that R is based on Lisp.
https://www.i-programmer.info/programming/other-languages/1706-a-programmers-guide-to-r.html

And, in my view, this makes your problem immediately much more
important for the Python community. Because both Python and R are
major languages in the area of Data Science.

Thank you so much for your previous post, and to all the others whose
posts have contributed to this clarification.

-- 
best regards

Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Jacob Solinsky
On Thu, 16 Aug 2018, 12:44 Jacob Solinsky,  wrote:

> I wanted the called, jumped to function to change state in the caller.
> From what I tried to do, passing locals() cannot accomplish this. I have
> made it happen in other languages though.
> In the R language, one can do this
>
> foo = function(){
>localenv = environment()
>eval(bar, environment = localenv)
>
> The above code captures the environment of the calling function and
> executes the called function as if the calling function's local environment
> was the global environment. bar doesn't have to be a function, it can be
> any valid R expression captured with the expr() function, and everything in
> R is an expression thus allowing for the full usage code blocks. Outside of
> lisp-like languages this feat seems to usually be impossible though.
>
>
> On Thu, 16 Aug 2018, 12:34 Jonathan Fine,  wrote:
>
>> Hi Chris
>>
>> Steve and you wrote:
>>
>> >> there
>> >> are times where I have really wanted to access the caller's
>> environment,
>> >> not the environment where my function was defined.
>>
>> > what am I missing? can't you get that by passing locals() in to a
>> function?
>>
>> I think this will fail when values are changed. According to
>> https://docs.python.org/3/library/functions.html#locals
>> > The contents of this dictionary should not be modified; changes may not
>> affect the values of local and free variables used by the interpreter.
>>
>> I suspect that Jacob, the original poster, wants to change state, and
>> also to read changed state.  Jacob, could you confirm or correct, that
>> you want the called function to be able to change state in caller (or
>> perhaps even further up the stack).
>>
>> To finish, here's an interactive example of changing the value of
>> locals().
>>
>> >>> def f(a=1): loc = locals(); yield loc; yield a
>> >>> it = f()
>> >>> ctx = next(it)
>> >>> ctx
>> {'a': 1}  ## This surprised me.
>> >>>
>> >>>
>> >>> def f(a=1): loc = locals(); yield locals(); yield a
>> >>> it = f()
>> >>> ctx = next(it)
>> >>> ctx
>> {'a': 1, 'loc': {...}}
>> >>> ctx['a'] = 3
>> >>> ctx['loc']['a'] = 5
>> >>> next(it) ## Is it 1 or 3 or 5?
>> 1  ## The value of 'a' hasn't changed.
>>
>> --
>> Jonathan
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Jonathan Fine
Hi Chris

Steve and you wrote:

>> there
>> are times where I have really wanted to access the caller's environment,
>> not the environment where my function was defined.

> what am I missing? can't you get that by passing locals() in to a function?

I think this will fail when values are changed. According to
https://docs.python.org/3/library/functions.html#locals
> The contents of this dictionary should not be modified; changes may not 
> affect the values of local and free variables used by the interpreter.

I suspect that Jacob, the original poster, wants to change state, and
also to read changed state.  Jacob, could you confirm or correct, that
you want the called function to be able to change state in caller (or
perhaps even further up the stack).

To finish, here's an interactive example of changing the value of locals().

>>> def f(a=1): loc = locals(); yield loc; yield a
>>> it = f()
>>> ctx = next(it)
>>> ctx
{'a': 1}  ## This surprised me.
>>>
>>>
>>> def f(a=1): loc = locals(); yield locals(); yield a
>>> it = f()
>>> ctx = next(it)
>>> ctx
{'a': 1, 'loc': {...}}
>>> ctx['a'] = 3
>>> ctx['loc']['a'] = 5
>>> next(it) ## Is it 1 or 3 or 5?
1  ## The value of 'a' hasn't changed.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Chris Barker via Python-ideas
On Thu, Aug 16, 2018 at 1:28 AM, Steven D'Aprano 
wrote:

> there
> are times where I have really wanted to access the caller's environment,
> not the environment where my function was defined.
>

what am I missing? can't you get that by passing locals() in to a function?

A bit clunky, sure, but everyone seems to agree that this a fairly rarely
used approach.

-CHB

-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Brice Parent
If I understand well the need (I'm unsure I've had it myself), it would 
be easier to be able to import the function in the active context, like 
this:


def foo(a):
    return a + c

def bar(a, c):
    return foo(a)

def bazz(a, c):
    import __file__.foo
    return foo(a)

c = 5
call = bar(1, 3)  # -> 6
jump = bazz(1, 3)  # -> 4

bazz would be equivalent to:

def bazz(a, c):
    def foo(a):
    return a + c
    return foo(a)

I'm not saying the syntax is the one that should be used (__file__ 
possibly not existing may be a problem), not even saying that we should 
have this. I'm just showing a way to do the same thing with an easier 
(to me) syntax.



- Brice
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-16 Thread Steven D'Aprano
On Wed, Aug 15, 2018 at 09:58:28PM -0400, David Mertz wrote:
> When did you last read the Dijkstra paper. It's short and he explains very
> well why exactly all the constructs you mention are unlike Goto.

Of course I've read it, and no he does not. He only mentions if...else 
and looping. He doesn't mention break, continue, exceptions (I don't 
think exceptions had even been invented in 1968).

I think that if Dijkstra were still alive, he would probably chose to 
understate or dismiss the similarities between goto and break/continue. 
Others might choose to focus on the similarities rather than the 
differences, e.g. "continue" is just a goto to the start of the loop, 
"break" is goto the end of the loop.

But this isn't a debate over the pros and cons of goto. Goto is not 
relevant. This proposal is for dynamic scoping, not a way to change 
execution order or jump from one part of code to another.


> This isn't a proposal to subroutines, it's a proposal for subroutines in
> which all lexically scoped variables are implicitly nonlocal.

Language fail :-)

"This isn't a proposal for subroutines, it's a proposal for subroutines" 
:-)

I've read the proposal differently, for dynamic scoping, not lexical 
scoping plus implicit nonlocal. It may be that you could get similar 
results from either, but they are fundamentally different.

Python already has a kind of dynamic "scoping" (of sorts) which you 
probably use every day and never think twice about it. When an exception 
occurs, the scope of the exception handlers is the runtime call stack, 
not the lexical scope.

There's nothing *inherently* bad about dynamic resolution of FOO, for 
any value of FOO (be it inheritence and method resolution, attribute 
lookup, scoping, or exception handling). It has its pros and cons, of 
course. I'd even allow that if overused or misused, dynamic scoping will 
be hard to reason about.

(I believe it was Guy Steele who proved that dynamic scoping is 
equivalent to a single global scope, but of course that only applies 
when *all* functions are *always* dynamically scoped.)

Just as we allow global variables for those odd cases where they are 
needed (or even just because it is more convienent), so there's a case 
for allowing dynamic scoping. Especially when the alternatives (classes, 
closures) are clumsy, difficult to get right, full of duplicated code 
and boilerplate.

I wouldn't want every function call to use dynamic scoping, but there 
are times where I have really wanted to access the caller's environment, 
not the environment where my function was defined.

We ought to give this concept a fair shake, not just dismiss it on the 
basis of platitudes "X considered harmful", especially when X isn't even 
relevant.


> That's basically Goto

Its nothing like goto, except to the (small) degree that any jump to a 
subroutine is a goto.


> certainly course enough to suffer all of Dijkstra's
> complaints.
> 
> Yes, technically this could be called dynamic scope instead. But
> notwithstanding the use in elisp, that's pretty widely regarded as a bad
> ideas (even by the emacs developers who regret that early decision).

Richard Stallman doesn't.

I'm sure you can still find thousands of Python developers who regret 
that it uses significant whitespace and no braces. I know you can find 
Python developers who hate "lambda", and I know some who don't 
understand comprehensions and regret their inclusion in the language.

Just about every proposal for new syntax is objected to, sometimes 
vehemently enough to drive Guido into "permanent vacation" (retirement) 
from his position of BDFL :-(

So yes, I'm sure that some Emacs developers think dynamic scoping is a 
mistake, just as some Python developers think FOO is a mistake, for just 
about any value of FOO you can think of.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread David Mertz
When did you last read the Dijkstra paper. It's short and he explains very
well why exactly all the constructs you mention are unlike Goto.

This isn't a proposal to subroutines, it's a proposal for subroutines in
which all lexically scoped variables are implicitly nonlocal. That's
basically Goto, certainly course enough to suffer all of Dijkstra's
complaints.

Yes, technically this could be called dynamic scope instead. But
notwithstanding the use in elisp, that's pretty widely regarded as a bad
ideas (even by the emacs developers who regret that early decision).

On Wed, Aug 15, 2018, 9:41 PM Steven D'Aprano  wrote:

> On Wed, Aug 15, 2018 at 08:35:35PM -0400, David Mertz wrote:
>
> > Goto considered harmful.
>
> Fortunately this proposal has nothing to do with goto.
>
> Elazar is correct that its a kind of subroutine call, just like an
> ordinary function call, except the scoping rules are different.
>
> And for the record, not everyone agrees that Dijkstra is correct about
> goto. Certainly unstructured code is harmful, but we use restricted
> forms of goto all the time, we just don't call it by that name:
>
> - loops
> - continue
> - break
> - if...else
> - function calls
> - exception handling
>
> Just like goto, these are all jumps which change the execution order of
> your code. And some people defend limited, careful use of explicit goto,
> including Donald Knuth.
>
>
> --
> Steve
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Steven D'Aprano
On Wed, Aug 15, 2018 at 08:35:35PM -0400, David Mertz wrote:

> Goto considered harmful.

Fortunately this proposal has nothing to do with goto.

Elazar is correct that its a kind of subroutine call, just like an 
ordinary function call, except the scoping rules are different.

And for the record, not everyone agrees that Dijkstra is correct about 
goto. Certainly unstructured code is harmful, but we use restricted 
forms of goto all the time, we just don't call it by that name:

- loops
- continue
- break
- if...else
- function calls
- exception handling

Just like goto, these are all jumps which change the execution order of 
your code. And some people defend limited, careful use of explicit goto, 
including Donald Knuth.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Abe Dillon
[Jacob Solinsky]

> these local variables are used quite often in the mutate methods, of which
> there are several dozen, so storing them by default saves a lot of typing.


There are several things you can do to alleviate the typing problem:
1) Get an IDE that has auto-complete. I recommend PyCharm Community
Edition, but there are several.
2) Use better naming: there are many shorter synonyms for "preceding" and
"succeding" and the word "morpheme" is redundant.
3) define as much as you can in the higher scopes:

C = re.compile("^[bpgkdtszSZjCmnywh]").match
M = re.compile("^[mn]$").match

class Morpheme:
  @property
  def pf(self): return self.pre.form

  @property
  def sf(self): return self.suc.form

  @property
  def precm(self): return C(self.pf)

  @property
  def sucmm(self): return M(self.sf)

  ...

I think what would help most of all is reorganizing your code. As I
understand it, a morpheme is the "smallest grammatical unit in a language"
 so maybe it makes more sense to
make the morpheme class fairly simple and not have a morpheme have any
inherent awareness of its preceding or succeeding morphemes. That seems
like the job of a larger construct that would deal with sequences of
morphemes. The way you have it right now, the morpheme seems to play a
double role a linked-list and a gramatical unit.

[Jacob Solinsky]

> I found cluttering the Morpheme object instances with flags and such to be
> inelegant, since these flags are only used by the mutate method.
>

That may be an indicator that you're trying to do too much with the
morpheme class.

[Jacob Solinsky]

> Also, without using a hacky solution like making Morpheme a subclass of
> types.SimpleNamespace, every new flag I might want to inject has to have a
> default value set in the __init__ method to prevent an AttributeError from
> being raised.


Yes, you typically want to define all your object attributes in __init__
otherwise your objects become fragile and can break if you don't call the
right methods in the right order. It's generally considered a bad idea to
define instance attributes anywhere else unless it's something like a
"private" helper method that gets called inside __init__.

[Jacob Solinsky]

> Anyways, I will look around in the mail list for discussions of Code
> blocks, now that I know they are called.


Don't take this the wrong way, but it might be better to acquaint yourself
with the set of tools already available before looking for new ones.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Steven D'Aprano
On Wed, Aug 15, 2018 at 01:52:27PM -0500, Jacob Solinsky wrote:

> -Jumping to a function as opposed to calling a function
> 
> When a function is jumped to, it inherits the variables in the 
> caller’s local namespace and is free to modify them or add new local 
> variables, unlike a normal function call, wherein the caller’s 
> namespace is inaccesible.

I think that the standard term for what you want is *dynamic scoping*.

http://wiki.c2.com/?DynamicScoping

http://leafo.net/guides/dynamic-scoping-in-lua.html

The most common language today that uses dynamic scoping is probably 
Emacs Lisp. Although dynamic scoping is very powerful, it is also harder 
to implement correctly (so I believe) and harder to reason about. It is 
generally considered that dynamic scoping is equivalent to the exclusive 
use of global variables (all functions see the same variables, no matter 
where they are defined), so the use of dynamic scoping gives up the 
benefits of local variables.

(See also "Global variables considered harmful".)


> At present, the only way I know of to 
> accomplish this is to bundle all variables in the caller method’s 
> namespace as properties of the method’s instance and have the callee 
> method modify those properties.

This would generally be considered a severe violation of the Law of 
Demeter, one of the most important principles for reducing coupling 
between software components:

https://www2.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/LawOfDemeter.htm

http://www.ccs.neu.edu/home/lieber/LoD.html

but also one of the most misunderstood. (Anyone who tells you that the 
LoD is "never use more than one dot" is wrong.)

As far as I am concerned, reducing coupling between software components 
is the single most important design principle there is. But what do we 
do when the problem you are trying to solve inherently has a lot of 
coupling between data components? I think that computer science doesn't 
have a lot to say about such hard problems, apart from "avoid them".


> Though it is easier to read code 
> written this way, it resulted in a great deal of redundancy in the 
> code I was writing. The task I was attempting to accomplish was 
> approximately this:

What you quoted was not a description of the task, but a concrete 
implementation of one possible solution to the task. You are describing 
*how* you want to do it, but you haven't described what *it* is.

This is not the place for it, but generally you should describe the 
functional requirements, not the implementation. You have Nouns, and 
Verbs, but what do you want to do with them? What is the high-level 
behaviour? If you focus on implementation too early, you may blind 
yourself to simpler solutions that accomplish the same end using a 
completely different means.

A light-hearted example:

"How do I turn the temperature of my refridgerator up? I need to boil 
some water, but the temperature control of the fridge only goes up to 
about 10°C (50°F)."

"Why don't you use the stove or microwave oven?"

"Because... that is to say... I... okay."


Since I don't understand your functional requirements, I don't know 
whether you are dealing with a situation which inherently requires high 
coupling, or if you are missing a solution which would avoid the need 
for global variables or dynamic scoping.


[...]
> Each subclass of Morpheme has its own slightly different mutate 
> method. Some subclasses of Morpheme needed to access and manipulate a 
> great deal of information about the verb and their surroundings,

This suggests to me that a solution might be to generate and pass around 
some sort of *context object* for each word you operate on. The obvious 
problems with this include:

- you have to generate that context object for every word, whether
  it will use it or not;

- in principle, the amount of context needed could be unbounded; 
  one word may only need information from the previous word, 
  while another word in a long run-on sentence may need information
  from half a page back.


> while 
> other subclasses’ mutate methods differed little from the default. 
> Most of the variables manipulated by the mutate method are not used by 
> any other methods of class Morpheme and thus should not be made 
> properties of the attached instance. What I wish I were able to do is 
> write many little methods that modify the same set of local variables 
> and compose them together into a complete mutate method. 

Closures are the exact equivalent of classes. If you have a solution 
(however clumsy) that works with classes, you should be able to re-write 
it in terms of closures. Whether that solution is less clumsy remains to 
be seen!

So you can have something like this:

def environment():
a = 1
b = 2
# define some closures
def change1():
nonlocal a
a += 1
def change2():
nonlocal a, b
a += 2
b += 3
   def inspect(

Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Elazar
I have no opinion on the proposal, but the equation with goto is dead
wrong. Yes, technically this is a goto. But so is a regular function call.
Jumping to a function makes thd code _easier_ to reason about, statically,
not harder. When you call an arbitrary function, you have no idea whether
it will return or not. When you jump to a function, you _know_ it will not
return. That's strictly more information, based solely on the syntax of the
statement.

Yes, if you have local functions mutating the state then jumpung to them
makes the code difficult to read. *but so is calling them*, with the
addition of the returning that you have to track.

Jumping to functions is procedural programming. There is no reasonfor it to
be "considered harmful" any more than calling funcions; indeed even less
so.

Elazar

On Wed, Aug 15, 2018, 17:42 Eric Fahlgren  wrote:

> How about just
> https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf
>
> On Wed, Aug 15, 2018 at 5:38 PM David Mertz  wrote:
>
>> Hmm.. link broke. Is this right?
>>
>>
>> https://www.google.com/url?sa=t&source=web&rct=j&url=https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf&ved=2ahUKEwi8lqHYqfDcAhXImOAKHeAzDmsQFjAEegQIBhAB&usg=AOvVaw1CZug_36-PbevItYXTb7SR
>>
>> On Wed, Aug 15, 2018, 8:35 PM David Mertz  wrote:
>>
>>> Goto considered harmful.
>>>
>>>
>>> https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf&ved=2ahUKEwi8lqHYqfDcAhXImOAKHeAzDmsQFjAEegQIBhAB&usg=AOvVaw1CZug_36-PbevItYXTb7SR
>>>
>>> On Wed, Aug 15, 2018, 3:52 PM Jacob Solinsky 
>>> wrote:
>>>
 -Jumping to a function as opposed to calling a function

 When a function is jumped to, it inherits the variables in the caller’s
 local namespace and is free to modify them or add new local variables,
 unlike a normal function call, wherein the caller’s namespace is
 inaccesible. At present, the only way I know of to accomplish this is to
 bundle all variables in the caller method’s namespace as properties of the
 method’s instance and have the callee method modify those properties.
 Though it is easier to read code written this way, it resulted in a great
 deal of redundancy in the code I was writing. The task I was attempting to
 accomplish was approximately this:

 class Verb:
 def __init__(self, parameters):
 self.parameters = parameters
 def conjugate(self):
 #Using the parameters, chose an appropriate list of
 morphemes to prefix and suffix to the verb
 self.morphemelist = morphemelist
 for morpheme in self.morphemelist:
 morpheme.mutate()
 returnstring = ‘'
 for morpheme in self.morphemelist:
 returnstring = returnstring + morpheme.form
 returnstring = returnstring

 class Morpheme:
 def __init__(self, verb, form, precedingmorpheme,
 succeedingmorpheme):
 self.verb = verb
 self.form = form
 self.precedingmorpheme = precedingmorpheme
 self.succeedingmorpheme = succeedingmorpheme
 def mutate(self):
 #Using the verb’s parameters and the type and form of
 the preceding and succeeding morpheme, mutate this morpheme’s form so that
   #a correct verb form is produced
 self.form = newform

 class Ban(Morpheme):
 def __init__(self, verb, form):
 super().__init__(verb, ‘ban’)
 def mutate(self):
 #This morpheme has mutation logic unique to itself but
 with many similarities to the default morpheme’s mutation logic
 self.form = newform

 Each subclass of Morpheme has its own slightly different mutate method.
 Some subclasses of Morpheme needed to access and manipulate a great deal of
 information about the verb and their surroundings, while other subclasses’
 mutate methods differed little from the default. Most of the variables
 manipulated by the mutate method are not used by any other methods of class
 Morpheme and thus should not be made properties of the attached instance.
 What I wish I were able to do is write many little methods that modify the
 same set of local variables and compose them together into a complete
 mutate method. This would be effectively equivalent to having the “jump to
 function” calls be replaced with the text in the function’s body, like a C
 language macrosubstitution, but without using anything like preprocessor
 directives.

 Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the
 syntax to jump to foo(a, b)

 def foo(a):
 return a + c

 def bar(a, c):
 return foo(a)

 def bazz(a, c):

Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Eric Fahlgren
How about just
https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf

On Wed, Aug 15, 2018 at 5:38 PM David Mertz  wrote:

> Hmm.. link broke. Is this right?
>
>
> https://www.google.com/url?sa=t&source=web&rct=j&url=https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf&ved=2ahUKEwi8lqHYqfDcAhXImOAKHeAzDmsQFjAEegQIBhAB&usg=AOvVaw1CZug_36-PbevItYXTb7SR
>
> On Wed, Aug 15, 2018, 8:35 PM David Mertz  wrote:
>
>> Goto considered harmful.
>>
>>
>> https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf&ved=2ahUKEwi8lqHYqfDcAhXImOAKHeAzDmsQFjAEegQIBhAB&usg=AOvVaw1CZug_36-PbevItYXTb7SR
>>
>> On Wed, Aug 15, 2018, 3:52 PM Jacob Solinsky 
>> wrote:
>>
>>> -Jumping to a function as opposed to calling a function
>>>
>>> When a function is jumped to, it inherits the variables in the caller’s
>>> local namespace and is free to modify them or add new local variables,
>>> unlike a normal function call, wherein the caller’s namespace is
>>> inaccesible. At present, the only way I know of to accomplish this is to
>>> bundle all variables in the caller method’s namespace as properties of the
>>> method’s instance and have the callee method modify those properties.
>>> Though it is easier to read code written this way, it resulted in a great
>>> deal of redundancy in the code I was writing. The task I was attempting to
>>> accomplish was approximately this:
>>>
>>> class Verb:
>>> def __init__(self, parameters):
>>> self.parameters = parameters
>>> def conjugate(self):
>>> #Using the parameters, chose an appropriate list of
>>> morphemes to prefix and suffix to the verb
>>> self.morphemelist = morphemelist
>>> for morpheme in self.morphemelist:
>>> morpheme.mutate()
>>> returnstring = ‘'
>>> for morpheme in self.morphemelist:
>>> returnstring = returnstring + morpheme.form
>>> returnstring = returnstring
>>>
>>> class Morpheme:
>>> def __init__(self, verb, form, precedingmorpheme,
>>> succeedingmorpheme):
>>> self.verb = verb
>>> self.form = form
>>> self.precedingmorpheme = precedingmorpheme
>>> self.succeedingmorpheme = succeedingmorpheme
>>> def mutate(self):
>>> #Using the verb’s parameters and the type and form of
>>> the preceding and succeeding morpheme, mutate this morpheme’s form so that
>>>   #a correct verb form is produced
>>> self.form = newform
>>>
>>> class Ban(Morpheme):
>>> def __init__(self, verb, form):
>>> super().__init__(verb, ‘ban’)
>>> def mutate(self):
>>> #This morpheme has mutation logic unique to itself but
>>> with many similarities to the default morpheme’s mutation logic
>>> self.form = newform
>>>
>>> Each subclass of Morpheme has its own slightly different mutate method.
>>> Some subclasses of Morpheme needed to access and manipulate a great deal of
>>> information about the verb and their surroundings, while other subclasses’
>>> mutate methods differed little from the default. Most of the variables
>>> manipulated by the mutate method are not used by any other methods of class
>>> Morpheme and thus should not be made properties of the attached instance.
>>> What I wish I were able to do is write many little methods that modify the
>>> same set of local variables and compose them together into a complete
>>> mutate method. This would be effectively equivalent to having the “jump to
>>> function” calls be replaced with the text in the function’s body, like a C
>>> language macrosubstitution, but without using anything like preprocessor
>>> directives.
>>>
>>> Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the
>>> syntax to jump to foo(a, b)
>>>
>>> def foo(a):
>>> return a + c
>>>
>>> def bar(a, c):
>>> return foo(a)
>>>
>>> def bazz(a, c):
>>> return foo(a)%
>>>
>>> c = 5
>>>
>>> call = bar(1, 3)
>>>
>>> jump = bazz(1, 3)
>>>
>>>
>>> After execution, call in the above code would be 6 and jump in the above
>>> code would be 4.
>>>
>>>
>>> ___
>>> Python-ideas mailing list
>>> Python-ideas@python.org
>>> https://mail.python.org/mailman/listinfo/python-ideas
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread David Mertz
Hmm.. link broke. Is this right?

https://www.google.com/url?sa=t&source=web&rct=j&url=https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf&ved=2ahUKEwi8lqHYqfDcAhXImOAKHeAzDmsQFjAEegQIBhAB&usg=AOvVaw1CZug_36-PbevItYXTb7SR

On Wed, Aug 15, 2018, 8:35 PM David Mertz  wrote:

> Goto considered harmful.
>
>
> https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf&ved=2ahUKEwi8lqHYqfDcAhXImOAKHeAzDmsQFjAEegQIBhAB&usg=AOvVaw1CZug_36-PbevItYXTb7SR
>
> On Wed, Aug 15, 2018, 3:52 PM Jacob Solinsky 
> wrote:
>
>> -Jumping to a function as opposed to calling a function
>>
>> When a function is jumped to, it inherits the variables in the caller’s
>> local namespace and is free to modify them or add new local variables,
>> unlike a normal function call, wherein the caller’s namespace is
>> inaccesible. At present, the only way I know of to accomplish this is to
>> bundle all variables in the caller method’s namespace as properties of the
>> method’s instance and have the callee method modify those properties.
>> Though it is easier to read code written this way, it resulted in a great
>> deal of redundancy in the code I was writing. The task I was attempting to
>> accomplish was approximately this:
>>
>> class Verb:
>> def __init__(self, parameters):
>> self.parameters = parameters
>> def conjugate(self):
>> #Using the parameters, chose an appropriate list of
>> morphemes to prefix and suffix to the verb
>> self.morphemelist = morphemelist
>> for morpheme in self.morphemelist:
>> morpheme.mutate()
>> returnstring = ‘'
>> for morpheme in self.morphemelist:
>> returnstring = returnstring + morpheme.form
>> returnstring = returnstring
>>
>> class Morpheme:
>> def __init__(self, verb, form, precedingmorpheme,
>> succeedingmorpheme):
>> self.verb = verb
>> self.form = form
>> self.precedingmorpheme = precedingmorpheme
>> self.succeedingmorpheme = succeedingmorpheme
>> def mutate(self):
>> #Using the verb’s parameters and the type and form of the
>> preceding and succeeding morpheme, mutate this morpheme’s form so that
>>   #a correct verb form is produced
>> self.form = newform
>>
>> class Ban(Morpheme):
>> def __init__(self, verb, form):
>> super().__init__(verb, ‘ban’)
>> def mutate(self):
>> #This morpheme has mutation logic unique to itself but
>> with many similarities to the default morpheme’s mutation logic
>> self.form = newform
>>
>> Each subclass of Morpheme has its own slightly different mutate method.
>> Some subclasses of Morpheme needed to access and manipulate a great deal of
>> information about the verb and their surroundings, while other subclasses’
>> mutate methods differed little from the default. Most of the variables
>> manipulated by the mutate method are not used by any other methods of class
>> Morpheme and thus should not be made properties of the attached instance.
>> What I wish I were able to do is write many little methods that modify the
>> same set of local variables and compose them together into a complete
>> mutate method. This would be effectively equivalent to having the “jump to
>> function” calls be replaced with the text in the function’s body, like a C
>> language macrosubstitution, but without using anything like preprocessor
>> directives.
>>
>> Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the
>> syntax to jump to foo(a, b)
>>
>> def foo(a):
>> return a + c
>>
>> def bar(a, c):
>> return foo(a)
>>
>> def bazz(a, c):
>> return foo(a)%
>>
>> c = 5
>>
>> call = bar(1, 3)
>>
>> jump = bazz(1, 3)
>>
>>
>> After execution, call in the above code would be 6 and jump in the above
>> code would be 4.
>>
>>
>> ___
>> Python-ideas mailing list
>> Python-ideas@python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread David Mertz
Goto considered harmful.

https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf&ved=2ahUKEwi8lqHYqfDcAhXImOAKHeAzDmsQFjAEegQIBhAB&usg=AOvVaw1CZug_36-PbevItYXTb7SR

On Wed, Aug 15, 2018, 3:52 PM Jacob Solinsky 
wrote:

> -Jumping to a function as opposed to calling a function
>
> When a function is jumped to, it inherits the variables in the caller’s
> local namespace and is free to modify them or add new local variables,
> unlike a normal function call, wherein the caller’s namespace is
> inaccesible. At present, the only way I know of to accomplish this is to
> bundle all variables in the caller method’s namespace as properties of the
> method’s instance and have the callee method modify those properties.
> Though it is easier to read code written this way, it resulted in a great
> deal of redundancy in the code I was writing. The task I was attempting to
> accomplish was approximately this:
>
> class Verb:
> def __init__(self, parameters):
> self.parameters = parameters
> def conjugate(self):
> #Using the parameters, chose an appropriate list of
> morphemes to prefix and suffix to the verb
> self.morphemelist = morphemelist
> for morpheme in self.morphemelist:
> morpheme.mutate()
> returnstring = ‘'
> for morpheme in self.morphemelist:
> returnstring = returnstring + morpheme.form
> returnstring = returnstring
>
> class Morpheme:
> def __init__(self, verb, form, precedingmorpheme,
> succeedingmorpheme):
> self.verb = verb
> self.form = form
> self.precedingmorpheme = precedingmorpheme
> self.succeedingmorpheme = succeedingmorpheme
> def mutate(self):
> #Using the verb’s parameters and the type and form of the
> preceding and succeeding morpheme, mutate this morpheme’s form so that
>   #a correct verb form is produced
> self.form = newform
>
> class Ban(Morpheme):
> def __init__(self, verb, form):
> super().__init__(verb, ‘ban’)
> def mutate(self):
> #This morpheme has mutation logic unique to itself but
> with many similarities to the default morpheme’s mutation logic
> self.form = newform
>
> Each subclass of Morpheme has its own slightly different mutate method.
> Some subclasses of Morpheme needed to access and manipulate a great deal of
> information about the verb and their surroundings, while other subclasses’
> mutate methods differed little from the default. Most of the variables
> manipulated by the mutate method are not used by any other methods of class
> Morpheme and thus should not be made properties of the attached instance.
> What I wish I were able to do is write many little methods that modify the
> same set of local variables and compose them together into a complete
> mutate method. This would be effectively equivalent to having the “jump to
> function” calls be replaced with the text in the function’s body, like a C
> language macrosubstitution, but without using anything like preprocessor
> directives.
>
> Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the
> syntax to jump to foo(a, b)
>
> def foo(a):
> return a + c
>
> def bar(a, c):
> return foo(a)
>
> def bazz(a, c):
> return foo(a)%
>
> c = 5
>
> call = bar(1, 3)
>
> jump = bazz(1, 3)
>
>
> After execution, call in the above code would be 6 and jump in the above
> code would be 4.
>
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Chris Angelico
On Thu, Aug 16, 2018 at 8:53 AM, Jacob Solinsky  wrote:
> What I had hoped to do was use a preamble code block to collect all of the
> most common queries called by the mutate function in the local namespace,
> for example
>
> C = 'bpgkdtszSZjCmnywh'
> M = 'mn'
>
>
> class Morpheme:
> #stuff
>
> def preamble(self):
>
> ps = self.precedingmorpheme.form
> ss = self.succeedingmorpheme.form
> ssc = re.match(f'^[{C}]', self.succedingmorpheme.form) #Whether or not
> the following morpheme is consonant initial
> ssm = re.match(f'[{M}]$', self.precedingmorpheme.form) #Whether or not
> the preceding morpheme is nasal final
>
> these local variables are used quite often in the mutate methods, of which
> there are several dozen, so storing them by default saves a lot of typing.
>

Ahh, I see what you mean. I was thinking the other way - a single
mutate function that has a part in there saying "now run the code
block for this particular subclass".

What would be really nice would be something like:

from preamble() import *

I'm fairly sure that (per se) isn't going to fly, but it would be
interesting as a concept. Would need a new spelling.

The quirky part of my brain is trying to figure if class namespace can
be abused for this.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Jacob Solinsky
What I had hoped to do was use a preamble code block to collect all of the
most common queries called by the mutate function in the local namespace,
for example

C = 'bpgkdtszSZjCmnywh'
M = 'mn'


class Morpheme:
#stuff

def preamble(self):

ps = self.precedingmorpheme.form
ss = self.succeedingmorpheme.form
ssc = re.match(f'^[{C}]', self.succedingmorpheme.form) #Whether or not
the following morpheme is consonant initial
ssm = re.match(f'[{M}]$', self.precedingmorpheme.form) #Whether or not
the preceding morpheme is nasal final

these local variables are used quite often in the mutate methods, of which
there are several dozen, so storing them by default saves a lot of typing.



class Ban(Morpheme):
def __init__(self):
  super().__init__(verb, precedingmorpheme, succeedingmorpheme,
form = 'ban')
def mutate(self):
  self.preamble()%
  if ps[-1] == 'd':
 self.form = 'p' + self.form[1:]
 self.preceding.form = ''
  if ssc:
 self.form = self.form + 'E'
  if ssm:
 self.form = re.sub('an', 'An', self.form)

What I actually ended up doing is placing these queries in the Morpheme
__init__ method
def __init__(self, ...):
self.ps = self.precedingmorpheme.form
self.ss = self.succeedingmorpheme.form
self.ssc = re.match(f'^[{C}]', self.succedingmorpheme.form)
#Whether or not the following morpheme is consonant initial
self.ssm = re.match(f'[{M}]$', self.precedingmorpheme.form)
#Whether or not the preceding morpheme is nasal final

This works perfectly fine, but I found cluttering the Morpheme object
instances with flags and such to be inelegant, since these flags are only
used by the mutate method. Also, without using a hacky solution like making
Morpheme a subclass of types.SimpleNamespace, every new flag I might want
to inject has to have a default value set in the __init__ method to prevent
an AttributeError from being raised. Anyways, I will look around in the
mail list for discussions of Code blocks, now that I know they are called.


On Wed, 15 Aug 2018, 16:41 Abe Dillon,  wrote:

> Jumping into functions that mutate variables in the calling scope sounds a
> lot like "GoTo"  which
> is notorious for leading to code that's very hard to reason about. Your
> functions would implicitly require that you assign variables in the calling
> scope before calling the function instead of explicitly requiring them in
> the function's signature. That can be very confusing.
>
> A lot of times, when I find that my function call signatures have become
> unwieldy, it's a sign that I need to bundle a lot of related variables into
> an object and either define methods on that object or pass that object to
> functions instead of the large number of variables that it encapsulates.
> You just use 'self' as a sort-of back-pack that carries around what you
> need.
>
> It's difficult to see what you're after from your Verb and Morpheme
> example. They don't seem to call any functions that use variables from the
> caller's scope. Can you flesh that out a bit better?
>
>
> On Wed, Aug 15, 2018 at 3:24 PM, Chris Angelico  wrote:
>
>> On Thu, Aug 16, 2018 at 4:52 AM, Jacob Solinsky 
>> wrote:
>> > -Jumping to a function as opposed to calling a function
>> >
>> > When a function is jumped to, it inherits the variables in the caller’s
>> local namespace and is free to modify them or add new local variables,
>> unlike a normal function call, wherein the caller’s namespace is
>> inaccesible. At present, the only way I know of to accomplish this is to
>> bundle all variables in the caller method’s namespace as properties of the
>> method’s instance and have the callee method modify those properties.
>> Though it is easier to read code written this way, it resulted in a great
>> deal of redundancy in the code I was writing.
>> >
>>
>> > Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the
>> syntax to jump to foo(a, b)
>> >
>> > def foo(a):
>> > return a + c
>> >
>> > def bar(a, c):
>> > return foo(a)
>> >
>> > def bazz(a, c):
>> > return foo(a)%
>> >
>> > c = 5
>> >
>> > call = bar(1, 3)
>> >
>> > jump = bazz(1, 3)
>> >
>> >
>> > After execution, call in the above code would be 6 and jump in the
>> above code would be 4.
>>
>> You're trying to shed encapsulation (by having the jumped-to function
>> operate in the "caller's" namespace), but also pass parameters to it.
>> That's going to cause a lot of confusion.
>>
>> I'm sympathetic to the problem, but I don't think functions are the
>> solution here. You want some form of code block. There've been a
>> number of proposals along those lines, and so far, not one of them has
>> been really implementable. Check out some of the prior theories and
>> see if one of them will work for you.
>>
>> ChrisA
>> ___
>> Python-ideas 

Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Abe Dillon
Sorry for the double post, but I wanted to make sure you saw my original
misplaced post:

Jumping into functions that mutate variables in the calling scope sounds a
lot like "GoTo"  which is
notorious for leading to code that's very hard to reason about. Your
functions would implicitly require that you assign variables in the calling
scope before calling the function instead of explicitly requiring them in
the function's signature. That can be very confusing.

A lot of times, when I find that my function call signatures have become
unwieldy, it's a sign that I need to bundle a lot of related variables into
an object and either define methods on that object or pass that object to
functions instead of the large number of variables that it encapsulates.
You just use 'self' as a sort-of back-pack that carries around what you
need.

It's difficult to see what you're after from your Verb and Morpheme
example. They don't seem to call any functions that use variables from the
caller's scope. Can you flesh that out a bit more to show where the problem
arrises?
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Abe Dillon
[Chris Angelico]

> Drop the word "function" and it's no longer about a goto - it's about
> a block of code that can be deposited into another context.


The only context I've used goto is in a TI-83 scientific calculator, but in
that, it was just about jumping around to different labels in code and had
nothing to do with functions. Though this may not have been the "canonical"
goto that Dijkstra considered harmful.

[Chris Angelico]

> By the way:


> > It's difficult to see what you're after from your Verb and Morpheme
> example.


> You're responding to MY post, which is a response to Jacob's. Please
> watch your use of pronouns; it would help a lot if you weren't top
> posting, and were directly responding to specific people's specific
> comments.


Sorry, I ran into a lot of problems trying to use the Google Groups
interface to post, so I've resorted to strictly using email. Unfortunately,
that makes the structure of the conversation less obvious to me. I'll try
to be more mindful of this in the future.

On Wed, Aug 15, 2018 at 4:58 PM, Chris Angelico  wrote:

> On Thu, Aug 16, 2018 at 7:40 AM, Abe Dillon  wrote:
> > Jumping into functions that mutate variables in the calling scope sounds
> a
> > lot like "GoTo" which is notorious for leading to code that's very hard
> to
> > reason about. Your functions would implicitly require that you assign
> > variables in the calling scope before calling the function instead of
> > explicitly requiring them in the function's signature. That can be very
> > confusing.
>
> Drop the word "function" and it's no longer about a goto - it's about
> a block of code that can be deposited into another context. If you
> were to copy and paste that code, its meaning would be defined by
> where it is used; the idea of a "code block" is that you can do that
> with something that can be passed around like a function, but isn't a
> function.
>
> We could borrow a term from the Python grammar and call it a "suite",
> perhaps, but "code block" is probably the best term. As mentioned,
> there have been previous proposals along these lines.
>
> By the way:
>
> > It's difficult to see what you're after from your Verb and Morpheme
> example.
>
> You're responding to MY post, which is a response to Jacob's. Please
> watch your use of pronouns; it would help a lot if you weren't top
> posting, and were directly responding to specific people's specific
> comments.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Chris Angelico
On Thu, Aug 16, 2018 at 7:40 AM, Abe Dillon  wrote:
> Jumping into functions that mutate variables in the calling scope sounds a
> lot like "GoTo" which is notorious for leading to code that's very hard to
> reason about. Your functions would implicitly require that you assign
> variables in the calling scope before calling the function instead of
> explicitly requiring them in the function's signature. That can be very
> confusing.

Drop the word "function" and it's no longer about a goto - it's about
a block of code that can be deposited into another context. If you
were to copy and paste that code, its meaning would be defined by
where it is used; the idea of a "code block" is that you can do that
with something that can be passed around like a function, but isn't a
function.

We could borrow a term from the Python grammar and call it a "suite",
perhaps, but "code block" is probably the best term. As mentioned,
there have been previous proposals along these lines.

By the way:

> It's difficult to see what you're after from your Verb and Morpheme example.

You're responding to MY post, which is a response to Jacob's. Please
watch your use of pronouns; it would help a lot if you weren't top
posting, and were directly responding to specific people's specific
comments.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Abe Dillon
Jumping into functions that mutate variables in the calling scope sounds a
lot like "GoTo"  which is
notorious for leading to code that's very hard to reason about. Your
functions would implicitly require that you assign variables in the calling
scope before calling the function instead of explicitly requiring them in
the function's signature. That can be very confusing.

A lot of times, when I find that my function call signatures have become
unwieldy, it's a sign that I need to bundle a lot of related variables into
an object and either define methods on that object or pass that object to
functions instead of the large number of variables that it encapsulates.
You just use 'self' as a sort-of back-pack that carries around what you
need.

It's difficult to see what you're after from your Verb and Morpheme
example. They don't seem to call any functions that use variables from the
caller's scope. Can you flesh that out a bit better?


On Wed, Aug 15, 2018 at 3:24 PM, Chris Angelico  wrote:

> On Thu, Aug 16, 2018 at 4:52 AM, Jacob Solinsky 
> wrote:
> > -Jumping to a function as opposed to calling a function
> >
> > When a function is jumped to, it inherits the variables in the caller’s
> local namespace and is free to modify them or add new local variables,
> unlike a normal function call, wherein the caller’s namespace is
> inaccesible. At present, the only way I know of to accomplish this is to
> bundle all variables in the caller method’s namespace as properties of the
> method’s instance and have the callee method modify those properties.
> Though it is easier to read code written this way, it resulted in a great
> deal of redundancy in the code I was writing.
> >
>
> > Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the
> syntax to jump to foo(a, b)
> >
> > def foo(a):
> > return a + c
> >
> > def bar(a, c):
> > return foo(a)
> >
> > def bazz(a, c):
> > return foo(a)%
> >
> > c = 5
> >
> > call = bar(1, 3)
> >
> > jump = bazz(1, 3)
> >
> >
> > After execution, call in the above code would be 6 and jump in the above
> code would be 4.
>
> You're trying to shed encapsulation (by having the jumped-to function
> operate in the "caller's" namespace), but also pass parameters to it.
> That's going to cause a lot of confusion.
>
> I'm sympathetic to the problem, but I don't think functions are the
> solution here. You want some form of code block. There've been a
> number of proposals along those lines, and so far, not one of them has
> been really implementable. Check out some of the prior theories and
> see if one of them will work for you.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Chris Angelico
On Thu, Aug 16, 2018 at 4:52 AM, Jacob Solinsky  wrote:
> -Jumping to a function as opposed to calling a function
>
> When a function is jumped to, it inherits the variables in the caller’s local 
> namespace and is free to modify them or add new local variables, unlike a 
> normal function call, wherein the caller’s namespace is inaccesible. At 
> present, the only way I know of to accomplish this is to bundle all variables 
> in the caller method’s namespace as properties of the method’s instance and 
> have the callee method modify those properties. Though it is easier to read 
> code written this way, it resulted in a great deal of redundancy in the code 
> I was writing.
>

> Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the syntax 
> to jump to foo(a, b)
>
> def foo(a):
> return a + c
>
> def bar(a, c):
> return foo(a)
>
> def bazz(a, c):
> return foo(a)%
>
> c = 5
>
> call = bar(1, 3)
>
> jump = bazz(1, 3)
>
>
> After execution, call in the above code would be 6 and jump in the above code 
> would be 4.

You're trying to shed encapsulation (by having the jumped-to function
operate in the "caller's" namespace), but also pass parameters to it.
That's going to cause a lot of confusion.

I'm sympathetic to the problem, but I don't think functions are the
solution here. You want some form of code block. There've been a
number of proposals along those lines, and so far, not one of them has
been really implementable. Check out some of the prior theories and
see if one of them will work for you.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-15 Thread Jonathan Fine
Hi Jacob

Thank you for your problem. I'll focus on your simple example (lightly
edited for clarity)

> Let foo(a, b) be the syntax to call foo(a, b), and foo(a, b)% be the syntax 
> to jump to foo(a, b)
>
> c = 5
>
> def foo(a):
> return a + c
>
> def bar(a, c):
> return foo(a)
>
> def bazz(a, c):
> return foo(a)%
>
> call = bar(1, 3) # 6, being 1 + 5
> bazz(1, 3) # 4, being 1 + 3

This may allow you to solve your verb and morpheme problem. But I hope
there's an easier way. One that can be done using Python as it is now.

My understanding is that you want a stack. Similar to the Python's
function call stack, but with something extra. So that functions
execute in an richer context.

Here's an idea. Start by giving us a toy example of a calculation
you'd like to do. Then the problem is: how to do this in Python.

By the way, are there any existing Python libraries for this sort of thing?

I hope this helps.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/