467,136 Members | 1,399 Online

# "Updating" lambda functions

 Hi, I'm trying to write a Python function that parses an expression and builds a function tree from it (recursively). During parsing, lambda functions for the the terms and sub-expressions are constructed on the fly. Now my problem is lazy evaluation. Or at least I think it is. :-) I need to "update" a lambda function, like this: fu = lambda x: x ... fu = lambda x: fu(x) + 17 ... fu = lambda x: fu(x) * 3 Of course that doesn't work, because fu is resolved when the lambda is called, not when it's defined, so I'll run into an endless recursion. My current solution is to define a helper function which passes the lambda through its argument: def add_17 (fu): return lambda x: fu(x) + 17 def mul_3 (fu): return lambda x: fu(x) * 3 fu = lambda x: x ... fu = add_17(fu) ... fu = mul_3(fu) That works, but it strikes me as unclean and ugly. Is there a better way to do it? Best regards Oliver -- Oliver Fromme, Konrad-Celtis-Str. 72, 81369 Munich, Germany ``All that we see or seem is just a dream within a dream.'' (E. A. Poe) Jul 18 '05 #1
• viewed: 3206
Share:
53 Replies
 On Thu, 16 Sep 2004 14:07:20 +0000, Oliver Fromme wrote: I need to "update" a lambda function, like this: That says you need to use classes, not lambda functions. Jul 18 '05 #2
 "Oliver Fromme" wrote in message news:2q*************@uni-berlin.de... | That works, but it strikes me as unclean and ugly. | Is there a better way to do it? I don't like it either. Consider this: composition = lambda f,g: lambda x: f(g(x)) add_17 = lambda x: x+17 mul_3 = lambda x: 3*x fu = lambda x:x fu(3) 3 fu = composition(add_17,fu) fu(3) 20 fu = composition(mul_3,fu) fu(3) 60 Jul 18 '05 #3
 On 16 Sep 2004 14:07:20 GMT, Oliver Fromme wrote: Hi,I'm trying to write a Python function that parsesan expression and builds a function tree from it(recursively).During parsing, lambda functions for the the termsand sub-expressions are constructed on the fly.Now my problem is lazy evaluation. Or at least Ithink it is. :-)I need to "update" a lambda function, like this: fu = lambda x: x ... fu = lambda x: fu(x) + 17 ... fu = lambda x: fu(x) * 3Of course that doesn't work, because fu is resolvedwhen the lambda is called, not when it's defined, soI'll run into an endless recursion.My current solution is to define a helper functionwhich passes the lambda through its argument: def add_17 (fu): return lambda x: fu(x) + 17 def mul_3 (fu): return lambda x: fu(x) * 3 fu = lambda x: x ... fu = add_17(fu) ... fu = mul_3(fu)That works, but it strikes me as unclean and ugly.Is there a better way to do it?Best regards Oliver--Oliver Fromme, Konrad-Celtis-Str. 72, 81369 Munich, Germany``All that we see or seem is just a dream within a dream.''(E. A. Poe) You could exploit the way functions become bound methods, e.g., fu = lambda x: x fu = (lambda f,x: f(x) + 17).__get__(fu) fu = (lambda f,x: f(x) * 3).__get__(fu) fu(1) 54 fu(0) 51 fu(-15) 6 fu(-16) 3 fu(1,2) Traceback (most recent call last): File "", line 1, in ? TypeError: () takes exactly 2 arguments (3 given) fu of of at 0x008FD8B0>>> or, you could make a magic function-composing object with magic composing properties, exploiting the method-making mechanism in a different way, e.g., class FC(object): ... def __setattr__(self, name, f): ... if not hasattr(self, name): self.__dict__[name] = [f] ... else: self.__dict__[name].append(f) ... def __getattribute__(self, name): ... if name == '__dict__': return object.__getattribute__(self, '__dict__') ... return type(self).__dict__['_xfuns'].__get__( ... object.__getattribute__(self,name)) ... def _xfuns(flist, x): ... for f in flist: x = f(x) ... return x ... fc = FC() fc.fu = lambda x: x fc.fu = lambda x: x + 17 fc.fu = lambda x: x * 3 fc.fu(1) 54 fc.fu(0) 51 fc.fu(-15) 6 fc.fu(1,2) Traceback (most recent call last): File "", line 1, in ? TypeError: _xfuns() takes exactly 2 arguments (3 given) fc.bar = lambda x: x*3 fc.bar = lambda x: x+10 fc.bar(0) 10 fc.bar(2) 16 fc.fu(-18) -3 All just to explore python's features, not to recommend specific uses ;-) Regards, Bengt Richter Jul 18 '05 #4
 "Oliver Fromme" wrote in message news:2q*************@uni-berlin.de... fu = lambda x: x fu = lambda x: fu(x) + 17 etc I am curious if there is any reason other that habit carried over from other languages to not write the above as def fu(x): return x def fu(x): return fu(x) + 17 etc Granted, the latter takes 2 more keystrokes, but the resulting object gets a proper .name attribute. And, of course, the def form is required for a multiline body anyway. (Note: I am not asking about the use of lambda *within* an expression or as a return value, but only the immediate name-binding of the supposedly anonymous function where one does not want anonymity.) Terry J. Reedy Jul 18 '05 #5
 "Terry Reedy" wrote in message news:ma**************************************@pyth on.org... | I am curious if there is any reason other that habit carried over from | other languages to not write the above as | | def fu(x): return x | def fu(x): return fu(x) + 17 | etc In my interpreter (IDLE 1.0 on Windows 98) it causes an infinite regress. Jul 18 '05 #6
 Elaine Jackson home.com> writes: "Terry Reedy" udel.edu> wrote in message news:mailman.3428.1095385637.5135.python-list python.org... | I am curious if there is any reason other that habit carried over from | other languages to not write the above as | | def fu(x): return x | def fu(x): return fu(x) + 17 | etc In my interpreter (IDLE 1.0 on Windows 98) it causes an infinite regress. Yes, it will, exactly as the lambda version would have. (And all the solutions suggested to you for the lambda form are equally applicable to the def form.) The question is why use the lambda form when you *do* want to bind your function to a name? Basically, f = lambda args: body is equivalent to def f(args): body except that the def body is a set of statements (so you have to use 'return'), and the lambda body is a single expression. Not that it's coming any time soon, but Python 3000 is supposed to remove lambda functions, so when you really *do* want to bind a function to a name (like in your case here), it would probably be a good habit to get into to use defs instead. Steve Jul 18 '05 #7
 On Fri, 17 Sep 2004 07:46:12 +0000 (UTC), Steven Bethard wrote: Elaine Jackson home.com> writes: "Terry Reedy" udel.edu> wrote in message news:mailman.3428.1095385637.5135.python-list python.org... | I am curious if there is any reason other that habit carried over from | other languages to not write the above as | | def fu(x): return x | def fu(x): return fu(x) + 17 | etc In my interpreter (IDLE 1.0 on Windows 98) it causes an infinite regress.Yes, it will, exactly as the lambda version would have. (And all thesolutions suggested to you for the lambda form are equally applicable to thedef form.) The question is why use the lambda form when you *do* want to bindyour function to a name? Basically,f = lambda args: bodyis equivalent todef f(args): bodyexcept that the def body is a set of statements (so you have to use 'return'),and the lambda body is a single expression. Yes, but obj.f = lambda args: body is possible without an intermediate local binding of f that might clobber a previous f, as in def f(args): body obj.f = f del f # if you want to clean up. But better save the old f in that case? I'd rather use lambda. Not that it's coming any time soon, but Python 3000 is supposed to removelambda functions, so when you really *do* want to bind a function to a name(like in your case here), it would probably be a good habit to get into to usedefs instead. Well, if lambda is removed (or not ;-), I hope an anonymous def expression is allowed, so we can write obj.f = def(args): body or obj.f = def(args): body or obj.f = ( def(args): body ) # at or to the left of the def column, for final dedent without special ')' processing. (where def body indentation is referenced from wherever the def is) Regards, Bengt Richter Jul 18 '05 #8
 Bengt Richter oz.net> writes: On Fri, 17 Sep 2004 07:46:12 +0000 (UTC), I wrote:f = lambda args: bodyis equivalent todef f(args): body Yes, but obj.f = lambda args: body is possible without an intermediate local binding of f that might clobber a previous f Yeah, I probably should have been clear about that. If 'f' is really just a name (as it was in my example) the two syntaxes I gave are equivalent. If 'f' really isn't just a name, then you do still want an anonymous function. In the OP's example though, 'f' really was just a name. Well, if lambda is removed (or not , I hope an anonymous def expression is allowed... Well, it's come up a number of times (one of the more recent is http://mail.python.org/pipermail/pyt...e/226714.html), but it doesn't seem like there was any agreement on (a) what it should look like, or (b) why having such anonymous defs was such a gain over named defs. If you'd like to champion a PEP about it... ;) Steve Jul 18 '05 #9
 "Bengt Richter" wrote in message news:ci*************************@theriver.com... "Terry Reedy" udel.edu> wrote in message news:mailman.3428.1095385637.5135.python-list python.org... | I am curious if there is any reason other that habit carried over from | other languages to not write the above as | | def fu(x): return x | def fu(x): return fu(x) + 17 obj.f = lambda args: body is possible without an intermediate local binding of f that might clobber a previous f, as in def f(args): body obj.f = f del f # if you want to clean up. But better save the old f in that case? I'd rather use lambda. Thanks. I had not thought of this variation. Similar would be seq[n] = lambda Of course, I *might* prefer being able to write def obj.f(params): # and def seq[n](params): Since def is effectively a binding statement, name to function object (like import, name to module), these seem not entirely unreasonable to me. Terry J. Reedy Jul 18 '05 #10
 What? is lambda is going away? Say it ain't so! On Fri, Sep 17, 2004 at 08:26:19AM +0000, Bengt Richter wrote: | >f = lambda args: body | > is equivalent to | >def f(args): body Not really -- the item above is _bad style_, people write, def f(args): body | obj.f = lambda args: body Or more commonly, func(arg, lambda args: body) | I'd rather use lambda. No joke. For the common case above, which occurs _everywhere_ in my 'deferred execution' code, one would write: def somerandomname(args): body func(arg, somerandomname) So, you've taken something that is a perfectly clear one-liner and converted it into a 3 line chunk of code with _zero_ added clarity, in fact, I'd say you've dramatically reduced clarity by requiring the a name be 'minted'. Ugly. Multiply this by 10x in one of my source files and you've taken something perfectly readable and turned it into maze of confusion. This _hides_ the true intent rather than making it clear that the function is temporary thingy. | >Not that it's coming any time soon, but Python 3000 is supposed to remove | >lambda functions Expect me to whine very loudly on a daily basis when Python 3000 becomes near. In fact, let the preemptive supplication begin. | Well, if lambda is removed (or not ;-), I hope an anonymous def | expression is allowed, so we can write | | obj.f = def(args): | body | or | | obj.f = def(args): body | | or | | obj.f = ( | def(args): | body | ) Ewww. How is this better than lambda? Let's keep lambda, no? Clark -- Clark C. Evans Prometheus Research, LLC. http://www.prometheusresearch.com/ o office: +1.203.777.2550 ~/ , mobile: +1.203.444.0557 // (( Prometheus Research: Transforming Data Into Knowledge \\ , \/ - Research Exchange Database /\ - Survey & Assessment Technologies ` \ - Software Tools for Researchers ~ * Jul 18 '05 #11
 In article , Clark C. Evans wrote: What? is lambda is going away? Say it ain't so! They keep threatening it, and it keeps not happening. In the meantime, we can use this time to our advantage, preparaing our vocal chords for the eventual screaming fits and wails of agonizing pain. ;) | >Not that it's coming any time soon, but Python 3000 is supposed to remove| >lambda functions Expect me to whine very loudly on a daily basis when Python 3000 becomes near. In fact, let the preemptive supplication begin. Since enough time has gone by since I last whined, let me just take this opportunity to say, in a completely calm, diplomatic, and non-confrontational way: "Ruby-style code blocks would be nice." (o) Don't beg for code blocks again today ( ) Don't beg for code blocks again in the next three days ( ) Don't beg for code blocks again in the next week [ OK ] -- .:[ dave benjamin: ramen/[sp00] -:- spoomusic.com -:- ramenfest.com ]:. "talking about music is like dancing about architecture." Jul 18 '05 #12
 Clark C. Evans wrote: No joke. For the common case above, which occurs _everywhere_in my 'deferred execution' code, one would write: def somerandomname(args): body func(arg, somerandomname)So, you've taken something that is a perfectly clear one-liner andconverted it into a 3 line chunk of code with _zero_ added clarity,in fact, I'd say you've dramatically reduced clarity by requiringthe a name be 'minted'. Ugly. I don't agree. I *still* have to stop and think every time I see a lamba -- they parse completely differently in my mind than anything else in Python does, and they confuse me every time. Yes, defining a small function requires two extra lines... but, y'know, it's not like my editor is going to run out of paper. And I find that a well-chosen name, even for a single-use thing like this, greatly adds clarity. To my mind, calling this func_callback(), or some such descriptive name, makes the intent *much* more clear than 'lambda' does. Multiply this by 10x in one of mysource files and you've taken something perfectly readable andturned it into maze of confusion. This _hides_ the true intentrather than making it clear that the function is temporary thingy. Only when one is already familiar with lambdas. I've gotten to the point where I *can* understand them, but it's still a struggle. It seems to me that the benefits of having lambda are outweighed by the fair amount of extra mental space that they use up. It just strikes me as too much of a special case to deserve special syntax that has absolutely no parallel elsewhere in Python. | Well, if lambda is removed (or not ;-), I hope an anonymous def| expression is allowed, so we can write|| obj.f = def(args):| body| or|| obj.f = def(args): body|| or|| obj.f = (| def(args):| body| )Ewww. How is this better than lambda? Let's keep lambda, no? I certainly agree that none of these examples strike me as less troublesome than lambda. Indeed, the second one effectively *is* lambda syntax, except with added parens and a name change. And the others both scream out that there *will* be problems with indenting properly. I remain unconvinced that the utility of anonymity is so great that either special case is justified. Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #13
 >>>>> "Clark" == Clark C Evans writes: Clark> def somerandomname(args): Clark> body Clark> func(arg, somerandomname) Clark> So, you've taken something that is a perfectly clear Clark> one-liner and converted it into a 3 line chunk of code with Clark> _zero_ added clarity, in fact, I'd say you've dramatically Clark> reduced clarity by requiring the a name be 'minted'. Ugly. What does "minting" a name mean? You can always do def L(args): body func(arg, L) You can even make it a habit to always call it L. Clark> Expect me to whine very loudly on a daily basis when Python Clark> 3000 becomes near. In fact, let the preemptive Clark> supplication begin. Heh, I can already anticipate the whining around py3000. It will probably be a test bed for hundreds of new voting methods and give sociology students thesis-fodder for years. Clark> Ewww. How is this better than lambda? Let's keep lambda, Clark> no? I agree. Lambda doesn't suck anymore, so it deserves to live. -- Ville Vainio http://tinyurl.com/2prnb Jul 18 '05 #14
 On Mon, Oct 11, 2004 at 10:54:05AM -0700, Jeff Shannon wrote: | I don't agree. I *still* have to stop and think every time I see a | lamba -- they parse completely differently in my mind than anything else | in Python does, and they confuse me every time. Yes, defining a small | function requires two extra lines... but, y'know, it's not like my | editor is going to run out of paper. And I find that a well-chosen | name, even for a single-use thing like this, greatly adds clarity. To | my mind, calling this func_callback(), or some such descriptive name, | makes the intent *much* more clear than 'lambda' does. I beg to differ; and I'm talking about _my_ code, not yours. | Only when one is already familiar with lambdas. I've gotten to the | point where I *can* understand them, but it's still a struggle. It | seems to me that the benefits of having lambda are outweighed by the | fair amount of extra mental space that they use up. It just strikes me | as too much of a special case to deserve special syntax that has | absolutely no parallel elsewhere in Python. If you don't like lambda -- don't use it. Just beacuse you are unfamilar with a very helpful construct and are unwilling to learn does not mean you should prevent others from continuing to enjoy one of the more pleasant aspects of Python. Kind Regards, Clark Jul 18 '05 #15
 Dave Benjamin ha scritto: Since enough time has gone by since I last whined, let me just take this opportunity to say, in a completely calm, diplomatic, and non-confrontational way: "Ruby-style code blocks would be nice." (o) Don't beg for code blocks again today ( ) Don't beg for code blocks again in the next three days ( ) Don't beg for code blocks again in the next week [ OK ] do a b: indentblock would be uber cool, imho. Jul 18 '05 #16
 Clark C. Evans wrote: On Mon, Oct 11, 2004 at 10:54:05AM -0700, Jeff Shannon wrote:|| .... It| seems to me that the benefits of having lambda are outweighed by the| fair amount of extra mental space that they use up. It just strikes me| as too much of a special case to deserve special syntax that has| absolutely no parallel elsewhere in Python.If you don't like lambda -- don't use it. Just beacuse you areunfamilar with a very helpful construct and are unwilling to learndoes not mean you should prevent others from continuing to enjoyone of the more pleasant aspects of Python. Except that one of the design principles of Python is that it being easy to *read* is more important than being easy to write, with the assumption that much of the code that one reads will be code written by someone else. I do care how readable your code is, because (at least in principle) someday I may need to maintain it. ("If you don't like X, don't use it, but let others use it if they like" seems to be much more Perlish than Pythonic, at least IMHO.) Lambdas are hard to read, because they're significantly different, syntactically, from any other construct in the language -- it's not that I'm _unwilling_ to learn, it's that it is actively *difficult* to learn because it doesn't fit well, conceptually, into the rest of the language, so there's a mental impedance barrier that must be overcome. In order to explain lambdas to someone who is not already familiar with them, you have to explain first that it's kind of like a function def, except that it uses totally different syntax (aren't function defs supposed to use parens?), and you don't explicitly return anything even though it *does* return a value, and oh yes, you can't actually use statements because it has to be a single expression (and then you get to explain the difference between statements and expressions, and explain *why* there's a difference and that it really is a good thing)... That's a lot of special treatment for those cases where there actually might be a slight advantage to using an anonymous function, and "Special cases aren't special enough to break the rules." Lambdas *do* break many of Python's usual rules. Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #17
 On Mon, Oct 11, 2004 at 11:58:44AM -0700, Jeff Shannon wrote: | >If you don't like lambda -- don't use it. Just beacuse you are | >unfamilar with a very helpful construct and are unwilling to learn | >does not mean you should prevent others from continuing to enjoy | >one of the more pleasant aspects of Python. | | Except that one of the design principles of Python is that it being easy | to *read* is more important than being easy to write Exactly! Lambdas make my code easy to read and therefore more understandable. I don't use them beacuse they are easier to write, I use them beacuse they make reviewing source code easier: - they put simple expressions that are arguments right where they are used - they don't create random names that you have to worry about name collision or finding something meaningful (and not distracting) - you are certain to know that the chunk of code is not used anywhere else, that is, you can freely modify it Lambdas are all about making code more maintainable. | Lambdas are hard to read, This is _your_ opinion; lots of other people disagree. | because they're significantly different, | syntactically, from any other construct in the language This argument is just bogus. There are lots of things in Python that are significantly different from each other: - functions that return functoins, and hence can().be().chained() - using expressions as function arguments - list comprehensions - *args and **kwargs - overridable operators - classes, meta-classes - etc. In any of these cases one _could_ of course, find a similar way to do it with just a turning machine. But this isn't the point, the point is to give special syntax to common things that have specific meaning so that they are easily recognized. Best, Clark Jul 18 '05 #18
 Jeff Shannon ccvcorp.com> writes: Lambdas are hard to read, because they're significantly different, syntactically, from any other construct in the language Yes, they are different (summarizing your points): * no parens around argument list * returns a value without the return statement * contains a single expression, not a sequence of statements Of course, comparing something like the new decorator syntax to the older equivalent will also point out a construct that's "significantly different, syntactically, from any other construct in the language": @d1 @d2 def f(): pass as opposed to def f(): pass f = d1(d2(f)) Some points (in parallel with yours, as much as possible): * no parens, but functions are called * rebinds a name without an assignment statement[1] * appear as expressions, but act like statements * appear before a def, but are applied after I'd contend that lambda syntax is much more in-line with the rest of Python than decorator syntax. Not that I'm suggesting we get rid of decorator syntax -- I've already found it useful on a number of occasions. I just wanted to point out that, all things considered, lambdas are probably more consistent with Python than decorators are. Steve [1] Actually, I believe the function is not bound to a name until after the decorators are applied, but I don't think it's completely unreasonable to talk of this as a name rebinding. Jul 18 '05 #20
 gabriele renzi wrote: then what you want is a better lambda. One where you can use return, maybe, and where you can have statements and multiple expressions. Don't throw away the baby with the bathwater. But because of Python's line- and indentation-based syntax, doing all of that on a single line is... um... awkward at best, to put it mildly. And once you make a lambda multiline, then you lose most of the point of it -- at least, as far as I understand what the point is (having an in-line, anonymous callable). Once you allow statements and multiple expressions, all you're gaining is anonymity, which seems like a pretty paltry benefit to me. That's a lot of special treatment for those cases where there actually might be a slight advantage to using an anonymous function, and "Special cases aren't special enough to break the rules." Lambdas *do* break many of Python's usual rules. Just because you're thinking of lambdas as special cases. Whenever a case is very useful it is possible to break the rules. That's why there are all those funny literals. I agree that, if a case is *very* useful, it is possible to break the rules. List comprehensions, for example, break some of the rules, but they are indeed very useful, so the rule-breakage is more forgiveable. Maybe I'm just ignorant or behind the times, but I still haven't seen a real argument as to *why* lambdas are so useful. There's some assertions about how avoiding giving something a name makes things clearer, which I disagree with. ('Explicit is better than implicit.' I don't see how 'no name' makes the purpose of a code segment clearer than 'some meaningfully descriptive name', no matter how many times it's asserted.) There's complaints that it takes a whole two extra lines to type a proper function def, as opposed to being able to use lambdas inline... but again, I'd claim that with a properly named function, the intent at point-of-use will be quite clear and the cost of two extra lines of code is minimal. (I also tend to break complex expressions into multiple steps to increase clarity -- packing as much as possible into a single line doesn't strike me as all that desirable.) There's complaints about polluting the namespace... but ISTM that it's not *that* hard to come up with uniquely descriptive names. Lambdas may once have had some utility in capturing and tinkering with the scoping of names, but that became moot with the introduction of nested scopes 'way back when. I understand that lambdas are very popular in other programming languages (such as Lisp). But Python is not those languages, and which constructs are useful may well be different. I don't know enough Lisp to judge how helpful lambdas are there; I do know enough Python to believe that I should be able to see the advantages if they were as wonderful as their proponents say. My suspicion is that all of the Python users who like lambdas originally discovered them in other languages and are comfortable with them from that environment, but those who have no previous exposure to lambdas tend to be unimpressed (at best) by Python's take on them. This renders them, IMO, in the same category as the ternary operator that's continually proposed by converts from, say, C/C++ -- a feature whose usability is much greater in other languages than in Python, and whose inclusion would only satisfy those familiar with the feature from those other languages. The only difference between the two features, IMO, is that someone managed to talk Guido into including lambdas (which he reportedly regrets), and nobody managed to talk him into including the ternary operator. Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #21
 On Mon, 11 Oct 2004 12:36:21 -0400, "Clark C. Evans" wrote: What? is lambda is going away? Say it ain't so!On Fri, Sep 17, 2004 at 08:26:19AM +0000, Bengt Richter wrote: I didn't write the following, I replied to it. Note the extra quoting level. You are quoting Steven Bethard. See http://groups.google.com/groups?hl=e...t%40python.org ;-) | >f = lambda args: body| > is equivalent to| >def f(args): body It really should be f = lambda args: expr is equivalent to def f(args): return expr except for little details like f.__name__ and perhaps vestigial unexecuted byte code in the def version, until someone thinks it's worth the bother to optimize out. Not really -- the item above is _bad style_, people write, def f(args): body| obj.f = lambda args: bodyOr more commonly, commonly compared to what? obj.f = ... ? func(arg, lambda args: body)| I'd rather use lambda. That line I wrote, though the context is snipped ;-) No joke. For the common case above, which occurs _everywhere_in my 'deferred execution' code, one would write: def somerandomname(args): body func(arg, somerandomname)So, you've taken something that is a perfectly clear one-liner andconverted it into a 3 line chunk of code with _zero_ added clarity,in fact, I'd say you've dramatically reduced clarity by requiringthe a name be 'minted'. Ugly. Multiply this by 10x in one of mysource files and you've taken something perfectly readable andturned it into maze of confusion. This _hides_ the true intentrather than making it clear that the function is temporary thingy. [Not Bengt]| >Not that it's coming any time soon, but Python 3000 is supposed to remove| >lambda functionsExpect me to whine very loudly on a daily basis when Python 3000becomes near. In fact, let the preemptive supplication begin. [Bengt]| Well, if lambda is removed (or not ;-), I hope an anonymous def| expression is allowed, so we can write|| obj.f = def(args):| body| or|| obj.f = def(args): body|| or|| obj.f = (| def(args):| body| )Ewww. How is this better than lambda? Let's keep lambda, no? Sure, lambda is fine, but it doesn't allow statements, so something like def is needed. Just dropping the def name and allowing the def statement to be an expression seemed an easy step, since the name is basically the only difference. As seen above, finding an indentation style that is easy to read is a challeng, especially if the anonymous def is a middle argument to a functions call, e.g., func(arg1, (def(x): print x), arg3) much as with lambda, you may need parentheses to show where the expression ends. For a more complex def, we get into multiple lines in the arg list, e.g., expanded, func( arg1, # use a new line to get consistent indenting of arg list items (def(x, base=10): """even anonymous defs could have doc strings""" return int(x+'0', base) # weird function ), arg3 ) or, more compactly, func(arg1, def(x, base=10): """even anonymous defs could have doc strings""" return int(x+'0', base) # weird function ,arg3) It's a tough style problem. But what would you do with lambda, given that we don't have lots of insignificant silly parentheses? Regards, Bengt Richter Jul 18 '05 #22
 Dave Benjamin lackingtalent.com> writes: after(10, lambda: sprite.move(0, 5)) after(15, lambda: sprite2.rotate(30)) after(20, lambda: sprite.scale(120, 120)) after(22, lambda: sprite2.move(50, 50)) after(22, lambda: sound1.play()) after(23, lambda: sprite.move(0, 0)) after(26, lambda: sound1.stop()) Unfortunately, your "after" function is probably provided by your framework, but if that framework was written a little more Python-friendly, the after function would work like unittest.TestCase.assertRaises, e.g. def after(sec, func, *args, **kwds): # wait sec seconds ... # call func func(*args, **kwds) This would let you write the code above as: after(10, sprite.move, 0, 5) after(15, sprite2.rotate, 30) after(20, sprite.scale, 120, 120) after(22, sprite2.move, 50, 50) after(22, sound1.play) after(23, sprite.move, 0, 0) after(26, sound1.stop) which is actually slightly more concise (character-wise) than the lambda code, and doesn't force you to create a new lambda function to do something someone already created a function for. Again, I realize that in many cases having functions written like this is not possible because the functions are defined by a framework, not the coder, but if you happen to be one of the ones *writing* the framework, you can take advantage of Python's *args and **kwds syntax to make this kind of thing easier. Steve Jul 18 '05 #24
 In article , Steven Bethard wrote: Unfortunately, your "after" function is probably provided by your framework, but if that framework was written a little more Python-friendly, the after function would work like unittest.TestCase.assertRaises, e.g. def after(sec, func, *args, **kwds): # wait sec seconds ... # call func func(*args, **kwds) This would let you write the code above as: after(10, sprite.move, 0, 5) after(15, sprite2.rotate, 30) after(20, sprite.scale, 120, 120) after(22, sprite2.move, 50, 50) after(22, sound1.play) after(23, sprite.move, 0, 0) after(26, sound1.stop) which is actually slightly more concise (character-wise) than the lambda code, and doesn't force you to create a new lambda function to do something someone already created a function for. Ahh, what clever solutions dynamic typing can afford. =) Very nice. Again, I realize that in many cases having functions written like this is not possible because the functions are defined by a framework, not the coder, but if you happen to be one of the ones *writing* the framework, you can take advantage of Python's *args and **kwds syntax to make this kind of thing easier. Even if modifying the framework function is not an option, you can still accomplish similar results with an argument-binding function: def bind(func, *args, **kwds): return lambda: func(*args, **kwds) after(10, bind(sprite.move, 0, 5)) after(15, bind(sprite2.rotate, 30)) after(20, bind(sprite.scale, 120, 120)) .... Or, in the "more readable" Python3k-enforced style: def bind(func, *args, **kwds): def doit(): return func(*args, **kwds) return doit after(10, bind(sprite.move, 0, 5)) .... (sorry, couldn't resist ) -- .:[ dave benjamin: ramen/[sp00] -:- spoomusic.com -:- ramenfest.com ]:. "talking about music is like dancing about architecture." Jul 18 '05 #26
 On Mon, 11 Oct 2004 22:29:11 -0000, Dave Benjamin wrote: In article <10*************@corp.supernews.com>, Jeff Shannon wrote: gabriele renzi wrote: then what you want is a better lambda. One where you can use return, maybe, and where you can have statements and multiple expressions. Don't throw away the baby with the bathwater. But because of Python's line- and indentation-based syntax, doing all of that on a single line is... um... awkward at best, to put it mildly.This is true. I think that Ruby's code block syntax offers a workablealternative. Many will dispute this, saying it's too ugly, but this issubjective and not based on any technical reasons. Here is what I'veproposed in the past:def with_open_file(filename, proc): f = open(filename) try: proc(f) finally: f.close()with_open_file('data.txt', {|f| for line in f: print line})This is nearly identical to Ruby's syntax, except that instead of creatingan object with a call method, it creates a callable. How about extending lambda? E.g., with_open_file('data.txt', lambda f:< for line in f: print line:) I.e., the first non-white-space after the initial ':<' defines suite indentation, and a corresponding (to allow nesting) '>:' closes the lambda body (without necessarily having to be out-dented). Hence you could do a one liner for the above example: with_open_file('data.txt', lambda f:< for line in f: print line >:) IMO, if you are familiar with lambda, lambda f:< ... >: is less of a jump than {|f| ... } What did I forget? ;-) Obviously lambda f:expr can also be spelled lambda f:< return expr >: And once you make a lambda multiline, then you lose most of the point of it -- at least, as far as I understand what the point is (having an in-line, anonymous callable). Once you allow statements and multiple expressions, all you're gaining is anonymity, which seems like a pretty paltry benefit to me.It's not so much the anonymity that matters, it's the ability to use them asexpressions. It allows you to create your own control structures withoutdisrupting the logical flow of your program. For instance, right now inPython you'd have to write the above like this:def doit(f): for line in f: print linewith_open_file('data.txt', doit)To me, this reads, "When I say 'doit', I mean iterate through each line insome given object 'f', and print that line. Now, with the open file, 'doit'."Whereas, in the previous example, I'm saying, "With the open file, for eachline in the file, print the line." The difference is subtle, perhaps, butthe need to define a named function beforehand rearranges my code in a waythat I'm not particularly fond of. I agree. [...]I actually discovered lambdas in Python first (well, technically Tcl, but Ididn't know it at the time), and since then I have done a lot of programmingin Python. In fact, it would be safe to say that Python biases my use ofother languages to a greater degree than any other language biases my use ofPython. I don't use lambdas very often, but their use does come up, and Iwould rather see them become more powerful (or see code blocks added to thelanguage) than have them be removed entirely. I'd like to see a ternaryoperator too. Guido would have probably added one by now, but nobody couldagree on which syntax would be most "Pythonic". The same fate, I fear, is instore for any sufficiently advanced anonymous function syntax in Python.(Yet, somehow, decorators slipped through, even though nobody agreeed on asyntax for that either. I don't have a rational explanation for that...) Maybe we can piggyback on that ;-) @lambda f:< f.__name__ += '_decorated_by_an_extended_lambda' return f >: def foo(): pass Regards, Bengt Richter Jul 18 '05 #28
 Dave Benjamin writes: that it lacks a more powerful closure construct. For instance, on the dev list, as quickly as the new "sort(key=lambda x: x[1])" idiom was introduced, people started hunting for ways to squash the lambda, the winners being "operator.attrgetter()" and "operator.itemgetter()". But why would you want to need to remember such obscure functions? I never heard of any of those. Maybe they should be eliminated instead of lambda. There should be one obvious way to do it, and lambda suffices. Jul 18 '05 #29
 Paul Rubin <"http://phr.cx" NOSPAM.invalid> writes: Dave Benjamin lackingtalent.com> writes: ... "operator.attrgetter()" and "operator.itemgetter()". But why would you want to need to remember such obscure functions? I never heard of any of those. Couldn't tell if this was a joke or not, so in case it wasn't, attrgetter and itemgetter are being introduced in Python 2.4, I believe as a result of the sort(key=...) and sorted(key=...) discussions. Maybe they should be eliminated instead of lambda. There should be one obvious way to do it, and lambda suffices. This is the part that really sounded like a joke, but in case it wasn't... I could write a sort function every time I wanted to sort a list, but why not use the one that comes builtin with Python lists? I could write a strip function to remove whitespace from the ends of a string, but why not use the one that comes builtin with Python strs? Likewise, I could write a (lambda) function every time I wanted to select an item by index, e.g. lambda x: x[1] but if Python has already defined one for me, why would I define it again? Steve Jul 18 '05 #30
 On Mon, 11 Oct 2004 22:11:11 GMT, bo**@oz.net (Bengt Richter) wrote: [...]On Mon, 11 Oct 2004 12:36:21 -0400, "Clark C. Evans" wrote:[Bengt] Just want to say this isn't my latest idea ;-) See below: (the first non-white-space after the opening ':<' determines the suite indentation level, and the matching >: ends the suite (without necessarily being outdented or on a separate line). | Well, if lambda is removed (or not ;-), I hope an anonymous def| expression is allowed, so we can write|| obj.f = def(args):| body obj.f = lambda args:< body: or obj.f = lambda args:< body >: | or|| obj.f = def(args): body obj.f = lambda args:< body >: || or|| obj.f = (| def(args):| body| ) There wouldn't be much reason to use the extra parens above.Ewww. How is this better than lambda? Let's keep lambda, no?Sure, lambda is fine, but it doesn't allow statements, so somethinglike def is needed. Just dropping the def name and allowing thedef statement to be an expression seemed an easy step, since thename is basically the only difference. I had second thoughts ;-) As seen above, finding an indentation style that is easy to read isa challeng, especially if the anonymous def is a middle argument toa functions call, e.g., func(arg1, (def(x): print x), arg3) much better (IMO) now: func(arg1, lambda x:< print x >:, arg3) much as with lambda, you may need parentheses to show where the expression ends.For a more complex def, we get into multiple lines in the arg list, e.g.,expanded, func( arg1, # use a new line to get consistent indenting of arg list items (def(x, base=10): """even anonymous defs could have doc strings""" return int(x+'0', base) # weird function ), arg3 ) func( arg1, # use a new line to get consistent indenting of arg list items lambda x, base=10:< """even anonymous lambdas could have doc strings""" return int(x+'0', base) # weird function:, arg3 ) or, more compactly, func(arg1, def(x, base=10): """even anonymous defs could have doc strings""" return int(x+'0', base) # weird function ,arg3) func(arg1, lambda x, base=10:< """even anonymous lambdas could have doc strings""" return int(x+'0', base) >:, # weird function arg3) One-liner: func(arg1, lambda x, base=10:< "weird func doc"; return int(x+'0', base) >:, arg3) It's a tough style problem. But what would you do with lambda, given thatwe don't have lots of insignificant silly parentheses? I guess I took a stab at answering my own question ;-) Regards, Bengt Richter Jul 18 '05 #31
 Op 2004-10-11, Jeff Shannon schreef : gabriele renzi wrote: then what you want is a better lambda. One where you can use return, maybe, and where you can have statements and multiple expressions. Don't throw away the baby with the bathwater. But because of Python's line- and indentation-based syntax, doing all of that on a single line is... um... awkward at best, to put it mildly. Which is one of the reasons I think the indentation-based syntax was a mistake. If the syntax becomes an argument against a construct in the language, something is wrong with the syntax IMO. -- Antoon Pardon Jul 18 '05 #32
 Op 2004-10-11, Jeff Shannon schreef : Clark C. Evans wrote:On Mon, Oct 11, 2004 at 10:54:05AM -0700, Jeff Shannon wrote:|| .... It| seems to me that the benefits of having lambda are outweighed by the| fair amount of extra mental space that they use up. It just strikes me| as too much of a special case to deserve special syntax that has| absolutely no parallel elsewhere in Python.If you don't like lambda -- don't use it. Just beacuse you areunfamilar with a very helpful construct and are unwilling to learndoes not mean you should prevent others from continuing to enjoyone of the more pleasant aspects of Python. Except that one of the design principles of Python is that it being easy to *read* is more important than being easy to write, with the assumption that much of the code that one reads will be code written by someone else. I do care how readable your code is, because (at least in principle) someday I may need to maintain it. ("If you don't like X, don't use it, but let others use it if they like" seems to be much more Perlish than Pythonic, at least IMHO.) Lambdas are hard to read, because they're significantly different, syntactically, from any other construct in the language I didn't find them so. On the other hand I find having to come up with a name for a function can be very inconvenient and not worth the trouble. If python wants functions to be full fledged objects, is needs some way to have unnamed functions, just as you can have unnamed lists, numbers, instances etc. Can you imaging the protest, from people if it would be decide that no unnamed entities van be used. If you want to use a number or a list, as an argument you first have to name it and then use the name as argument. Well the reason for having anonymous numbers and lists is the same reason for having anonymous functions. -- it's not that I'm _unwilling_ to learn, it's that it is actively *difficult* to learn because it doesn't fit well, conceptually, into the rest of the language, so there's a mental impedance barrier that must be overcome. In order to explain lambdas to someone who is not already familiar with them, you have to explain first that it's kind of like a function def, except that it uses totally different syntax (aren't function defs supposed to use parens?) The problem is IMO that python uses two different kinds of ways to assign an object to a name. You have the assignment and you have the class and def statements. I would consider de class and def statements the odd man out, because they combine the construcion of the object with naming it, where normally the two are seperated. -- Antoon Pardon Jul 18 '05 #33
 On Tue, Oct 12, 2004 at 08:19:55AM +0000, Antoon Pardon wrote: | Op 2004-10-11, Jeff Shannon schreef : | > gabriele renzi wrote: | >> then what you want is a better lambda. One where you can use return, | >> maybe, and where you can have statements and multiple expressions. | >> Don't throw away the baby with the bathwater. | > | > But because of Python's line- and indentation-based syntax, doing all of | > that on a single line is... um... awkward at best, to put it mildly. | | Which is one of the reasons I think the indentation-based syntax was | a mistake. If the syntax becomes an argument against a construct | in the language, something is wrong with the syntax IMO. Indentation based structure is a godsend; a divine insight if you may. Python is much much better for it. However, just beacuse it can use indentation, doesn't mean that indentation should be mandated for every case. Python uses {} and [] to scope dict and list items, but this does not mean that a indentation based version of this wouldn't be welcome. In general, indentation is great for "outer-structure" that is, delimiting large code blocks. While delimiter based scoping is good for inner structures, small blocks of code. It should not be an either/or thing, one should properly have the option of using either option depending upon which style brings the most clarity. Cheers, Clark Jul 18 '05 #34
 Antoon Pardon wrote: Op 2004-10-11, Jeff Shannon schreef :Lambdas are hard to read, because they're significantly different,syntactically, from any other construct in the languageI didn't find them so. On the other hand I find having to come upwith a name for a function can be very inconvenient and not worththe trouble. If python wants functions to be full fledged objects,is needs some way to have unnamed functions, just as you can haveunnamed lists, numbers, instances etc.Can you imaging the protest, from people if it would be decidethat no unnamed entities van be used. If you want to use a numberor a list, as an argument you first have to name it and then usethe name as argument. Well the reason for having anonymous numbersand lists is the same reason for having anonymous functions. Functions are at a different level of granularity than numbers and lists. Anonymity makes sense for numbers and lists; it makes less sense for collections of numbers and lists; and it makes still less sense for organized collections of numbers, lists, and operations thereon, which are structured in a meaningful way to express some (part of an) algorithm. Similarly, I don't expect each line of code to have an individual name, but once I collect lines of code into a file, I certainly *do* expect to name that file, even if the file is only one or two lines long. Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #35
 Op 2004-10-12, Jeff Shannon schreef : Antoon Pardon wrote:Op 2004-10-11, Jeff Shannon schreef :Lambdas are hard to read, because they're significantly different,syntactically, from any other construct in the language I didn't find them so. On the other hand I find having to come upwith a name for a function can be very inconvenient and not worththe trouble. If python wants functions to be full fledged objects,is needs some way to have unnamed functions, just as you can haveunnamed lists, numbers, instances etc.Can you imaging the protest, from people if it would be decidethat no unnamed entities van be used. If you want to use a numberor a list, as an argument you first have to name it and then usethe name as argument. Well the reason for having anonymous numbersand lists is the same reason for having anonymous functions. Functions are at a different level of granularity than numbers and lists. Anonymity makes sense for numbers and lists; it makes less sense for collections of numbers and lists; and it makes still less sense for organized collections of numbers, lists, and operations thereon, which are structured in a meaningful way to express some (part of an) algorithm. I find it better to let the coder decide what makes sense in his program and what not. Similarly, I don't expect each line of code to have an individual name, but once I collect lines of code into a file, I certainly *do* expect to name that file, even if the file is only one or two lines long. So? If you then want to develop the code, do you put the new code in a new file and then use a program to include it, or do you put unnamed text in the already existing file? -- Antoon Pardon Jul 18 '05 #36
 Op 2004-10-12, Clark C. Evans schreef : On Tue, Oct 12, 2004 at 08:19:55AM +0000, Antoon Pardon wrote:| Op 2004-10-11, Jeff Shannon schreef :| > gabriele renzi wrote:| >> then what you want is a better lambda. One where you can use return,| >> maybe, and where you can have statements and multiple expressions.| >> Don't throw away the baby with the bathwater.| >| > But because of Python's line- and indentation-based syntax, doing all of| > that on a single line is... um... awkward at best, to put it mildly.|| Which is one of the reasons I think the indentation-based syntax was| a mistake. If the syntax becomes an argument against a construct| in the language, something is wrong with the syntax IMO. Indentation based structure is a godsend; a divine insight if you may. Python is much much better for it. That's your opinion I disagree. I find it especially annoying when I work interactively. I sometimes copy and paste something from an other window and it is just frustrating to get a syntax error back just because you had copied an extra space in front of the expression. However, just beacuse it can use indentation, doesn't mean that indentation should be mandated for every case. Python uses {} and [] to scope dict and list items, but this does not mean that a indentation based version of this wouldn't be welcome. In general, indentation is great for "outer-structure" that is, delimiting large code blocks. While delimiter based scoping is good for inner structures, small blocks of code. It should not be an either/or thing, one should properly have the option of using either option depending upon which style brings the most clarity. Well it isn't an either/or thing and I have seen it often enough that a proposed language structure was argued against because fitting it in the indentation-based syntax was going to be difficult/awkward or something like that. Suppose for the sake af the argument that someone comes up with a language structute that has almost everyone agree with that it would be usefull to include in the language. However the most natural indentation for the structure would be something like this: start: code control: code control: code I fear that alone would kill the possibility of including it in python. -- Antoon Pardon Jul 18 '05 #37
 Dave Benjamin wrote: Now, imagine you are setting up an animation this way: after(10, lambda: sprite.move(0, 5)) after(15, lambda: sprite2.rotate(30)) after(20, lambda: sprite.scale(120, 120)) after(22, lambda: sprite2.move(50, 50)) after(22, lambda: sound1.play()) after(23, lambda: sprite.move(0, 0)) after(26, lambda: sound1.stop()) Others have already mentioned altering the definition of the after() function, but you do not always have a pre-existing function that does exactly what you want, such as sprite2.rotate() or sound1.play(). Here is how I would do it, if lambda wasn't available: def lambda_(): sprite.move(0, 5) after(10, lambda_) def lambda_(): sprite2.rotate(30) after(15, lambda_) def lambda_(): sprite.scale(120, 120) after(20, lambda_) etc... I haven't verified this code in an actual interpreter, but I see no reason why it shouldn't work. I don't believe that there is any restriction on redefining functions. (pychecker might complain, though) This style isn't PEP 8 compliant, but if you don't like having two extra lines, you can always shrink it down to just one extra: def lambda_(): sprite.move(0, 5) after(10, lambda_) def lambda_(): sprite2.rotate(30) after (15, lambda_) etc... - Michael Hobbs Jul 18 '05 #38
 Clark C. Evans wrote: In general, indentation is great for "outer-structure" that is, delimiting large code blocks. While delimiter based scoping is good for inner structures, small blocks of code. It should not be an either/or thing, one should properly have the option of using either option depending upon which style brings the most clarity. The Haskell language (http://www.haskell.org) does exactly this. It uses indentation to infer structure, but the programmer is allowed to explicitly state structure using semicolons and braces. - Michael Hobbs Jul 18 '05 #39
 Clark C. Evans wrote: In general, indentation is great for "outer-structure" that is,delimiting large code blocks. While delimiter based scoping is goodfor inner structures, small blocks of code. It should not be aneither/or thing, one should properly have the option of using eitheroption depending upon which style brings the most clarity. Except that the Python philosophy is that overall, the greatest clarity is achieved by having a single obvious way to do things. In this viewpoint, there may be individual cases where delimiter-based scoping is clearer, but these are only local maxima; the use of a mixture of different styles (indentation and delimiters) will, over the entire corpus of Python-language programming, result in significantly less total clarity. Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #40
 Antoon Pardon wrote: Op 2004-10-12, Jeff Shannon schreef :Functions are at a different level of granularity than numbers andlists. Anonymity makes sense for numbers and lists; it makes less sensefor collections of numbers and lists; and it makes still less sense fororganized collections of numbers, lists, and operations thereon, whichare structured in a meaningful way to express some (part of an)algorithm.I find it better to let the coder decide what makes sense in his programand what not. Which is the Perl philosophy. Many people seem quite happy with Perl because of this TMTOWTDI attitude; personally, I prefer Python's clarity and simplicity. Similarly, I don't expect each line of code to have anindividual name, but once I collect lines of code into a file, Icertainly *do* expect to name that file, even if the file is only one ortwo lines long.So? If you then want to develop the code, do you put the new code in anew file and then use a program to include it, or do you put unnamedtext in the already existing file? Actually, I effectively do both of those, depending on circumstances. (Opening a new editor, typing in it, and then pasting that text into the middle of an existing file.) However, in this (admittedly weak, especially when pushed this far) analogy, a lambda is equivalent to putting the text in a new file, and insisting that that file not be given a name and be kept separate from the parent file, but be programmatically included nonetheless. Would you *want* to do that, even if your operating system allowed it? Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #41
 On Wed, 2004-10-13 at 10:58 -0700, Jeff Shannon wrote: Antoon Pardon wrote:Op 2004-10-12, Jeff Shannon schreef :Functions are at a different level of granularity than numbers andlists. Anonymity makes sense for numbers and lists; it makes less sensefor collections of numbers and lists; and it makes still less sense fororganized collections of numbers, lists, and operations thereon, whichare structured in a meaningful way to express some (part of an)algorithm. Hi Jeff, Jumping in way late in this thread, I'll toss in my pennies and say I still use lambda fairly regularly in one place, and it just happens to be the very place where I learned of lambda in the first place: event handlers for GUI programming. I first learned the technique in Tkinter circa 1.5.2 and still use it in wxPython. It isn't strictly necessary, but given the already cluttered nature of GUI programming, I'm pretty reluctant to toss in four or five more names every time I want a complicated event handler to get called with slightly different arguments. Basically I use it as a poor-man's curry (if I understand currying correctly, I've only seen conversations about it on this list and that's the impression I was left with: that it's a way of providing variations in the default arguments to a function). As I know you're a wxPython user as well, I'd be curious to know how you approach this particular problem. Regards, Cliff -- Cliff Wells Jul 18 '05 #42
 On Wed, Oct 13, 2004 at 10:58:14AM -0700, Jeff Shannon wrote: | Antoon Pardon wrote: | >I find it better to let the coder decide what makes sense in his program | >and what not. | | Which is the Perl philosophy. Many people seem quite happy with Perl | because of this TMTOWTDI attitude; personally, I prefer Python's clarity | and simplicity. On this list, that's damn near close to an ad hominem attack. There are more than one way to do many of things in Python, and just about every "feature" that gets added is yet another way to do something that is already being done. This doesn't stop features from being adopted, does it? Every list comprehension has an equivalent version using a while-loop. I could go on with examples, but your assertion is a leaky bucket, so why bother waste the space? Your arguments thus far have been "I don't use it, thus it probably isn't useful, and therefore, no one should be able to use it." It's an uninformed position and frankly, not very helpful. I use lambda because it: - puts the definition of an expression right where it is used; - doesn't require me to mint a name, or worry about other possible calls to the same expression; and - is efficient use of vertical coding space. All of these reasons provide clarity in maintaining code. If you are working with a programming style that uses CPS, deferred execution, or similar mechanism with heavy callbacks or passing functions, you will understand the importance of the above features. Kind Regards, Clark Jul 18 '05 #43
 Cliff Wells wrote: Hi Jeff,Jumping in way late in this thread, I'll toss in my pennies and say Istill use lambda fairly regularly in one place, and it just happens tobe the very place where I learned of lambda in the first place: eventhandlers for GUI programming. I first learned the technique in Tkintercirca 1.5.2 and still use it in wxPython. It isn't strictly necessary,but given the already cluttered nature of GUI programming, I'm prettyreluctant to toss in four or five more names every time I want acomplicated event handler to get called with slightly differentarguments. Basically I use it as a poor-man's curry (if I understandcurrying correctly, I've only seen conversations about it on this listand that's the impression I was left with: that it's a way of providingvariations in the default arguments to a function). That's my understanding of currying, as well, and I too know it only from discussion on this list. ;) But I recall that Alex Martelli, some time ago, provided a wonderful explanation of currying and a recipe or two for how it can be generically accomplished. (Before that explanation, I'd had no idea where the term came from and had been trying to work out how it coud be etymologically related to, say, currying horses... ;) ) I believe that his solution involved callable class instances that store the function to be called and the known parameters as attributes. That *was* quite a while ago (possibly even pre-2.2), though, so I don't know whether it'd still be the most effective recipe... and my memory about it is a bit flakey. As I know you're a wxPython user as well, I'd be curious to know how youapproach this particular problem. To be honest, I've rarely felt the need to do much currying in my wxPython (or other) applications. Maybe it's a design thing -- I tend to make every non-trivial component I use be a custom class/subclass, even if I'm only going to use it in one place, and it seems appropriate to have methods on that class which encapsulate its desired behavior to the point where currying isn't necessary. The closest I've come to needing currying is handled neatly by wxCallAfter(), which takes a function and a list of arguments to pass to that function. Then again, almost everything I've done so far has been fairly simple (as in low complexity, not necessarily easy...), so it's possible that I'm the odd one here... Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #44
 Clark C. Evans wrote: On Wed, Oct 13, 2004 at 10:58:14AM -0700, Jeff Shannon wrote:| Antoon Pardon wrote:| >I find it better to let the coder decide what makes sense in his program| >and what not.|| Which is the Perl philosophy. Many people seem quite happy with Perl| because of this TMTOWTDI attitude; personally, I prefer Python's clarity| and simplicity.On this list, that's damn near close to an ad hominem attack. Only if you choose to read it that way. I pointed out that many people are happy with Perl, thus implying that the philosophy behind programming languages is largely a matter of taste. It makes sense to choose a language whose design philosophy matches one's own. From this and other previous discussions, it seems to me that Antoon Pardon has a number of disagreements with Python's design goals; that's fine, he's certainly entitled to his opinion, but there are others who *do* agree with Python's design goals. ISTM that it would therefore be better, overall, for those who disagree with Pythonic philosophy to look for a different language that suits them better, and those who agree with Pythonic philosophy to keep using Python. Trying to please everyone with a single language just isn't gonna work, nor should it be expected to. Pointing this fact out has nothing to do with my personal opinions about Mr. Pardon, you, or anyone else. Your arguments thus far have been "I don't use it, thus it probablyisn't useful, and therefore, no one should be able to use it." It'san uninformed position and frankly, not very helpful. No, my arguments thus far have been that, for almost every use for which lambdas are beneficial, there's another approach that is more consistent with core Pythonic philosophy that works almost as well or better. There's lots of things that I don't use but that I think are extremely useful (metaclasses, for instance). Heck, I find metaclasses even more confusing than lambdas.... but I can also see that the *benefit* of metaclasses is greater, and is extremely difficult to match in more traditional Python. I have tried to be clear that I'm not the most experienced or talented developer ever; I'm a journeyman at best, and I know it, and I'm perfectly willing to learn from others when the benefit of their teaching is clear. But so far, the examples that I've been given for when lambda is useful are limited to "a programming style that uses CPS, deferred execution, or similar mechanism with heavy callbacks or passing functions," which may be something that you do a lot of but still sounds like a special case to me. And even within that style, alternate solutions can provide most of the benefits that lambda does. Oh, and I almost agree with you about list comprehensions -- they'd do just as well to be left out of Py3K, because they've been superseded by generator comprehensions. ;) Jeff Shannon Technician/Programmer Credit International Jul 18 '05 #47