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

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, <jfine2358@gmail.com> wrote:

Jacob Solinsky writes:
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: turnbull@sk.tsukuba.ac.jp University of Tsukuba Tel: 029-853-5175 Tennodai 1-1-1, Tsukuba 305-8573 JAPAN

Jacob Solinsky wrote:
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.ht... https://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.h... -- Jonathan

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 <https://www.nltk.org/>, TextBlob <https://textblob.readthedocs.io/en/dev/>, PyGlot <https://polyglot.readthedocs.io/en/latest/MorphologicalAnalysis.html>, 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 <jacobsolinsky@gmail.com> 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, <abedillon@gmail.com> wrote:

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 <jacobsolinsky@gmail.com> wrote:

Jacob Solinsky writes:
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: turnbull@sk.tsukuba.ac.jp University of Tsukuba Tel: 029-853-5175 Tennodai 1-1-1, Tsukuba 305-8573 JAPAN

Jacob Solinsky wrote:
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.ht... https://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.h... -- Jonathan

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 <https://www.nltk.org/>, TextBlob <https://textblob.readthedocs.io/en/dev/>, PyGlot <https://polyglot.readthedocs.io/en/latest/MorphologicalAnalysis.html>, 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 <jacobsolinsky@gmail.com> 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, <abedillon@gmail.com> wrote:

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 <jacobsolinsky@gmail.com> wrote:
participants (4)
-
Abe Dillon
-
Jacob Solinsky
-
Jonathan Fine
-
Stephen J. Turnbull