[Python-ideas] One more time... lambda function <--- from *** signature def.

Ron Adam ron3200 at gmail.com
Sat Mar 1 07:07:14 CET 2014



On 02/28/2014 09:46 PM, Steven D'Aprano wrote:
> On Fri, Feb 28, 2014 at 11:17:18AM -0600, Ron Adam wrote:
>> >
>> >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.
> You can't assign to True, False or None. (You can assign to True and
> False in Python 2, but shouldn't.)

I meant it the other way around.

For example... def is not assignable to anything..

      D = def     # won't work

      T = True    # works
      F = False
      N = None

      L = lambda  # won't work

lambda isn't an object like True, False, and None.

> [...]
>> >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.
> [...]
>> >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.

> I think it would be useful to have a way to delay execution of an
> expression, that is to say, have a way to capture an expression for
> later evaluation, something more lightweight than a function, but I
> don't think that limiting it to inside function calls is the right
> approach.

The expressing part isn't limited to inside function calls.. Or wouldn't be 
if it was a doable idea.

> Something perhaps like a thunk might be appropriate? We can*almost*  do
> that now, since Python has a compile function:
>
> thunk = compile("x + 3", "", "eval")
> # much later
> eval(thunk)


     def thunk(***expr):
         return expr

     def do thunks(*args):
         for expr in args:
             ***expr

     start = t = time()
     update_timer = thunk(t = time())
     show_timer = thunk(print(t-start))
     show_status = thunk(do_thunks(upate_timer, show_timer))


Then as you do things, possibly in different functions as well.

     ...
     ***show_status        # update t, and prints elapsed time.
     ...
     ***show_status
     ...
     ***show_status
     ...


Yes, it could be done with lambda too.




Here's where it differs...

So if we have this, where obj is nested expressions.

      While 1:
          try:
              obj = ***obj
          except TypeError:
              break

Then the result of the obj expression, could be a callable without any 
conflict.  Only delayed expressions would be expressed.

This was one of the properties I was looking for.


> Some problems with that approach:
>
> - You have to write the expression as a string, which means you lose any
> possibility of syntax highlighting.
>
> - The temptation is to pass some arbitrary untrusted string, which leads
> to serious security implications. The argument here should be limited
> to an actual expression, not a string containing an expression which
> might have come from who knows where.
>
> - It should be as lightweight as possible. The actual compilation of the
> expression should occur at compile-time, not run-time. That implies some
> sort of syntax for making thunks, rather than a function call.
>
> - Likewise actually evaluating the thunk should be really lightweight,
> which may rule out a function call to eval.
>
> - How should scoping work? I can see use-cases for flat scoping, static
> scoping, dynamic scoping, and the ability to optionally provide custom
> globals and locals, but I have no idea how practical any of them would
> be or what syntax they should use.

That's where the idea I mentioned in another response to this thread comes 
in.  Separating the namespace constructing from the code part of a function 
in a well defined way.

If that can be done... also pie in the sky. Then we could also evaluate an 
expression in a previously defined namespace.  It's hypothetical, so supply 
your own syntax for it.

The compiler will still compile the code, so most of the work is still done 
at compile time.  But we have these useful pieces we can take apart and put 
back together again.  (without calling eval, or exec.)

BTW, you can do that now, but it's very hard to get right.

      help(type(lambda:1))


> All of this is pie-in-the-sky at the moment, and not a serious proposal
> for Python 3.5.

Agree.
   Cheers,
      Ron





More information about the Python-ideas mailing list