I was thinking about introducing new opcodes for implementing static
variables. Not sure though. All of the ideas actually do the same thing.
The difference is approach.

On Fri, May 28, 2021 at 6:57 PM Chris Angelico <ros...@gmail.com> wrote:

> On Fri, May 28, 2021 at 10:11 PM Steven D'Aprano <st...@pearwood.info>
> wrote:
> >
> > On Fri, May 28, 2021 at 04:20:15AM +1000, Chris Angelico wrote:
> >
> > > def f():
> > >     static x = 0
> > >     x += 1
> > >     yield x
> > >
> > > next(f())
> > > next(f())
> > > next(f())
> > >
> > > will yield 1 every time?
> >
> > I think that this example has just about convinced me that Chris'
> > approach is correct. I wasn't thinking about generators or recursion.
> >
> > I think that closure nonlocals are almost as fast as locals, so we might
> > be able to use the closure mechanism to get this. Something vaguely
> > like this:
> >
> >     def func():
> >         static var = initial
> >         body
> >
> > is transformed into:
> >
> >     def factory():
> >         var = initial
> >         def func():
> >             nonlocal var
> >             body
> >         return func
> >     func = factory()
> >
> >
> > except that the factory is never actually exposed to Python code.
>
> I think that would probably work, but even better would be if the
> outer function didn't actually exist. A bit of playing around suggests
> that LOAD_DEREF could just work here. If you have multiple levels of
> nonlocals, the function flattens them out into a tuple in
> f.__closure__, identifying them by index. Statics could be another
> level of nonlocals that doesn't actually require a function as such.
>
> In terms of describing the semantics, I think this is probably the
> cleanest way to give a pure-Python equivalent.
>
> > It would be nice if there was some way to introspect the value of `var`
> > but if there is a way to do it I don't know it.
>
> No idea about other implementations, but in CPython, you can look at
> f.__closure__[*].cell_contents, but you'd need to know the mapping
> from static name to lookup index. I think the corresponding names are
> in f.__code__.co_freevars, but I'm not sure if there are any other
> things that go in there.
>
> > We might not even need new syntax if we could do that transformation
> > using a decorator.
> >
> >
> >     @static(var=initial)
> >     def func():
> >         body
> >
>
> Hmm, there'd need to be some transformations, since the code generator
> is always going to use lexical scope. You can't magically change a
> LOAD_GLOBAL into a LOAD_DEREF with a decorator - the only way would be
> to do some fairly hairy rewriting, and you might lose a lot of the
> efficiency. This really needs proper compiler support, and if it gets
> compiler support, it may as well have dedicated syntax.
>
> ChrisA
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/7CXYEBUKVCLB3O6APOG5TUMPACWFVUGY/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/V4QYXAECONMCXQZMFSEH2U7AUD3N4HZT/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to