(original) (raw)
If type annotations are treated like implicit lambdas, then that's a first step to something similar to Lisp's "special forms". A full generalization of that would allow, for example, logging.debug to not evaluate its args unless debugging is turned on (I use a logging.debug wrapper that allows lambdas as args, and evaluates them if debugging is turned on).
Maybe a better question is whether we want "special forms" in Python. It complicates some things but simplifies others. But things that satisfy Lisp programmers might not make Python programmers happy. ;)
On 4 November 2017 at 09:42, Guido van Rossum <guido@python.org> wrote:
I'm very worried about trying to come up with a robust implementation of this in under 12 weeks. By contrast, the stringification that Ćukasz is proposing feels eminently doable.--On Sat, Nov 4, 2017 at 6:51 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:On 4 November 2017 at 00:40, Guido van Rossum <guido@python.org> wrote:
\> IMO the inability of referencing class-level definitions from annotations on
\> methods pretty much kills this idea.
If we decided we wanted to make it work, I think the key runtime
building block we would need is a new kind of cell reference: an
IndirectAttributeCell.
Those would present the same interface as a regular nonlocal cell (so
it could be stored in \_\_closure\_\_ just as regular cells are, and
accessed the same way when the function body is executed), but
internally it would hold two references:
\- one to another cell object (\_\_class\_\_ for this use case)
\- an attribute name on the target object that get/set/del operations
on the indirect cell's value should affect
As Python code:
class IndirectAttributeCell:
def \_\_new\_\_(cls, cell, attr):
self.\_cell = cell
self.\_attr = attr
@property
def cell\_contents(self):
return getattr(self.\_cell.cell\_contents, self.\_attr)
@cell\_contents.setter
def cell\_contents(self, value):
setattr(self.\_cell.cell\_contents, self.\_attr, value)
@cell\_contents.deleter
def cell\_contents(self):
delattr(self.\_cell.cell\_contents, self.\_attr)
The class body wouldn't be able to evaluate the thunks (since
\`\_\_class\_\_\` wouldn't be set yet), but \`\_\_init\_subclass\_\_\`
implementations could, as could class decorators.
It would require some adjustment in the compiler as well (in order to
pass the class level attribute definitions down to these implicitly
defined scopes as a new kind of accessible external namespace during
the symbol analysis pass, as well as to register the use of
"\_\_class\_\_" if one of the affected names was referenced), but I think
it would work at least at a technical level (by contrast, every other
idea I came up with back when I was working on the list comprehension
change was sufficiently flawed that it fell apart within a few hours
of starting to tinker with the idea).
As an added bonus, we could potentially also extend the same
permissive name resolution semantics to the implicit scopes used in
comprehensions, such that it was only the explicitly defined scopes
(i.e. lambda expressions, function definitions, and nested classes)
that lost implicit access to the class level variables.
Cheers,
Nick.
P.S. If we subsequently decided to elevate expression thunks to a
first class language primitive, they shouldn't need any further
semantic enhancements beyond that one, since the existing scoping
rules already give the desired behaviour at module and function scope.
--Guido van Rossum (python.org/\~guido)
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/ pludemann%40google.com