[Python-ideas] One more time... lambda function <--- from *** signature def.
Ron Adam
ron3200 at gmail.com
Fri Feb 28 20:42:57 CET 2014
On 02/28/2014 11:54 AM, Chris Angelico wrote:
> On Sat, Mar 1, 2014 at 4:17 AM, Ron Adam<ron3200 at gmail.com> wrote:
>> >This returns a lambda-like function.
>> >
>> > def star_lambda(***expr): return expr
>> >
>> >
>> >And is used this way...
>> >
>> > result = star_lambda(a * b + c) # captures expression.
>> >
>> > actual_result = ***result # *** resolves "result" here!
>> >
> Interesting, but I don't like the way the interpretation of a function
> call depends on the target function. With both * and ** notations,
> there's absolutely no difference: the function is called with these
> positional and those keyword arguments, whether they came from actual
> args or from * or ** unpack/repacks;and there's no difference between
> a function that collects args with *args,**kwargs and one that
> collects them with individual names (or a C-level function that might
> do something altogether different).
It's not clear what differences you mean here... can you show some examples?
I think we just are used to not thinking about it, But it's not really that
different.
def fn(*args, **kwds): ...
This wraps args in a list, and kwds in a dict. It's up to the *function
called* to do what is intended by the syntax.
def fn(*args): ...
fn(a, b, c) --> fn(list(a, b, c)) #depends on function called.
def fn(**kwds): ...
fn(a=1, b=2, c=3) --> fn(dict(a=1, b=2, c=3)) # here too.
def fn(***expr): ...
fn(expr) --> fn(TriStar(lambda:(expr)))
# A bit more complex, but also the same.
# Parentheses need to capture tuple packing
# due to ',' having a higher precidence.
The mechanism behind each of these may be somewhat different, but there are
also similarities.
def fn(***expr): return ***expr
With these, it forwards the these existing cases nicely.
a, b, c = fn(a, b, c)
args = fn(*args)args, kwds
kwds = fn(**kwds)
args, kwds = fn(*args, **kwds)
And just like '**' can't be used to pack a dictionary directly, we can't
use '***' to pack an expression directly.
Using "**" in a funciton unpacks the dictionary.
Using "***" in a function call expresses the TriStar object.
(* any name for the TriStar object would work. (small detail))
NOW here is the main limitation... :-/
a, b, c = fn(a, b, c=1)
Which is because (a, b, c=1) isn't a valid expression outside of a function
call. Or should this be captured as (a, b, {"c":1})?
Sigh... darn edge cases. A bit more than an edge case I think.
Any ideas?
Cheers,
Ron
> With this proposal, your
> star_lambda function's declaration changes the call site - instead of
> evaluating a*b+c, it has to construct an anonymous function and pass
> it along.
More information about the Python-ideas
mailing list