[Python-Dev] Adventures with ASTs - Inline Lambda

Steve Holden steve at holdenweb.com
Fri Feb 17 06:55:42 CET 2006


Talin wrote:
> First off, let me apologize for bringing up a topic that I am sure that 
> everyone is sick of: Lambda.
> 
> I broached this subject to a couple of members of this list privately, 
> and I got wise feedback on my suggestions which basically amounted to 
> "don't waste your time."
> 
> However, after having thought about this for several weeks, I came to 
> the conclusion that I felt so strongly about this issue that the path of 
> wisdom simply would not do, and I would have to choose the path of 
> folly. Which I did.
> 
Thereby proving the truth of the old Scottish adage "The better the 
advice, the worse it's wasted". Not that I haven't been wasted myself a 
time or two.

> In other words, I went ahead and implemented it. Actually, it wasn't too 
> bad, it only took about an hour of reading the ast.c code and the 
> Grammar file (neither of which I had ever looked at before) to get the 
> general sense of what's going on.
> 
> So the general notion is similar to the various proposals on the Wiki - 
> an inline keyword which serves the function of lambda. I chose the 
> keyword "given" because it reminds me of math textbooks, e.g. "given x, 
> solve for y". And I like the idea of syntactical structures that make 
> sense when you read them aloud.
> 
> Here's an interactive console session showing it in action.
> 
> The first example shows a simple closure that returns the square of a 
> number.
> 
>     >>> a = (x*x given x)
>     >>> a(9)
>     81
> 
> You can also put parens around the argument list if you like:
> 
>     >>> a = (x*x given (x))
>     >>> a(9)
>     81
> 
> Same thing with two arguments, and with the optional parens:
> 
>     >>> a = (x*y given x,y)
>     >>> a(9, 10)
>     90
>     >>> a = (x*y given (x,y))
>     >>> a(9, 10)
>     90
> 
> Yup, keyword arguments work too:
> 
>     >>> a = (x*y given (x=3,y=4))
>     >>> a(9, 10)
>     90
>     >>> a(9)
>     36
>     >>> a()
>     12
> 
> Use an empty paren-list to indicate that you want to define a closure 
> with no arguments:
> 
>     >>> a = (True given ())
>     >>> a()
>     True
> 
> Note that there are some cases where you have to use the parens around 
> the arguments to avoid a syntactical ambiguity:
> 
>     >>> map( str(x) given x, (1, 2, 3, 4) )
>       File "<stdin>", line 1
>         map( str(x) given x, (1, 2, 3, 4) )
>                             ^
>     SyntaxError: invalid syntax
> 
> As you can see, adding the parens makes this work:
> 
>     >>> map( str(x) given (x), (1, 2, 3, 4) )
>     ['1', '2', '3', '4']
> 
> More fun with "map":
> 
>     >>> map( str(x)*3 given (x), (1, 2, 3, 4) )
>     ['111', '222', '333', '444']
> 
> Here's an example that uses the **args syntax:
> 
>     >>> a = (("%s=%s" % pair for pair in kwargs.items()) given **kwargs)
>     >>> list( a(color="red") )
>     ['color=red']
>     >>> list( a(color="red", sky="blue") )
>     ['color=red', 'sky=blue']
> 
> I have to say, the more I use it, the more I like it, but I'm sure that 
> this is just a personal taste issue. It looks a lot more natural to me 
> than lambda.
> 
> I should also mention that I resisted the temptation to make the 'given' 
> keyword an optional generator suffix as in "(a for a in l given l). As I 
> started working with the code, I started to realize that generators and 
> closures, although they have some aspects in common, are very different 
> beasts and should not be conflated lightly. (Plus the implementation 
> would have been messy. I took that as a clue :))
> 
> Anyway, if anyone wants to play around with the patch, it is rather 
> small - a couple of lines in Grammar, and a small new function in ast.c, 
> plus a few mods to other functions to get them to call it. The context 
> diff is less than two printed pages. I can post it somewhere if people 
> are interested.
> 
> Anyway, I am not going to lobby for a language change or write a PEP 
> (unless someone asks me to.) I just wanted to throw this out there and 
> see what people think of it. I definately don't want to start a flame 
> war, although I suspect I already have :/
> 
> Now I can stop thinking about this and go back to my TurboGears-based 
> Thesaurus editor :)
> 
Whether or not Guido can steel himself to engage in yet another round of 
this seemingly interminable discussion, at least this proposal has the 
merit of being concrete and not hypothetical.

It appears to hang together, but I'm not sure I see how it overcomes 
objections to lambda by replacing it with another keyword.

regards
  Steve
-- 
Steve Holden       +44 150 684 7255  +1 800 494 3119
Holden Web LLC                     www.holdenweb.com
PyCon TX 2006                  www.python.org/pycon/



More information about the Python-Dev mailing list