[Python-ideas] explicitation lines in python ?

Carl M. Johnson cmjohnson.mailinglist at gmail.com
Mon Jul 12 05:39:42 CEST 2010


On Sun, Jun 27, 2010 at 8:25 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:

> The availability of "nonlocal" binding semantics also makes the
> semantics much easier to define than they were in those previous
> discussions (the lack of clear semantics for name binding statements
> with an attached local namespace was the major factor blocking
> creation of a reference implementation for this proposal back then).
>
> For example:
>
>  c = sqrt(a*a + b*b) where:
>    a = retrieve_a()
>    b = retrieve_b()
>
> could translate to something like:
>
>  def _anon(): # *(see below)
>    nonlocal c
>    a = retrieve_a()
>    b = retrieve_b()
>    c = sqrt(a*a + b*b)
>  _anon()
>
> *(unlike Python code, the compiler can make truly anonymous functions
> by storing them solely on the VM stack. It already does this when
> executing class definitions):

I like this idea, but I would tweak it slightly. Maybe we should say

EXPRESSION where:
    BLOCK

is equivalent to

def _():
    BLOCK
    return EXPRESSION
_()

That way, c = a where: a = 7 would be equivalent to

def _():
   a = 7
   return a
c = _()

One advantage of this equivalence is it would make it easier to work
around a longstanding scoping gotcha. A naïve coder might expect this
code to print out numbers 0 to 4:

    >>> fs = []
    >>> for n in range(5):
    ...     def f():
    ...         print(item)
    ...     fs.append(f)
    ...
    >>> [f() for f in fs]
    4
    4
    4
    4
    4
    [None, None, None, None, None]

I think we all have enough experience to know this isn’t a totally
unrealistic scenario. I personally stumbled into when I was trying to
create a class by looping through a set of method names.

To get around it, one could use a where clause like so:

fs = []
for n in range(5):
    fs.append(f) where:
        shadow = n
        def f():
            print(shadow)

This would print out 0 to 4 as expected and be equivalent to

    >>> fs = []
    >>> for n in range(5):
    ...     def _():
    ...         shadow = n
    ...         def f():
    ...             print(shadow)
    ...         fs.append(f)
    ...     _()
    ...
    >>> [f() for f in fs]
    0
    1
    2
    3
    4
    [None, None, None, None, None]

I think a where-clause with def-like namespace semantics would be a
positive addition to Python, once the moratorium is up.

-- Carl Johnson



More information about the Python-ideas mailing list