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

MRAB python at mrabarnett.plus.com
Thu Sep 22 17:55:18 CEST 2011


On 22/09/2011 14:58, Nick Coghlan wrote:
> 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.
>
There are 2 issues here:

1. Shared variables:

     def accumulate(n):
         shared total = 0
         total += n
         return total

2. Definition-time expressions:

     adders = []
     for i in range(1):
         def adder(x):
             return x + deftime i
         adders.append(adder)



More information about the Python-ideas mailing list