Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]

2005-07-07 Thread Duncan Booth
Steven D'Aprano wrote:
> This is something I've never understood. Why is it bad 
> form to assign an "anonymous function" (an object) to a 
> name?

Because it obfuscates your code for no benefit. You should avoid making it 
hard for others to read your code (and 'others' includes yourself in the 
future).

Also, it obfuscates tracebacks: all lambda expressions will identify in 
tracebacks as , but if you define a function you can give it a 
meaningful name.

> 
> Why is it considered abuse of lambda to assign the 
> functions to a name? Is it an abuse of lambda to do this?
> 
> D = {"one": lambda noun: noun,
>  "two": lambda noun: noun + 's',
>  "many": lambda noun: 'lots of ' + noun + 's' }
> 
> assert D["two"]("python") == "pythons"
> 
> 
No, that is approaching a reasonable use of lambda, however I would still 
be inclined to write it with functions. e.g.

   def one(noun):
   return noun

   def two(noun):
   return noun+'s'

   def many(noun):
   return 'lots of %ss' % (noun,)

   D = dict(one=one, two=two, many=many)

although in this particular case I would probably just put format strings 
in the dictionary:

  def D(style, noun):
 formats = dict(one="%s", two="%ss", many="lots of %ss")
 return formats.get(style, "an indeterminate number of %ss") % (noun,)

  assert D("two","python") == "pythons"
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]

2005-07-07 Thread Steven D'Aprano
On Thu, 07 Jul 2005 09:36:24 +, Duncan Booth wrote:

> Steven D'Aprano wrote:
>> This is something I've never understood. Why is it bad 
>> form to assign an "anonymous function" (an object) to a 
>> name?
> 
> Because it obfuscates your code for no benefit. You should avoid making it 
> hard for others to read your code (and 'others' includes yourself in the 
> future).

I don't particularly think I'm that much smarter than the average
programmer. In fact I *know* that I'm not that much smarter. So why do I
see nothing obfuscated or obscure or difficult to understand in func =
lambda x: x**3 - 5*x when apparently most of the Python community find it
too complicated?

Whichever is "more readable" in the absolute sense, the "abused" lambda
expression above is within a gnat's whisker of the def equivalent,

def func(x):
return x**3 - 5*x

I honestly don't understand why it is supposed to be so hard to follow.

I can think of many function which should not be written with lambda, just
as some things shouldn't be written as list comps. But within the limits
of how much complexity you can reasonably include in a single expression,
I don't see why lambda puts people off.

I make it, eight mental tokens (not necessarily the same as Python tokens)
for the lambda versus nine for the def. A trivial difference. In my mind,
the tokens are:

func, =, lambda, x, :, x**3, -, 5*x

compared to:

def, func, (), x, :, return, x**3, -, 5*x

(Your mental parser may differ.)


> Also, it obfuscates tracebacks: all lambda expressions will identify in 
> tracebacks as , but if you define a function you can give it a 
> meaningful name.

Well there is that. If you have lots of lambdas assigned to names, I guess
debugging could be more difficult:

py> f = lambda x: 1.0/x
py> f(0)
Traceback (most recent call last):
  File "", line 1, in ?
  File "", line 1, in 
ZeroDivisionError: float division


py> def f(x):
... return 1.0/x
...
>>> f(0)
Traceback (most recent call last):
  File "", line 1, in ?
  File "", line 2, in f
ZeroDivisionError: float division

So far so good. But then:

py> g = f
py> del f
py> g(0)
Traceback (most recent call last):
  File "", line 1, in ?
  File "", line 2, in f
ZeroDivisionError: float division

(but we actually got the error by calling g, not f, and in fact f no
longer exists at the point we called g)


>> Why is it considered abuse of lambda to assign the 
>> functions to a name? Is it an abuse of lambda to do this?
>> 
>> D = {"one": lambda noun: noun,
>>  "two": lambda noun: noun + 's',
>>  "many": lambda noun: 'lots of ' + noun + 's' }
>> 
>> assert D["two"]("python") == "pythons"
>> 
>> 
> No, that is approaching a reasonable use of lambda, however I would still 
> be inclined to write it with functions. e.g.
> 
>def one(noun):
>return noun
> 
>def two(noun):
>return noun+'s'
> 
>def many(noun):
>return 'lots of %ss' % (noun,)
> 
>D = dict(one=one, two=two, many=many)

I find your version far more difficult to follow than mine.

Psychologically, I find that defs seem to carry significant mental weight
in a way that lambdas don't. Even though the lambda forms are
equivalent to the def forms, I find that the defs are more heavy-weight in
my conceptual map of the program than a lambda would be.

