On Thursday 18 August 2016 06:25, Terry Reedy wrote: > On 8/17/2016 2:07 AM, Steven D'Aprano wrote: > >> I realise that there are occasions where we might deliberate choose to >> assign an intermediate value to its own variable, but all else being equal, >> which would you prefer? >> >> #A >> alist = [] >> alist.append(2) >> alist.append(4) >> alist.append(8) >> process(alist) [... snip additional examples ...]
> Up to here, #A is a useless and stupid. Have you seen such code written? As a matter of fact, yes. Just the other day I posted an example from a former work-mate that was *worse* than any of those, something like this: x = [] x.append(1) x = len(x) >> #A >> def callback(btn): >> return btn.do_the_thing(42) or default >> the_button.setcommand(callback) >> process(the_button) >> >> #B >> the_button.setcommand(lambda btn: btn.do_the_thing(42) or default) >> process(the_button) > > This example is *not* parallel to the other 3. Here, A is useful real > code and might be preferred for multiple reasons. Sure -- I acknowledged at the beginning that there may be reasons why you want to give an intermediate value its own variable name. >> If you find yourself preferring B, B, B, A, you might ask yourself what >> makes a function different that you prefer to keep temporary functions >> around where they're not needed. > > When 'callback' is set as the command of the button, it is not > temporary, but must remain as long as the button remains. Only the name > binding is (possibly) disposable. The name binding is certainly disposable, because if it wasn't, you couldn't use an anonymous function (a lambda). *In general*, keeping an additional named reference to the callback around is unnecessary and wasteful -- although, as you point out and as I acknowledged, there may be exceptions. > Beginners often do not understand that the body of a lambda expression > is evaluated in a new local namespace, and only when the resulting > function is called, the same as with a def statement. They then neglect > to capture current values when writing lambda expressions in a for loop. Sure. But since the behaviour of def functions and lambda functions are identical, writing a named def won't solve that problem. > for section_name, line_number in text.parser.toc: > def goto(line=line_number): > text.yview(line) > drop.add_command(label=section_name, command=goto) > > To me, this is much better and I intend to commit it. Thank you for > prodding me to think through how bad the lambda form can be and to > rewrite the loop so I don't cringe reading it. The use of a named function here adds next to nothing. Instead of some number of anonymous functions called "<lambda>", you have an equal number of functions all named "goto". There's no easy way to distinguish them, and likely no real need to distinguish them -- they are simple enough that you can be almost certain that they are correct just from reading the code. So I don't see any benefit over this: for section_name, line_number in text.parser.toc: drop.add_command(label=section_name, command=lambda line=line_number: text.yview(line)) except that it is easier to fit in 79 columns :-) -- Steve -- https://mail.python.org/mailman/listinfo/python-list