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

Matt Joiner anacrolix at gmail.com
Mon Sep 19 21:05:00 CEST 2011


-1 plx

On Mon, Sep 19, 2011 at 11:22 PM, Sven Marnach <sven at marnach.net> wrote:
> Nick Coghlan wrote:
>> [...] allow a sequence of 'implicit locals' to be defined within
>> square brackets after the parameter list.
>
> I'm not quite sure whether the benefits of this proposal are worth the
> further rococoization of the language.  As far as I can see, the only
> benefit is keeping function signatures clean.
>
> Looking at the use cases one by one:
>
>> Micro-optimisation:
>>     # Current Python (internal to functools.lru_cache with default
>> argument hack)
>>     def decorating_function(user_function, tuple=tuple, sorted=sorted,
>> len=len, KeyError=KeyError):
>>          ... # 60 line function
>>
>>     # Proposal - explicitly implicit locals to clarify real calling signature
>>     def decorating_function(user_function) [tuple=tuple,
>> sorted=sorted, len=len, KeyError=KeyError)]:
>>          ... # 60 line function
>
> The proposed syntax isn't explicit enough for my taste to justify the
> change.  What the programmer really wants to tell the compiler is:
> Bind the given names at compile time rather than at run time.  I'd
> prefer if the syntax would reflect this intention, similar to the
> "global" and "nonlocal" declarations:
>
>    def decorating_function(user_function):
>        earlybind tuple, sorted, len, KeyError
>
> (Not being a native speaker of English, I don't even try to find a
> less dull name for this than "earlybind".  And I'm quite aware that
> the bar for the introduction of a new keyword is quite high.)
>
>> Early binding in a loop:
>>
>>    # Current Python
>>    adders = []
>>    for i in range(10):
>>       def f(x, _i=i):
>>           return x + _i
>>       adders.append(f)
>>
>>    # Proposal
>>    adders = []
>>    for i in range(10):
>>       def f(x) [i=i]:  # Real calling signature is clear
>>           return x + i
>>       adders.append(f)
>
> I don't see too much benefit of the proposed syntax for this use
> case.  If f() is a local throw-away function, I wouldn't worry about
> its signature.  If f() is a longer-lived object and I do care about
> its signature, I'd uses a class:
>
>    class Adder:
>        def __init__(self, i):
>            self.i = i
>        def __call__(self, x):
>            return x + self.i
>
>    [...] adders.append(Adder(i))
>
> I still think classes are the Python way to hide state, not closures.
> That said, this case would also be covered by the "earlybind" porposal
> above.
>
>> Algorithmic shared state (without a class):
>>
>>     # Current Python
>>     def f(*, _cache=[]):
>>         # Consenting adults, please don't override _cache when calling!
>>
>>     # Proposal
>>     def f() [_cache=[]]:  # Real calling signature is clear
>>         # _cache is an implicit local, not a keyword-only argument, so its safe
>
> Again, I'd use a class to hide state in the first place.  If someone
> really wants to avoid using a class for some reason, using function
> attributes would also be a viable way:
>
>    def f():
>        try:
>            cache = f._cache
>        except AttributeError:
>            cache = f._cache = []
>
> Cheers,
>    Sven
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>



More information about the Python-ideas mailing list