[Python-ideas] One more time... lambda function <--- from *** signature def.
Ron Adam
ron3200 at gmail.com
Fri Feb 28 18:17:18 CET 2014
Starting new thread because this bike has a different shape and color.
Yesterday I was thinking that just making the keyword lambda assignable
like True, False, and None, would be enough. But the issue with that is
lambda isn't a name to an actual object or type. That was the seed for
this idea. How to get lambda like functionality into some sort of object
that would be easy to use and explain.
This morning I thought we could have in a functions definition something,
like "*", and "**", to take an expression. Similar to Nicks idea with =:,
but more general.
The idea is to have "***" used in def mean to take "any" call expression
and not evaluate it until *** is used on it. ie... the same rules as *.
When used in a def to pack a tuple, and when used outside def, to unpack
it. So, "***" used in a def, stores the call expression, at call time, and
when used later, expresses it.
A function call that captures an expression may be tricky to do. Here's one
approach that requires sugar when a function defined with "***" is called.
class TriStar:
def __init__(self, expr):
""" expr is a callable that takes no arguments. """
self.expr = expr
def __tristar__(self):
""" ***obj --> result """
return self.expr()
def fn(***expr):...
(Any other suggestions for how to do this would be good.)
And at call time....
fn(...) --> fn(TriStar(expr=lambda:...))
So presuming we can do something like the above, the first case is ...
def star_fn(***expr) return ***expr
... = star_fn(...)
Which is a function that just returns whatever it's input is, and is even
more general than using *args, **kwds.
The call signature stored in expr isn't evaluated until it's returned with
***expr. So the evaluation is delayed, or lazy, but it's still explicit
and very easy to read.
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!
The resolution is done with ***name, rather than name().
That's actually very good because it can pass through callable tests. So
you can safely pass callable objects around without them getting called at
the wrong time or place.
We can shorten the name because star_lambda is just a function.
L = star_lambda
To me this is an exceptionally clean solution. Easy to use, and not to
hard to explain. Seems a lot more like a python solution to me as well.
Hoping it doesn't get shot down too quickly,
Ron ;-)
More information about the Python-ideas
mailing list