On 02/28/2014 11:54 AM, Chris Angelico 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,
On Sat, Mar 1, 2014 at 4:17 AM, Ron Adam<ron3200@gmail.com> wrote: 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.