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

> Jumping into functions that mutate variables in the calling scope sounds a
> lot like "GoTo" <https://en.wikipedia.org/wiki/Considered_harmful> 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 <ros...@gmail.com> wrote:
>
>> On Thu, Aug 16, 2018 at 4:52 AM, Jacob Solinsky <jacobsolin...@gmail.com>
>> 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/
>
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to