[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