[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