Put it this way: whenever I see a two-line def as above, I can't help
feeling that it is a waste of a def. ("Somebody went to all the trouble
to define a function for *that*?") Yet I would never think the same about
a lambda -- lambdas just feel like they should be light-weight. 

Am I just weird?



-- 
Steven.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]

2005-07-07 Thread Duncan Booth
Steven D'Aprano wrote:

> Put it this way: whenever I see a two-line def as above, I can't help
> feeling that it is a waste of a def. ("Somebody went to all the trouble
> to define a function for *that*?") Yet I would never think the same about
> a lambda -- lambdas just feel like they should be light-weight. 

Obviously we think differently there. I don't see why lambdas are any 
different than single expression functions. I certainly don't think of them 
as lighter weight; they take just as long to call; and they involve just as 
much stack setup/tear down. On the other hand I don't consider functions as 
heavyweight, I'm happy to define short helper functions anywhere I think it 
makes the code more expressive.

> Am I just weird?

No, just different[*]. There's nothing wrong with different.

[*] conclusion based entirely on your postings here. I have no evidence 
beyond that.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]

2005-07-07 Thread Bengt Richter
On 7 Jul 2005 15:46:23 GMT, Duncan Booth <[EMAIL PROTECTED]> wrote:

>Steven D'Aprano wrote:
>
>> Put it this way: whenever I see a two-line def as above, I can't help
>> feeling that it is a waste of a def. ("Somebody went to all the trouble
>> to define a function for *that*?") Yet I would never think the same about
>> a lambda -- lambdas just feel like they should be light-weight. 
>
>Obviously we think differently there. I don't see why lambdas are any 
>different than single expression functions. I certainly don't think of them 
>as lighter weight; they take just as long to call; and they involve just as 
>much stack setup/tear down. On the other hand I don't consider functions as 
>heavyweight, I'm happy to define short helper functions anywhere I think it 
>makes the code more expressive.
>
>> Am I just weird?
>
>No, just different[*]. There's nothing wrong with different.
>
>[*] conclusion based entirely on your postings here. I have no evidence 
>beyond that.
>
I think def is a form of assignment, with the target binding name
specified inside the expression syntax instead of to the left of an '=' as 
usual. I.e.,

def f(args): suite

is like

f = def(args): suite

except that I can't use an arbitrary left-hand side in the assignment, such as

MyClass.method = def(self, args): suite
or
   somedict['foo'] = def(self, args): suite

Personally, I think def(args): suite ought to be allowed as an expression that 
you could
put in parentheses like any other expression if you need/want to write it with 
multiple lines.
Obviously this could both replace and expand the functionality of lambda ;-)

Regards,
Bengt Richter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]

2005-07-07 Thread Ron Adam
Steven D'Aprano wrote:

> On Thu, 07 Jul 2005 09:36:24 +, Duncan Booth wrote:
> 
> 
>>Steven D'Aprano wrote:
>>
>>>This is something I've never understood. Why is it bad 
>>>form to assign an "anonymous function" (an object) to a 
>>>name?
>>
>>Because it obfuscates your code for no benefit. You should avoid making it 
>>hard for others to read your code (and 'others' includes yourself in the 
>>future).

Use a descriptive name like this?

def get_the_cube_of_x_and_then_subtract_five_multiplied_by_x(x):
  x**3 - 5*x

I think I like the lambda version here.  ;-)

It would probably have a name which refers to the context in which it's 
used, but sometimes the math expression it self is also the most readable.



> Put it this way: whenever I see a two-line def as above, I can't help
> feeling that it is a waste of a def. ("Somebody went to all the trouble
> to define a function for *that*?") Yet I would never think the same about
> a lambda -- lambdas just feel like they should be light-weight. 

In the case of an interface module you might have a lot of two like 
def's that simply change the name and argument format so several modules 
can use it and have a standard consistent or simplified interface.

The lambda may be perfectly fine for that.  But why not use def?

func_x = lambda x: (someother_func_x(x,'value'))

def func_x(x): return someother_func_x(x,'value')

There's both nearly identical, but the def is understandable to 
beginners and advanced python programs.


Cheers,
Ron


> Am I just weird?

Aren't we all?   ;-)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Why anonymity? [was Re: map/filter/reduce/lambda opinions and background unscientific mini-survey]

2005-07-07 Thread Daniel Schüle
> Am I just weird?

I feel the same way about where to use lambda's and where *not*
I come from C and C++ background and defining a function at the top 
level (no nested functions) would always require good reasons

function name has to be remembered, to put it in other words it has to 
be added in a mental list of available function
and writing a 2 liner function would only cause call overhead
(if not inlined) this may be the reason why "def" feels to me to have 
more weight as "lambda"
usually you define lambda and forget it, no wasted time to find proper 
name, which may also pollute the namespace
I find it more clear solution, it's concise

-- 
http://mail.python.org/mailman/listinfo/python-list