[Python-ideas] Before and after the colon in funciton defs.

Nick Coghlan ncoghlan at gmail.com
Thu Sep 22 15:58:41 CEST 2011


On Thu, Sep 22, 2011 at 6:21 PM, Paul Moore <p.f.moore at gmail.com> wrote:
> A concern I have with the expression variant is that I don't
> understand what it would mean except in the restricted contexts it's
> been discussed in. Can you describe the semantics of
>
>    static EXPR
>
> in isolation, so that we're not just interpreting it in terms of its
> use in an assignment, and can understand the wider implications?

It isn't really that different from the statement version - a
definition time expression would be calculated at definition time by
the interpreter and the resulting value cached on the function object.
At execution time, the cached value would be used in place of the
original expression. (As an implementation detail, this would likely
work by assigning such expressions an index in the function's closure
list and populating them at definition time as cells)

To use the classic "adder in a loop" example:

    # default argument hack
    adders = []
    for i in range(1):
        def adder(x, i=i):
            return x + i
        adders.append(adder)

    # default argument hack (lambda)
    adders = [(lambda x, i=i: x + i) for i in range(10)]

    # Definition time statement (lambda variant not supported)
    adders = []
    for i in range(1):
        def adder(x):
            atdef i=i   # Could conceivably shorten this to just 'atdef i'
            return x + i
        adders.append(adder)

    # Definition time expression (using same parenthesis rules as
yield expressions)
    adders = []
    for i in range(1):
        def adder(x):
            return x + (atdef i)
        adders.append(adder)

    # Definition time expression (lambda)
    adders = [(lambda x: x + (atdef i)) for i in range(10)]

I think there's a case to be made for the expression version - it's
likely to require less boilerplate than the statement version in
simple cases and is compatible with comprehension syntax (since it can
be embedded inside a lambda expression). The analogy with yield
expressions is a reasonable one - but instead of coming from send(),
the result of the expression is retrieved from the cache on the
function object.

The other advantage of the expression version is that it avoids the
issue of definition a new namespace where names can be looked up.
Instead, it's just a mechanism for caching the values of certain
expressions at definition time - at execution time, those values can
then either be used directly or else assigned to an ordinary local
variable.

I wasn't initially a fan of the idea, but it's growing on me.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list