[Python-ideas] pep-0484 - Forward references and Didactics - be orthogonal

Terry Reedy tjreedy at udel.edu
Tue Aug 25 20:07:33 CEST 2015


On 8/25/2015 12:19 PM, Erik Bray wrote:
> On Tue, Aug 25, 2015 at 11:15 AM, Terry Reedy <tjreedy at udel.edu> wrote:
>> 2. Class statements would initially create an empty class bound to the class
>> name.  This could break back compatibility, and would require cleanup in
>> case of a syntax error in the body. This would be similar to import
>> statements initially putting a empty module in sys.modules to support
>> circular imports.  This is messy and still bug prone is use.

'in use'.

> I have been thinking about this lately in a different context, and I
> would very much favor this approach.  I think in large part because it
> works this way for modules it would make sense for it to work for
> classes as well.  The fact that ClassName is bound to an object that
> will *eventually* become the class as soon as the parser has read in:
>
>      class ClassName:
>
> represents, to me (and I would suspect to many students as well), the
> least astonishment.
>
> I realize it would be a very non-trivial change, however.

It might be more useful to have def statements work that way (bind name 
to blank function object).  Then

def fac(n, _fac=fac):  # less confusing than 'fac=fac'
     return _fac(n-1)*n if n > 1 else 1

would actually be recursive regardless of external name bindings.

But as is the case with modules, exposing incomplete objects easily 
leads to buggy code, such as def f(n, code=f.__code__): pass

>>> what students have to write instead:
>>>
>>> #-------------bad workaround----------------------------\
>>> class Tree:
>>>       def __init__(self, left: 'Tree', right: 'Tree'):
>>>           self.left = left
>>>           self.right = right

> What about:
>>>> class Tree:
> ...     """Forward declaration of Tree type."""
> ...
>>>> class Tree(Tree):
> ...     """Tree implementation."""
> ...     def __init__(self, left: Tree, right: Tree):
> ...         self.left = left
> ...         self.right = right
>
> A little ugly, and potentially error-prone (but only, I think, in
> exceptional cases).  It's also a decent opportunity to teach something
> about forward-declaration, which I think is worth knowing about.  And
> I think this makes what's going on clearer than the string-based
> workaround.

I like this better than my decorator version. Notice that if Python were 
changed so that 'Tree' were bound to a blank class first thing, then 
Tree(Tree) would be subclassing itself, breaking code like the above 
unless a special rule was added to remove a class from its list of 
subclasses.

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list