Why does the father of Python dislike lambda anonymous functions?


Python supports lambda anonymous functions, and its extended BNF representation islambda_expr ::= "lambda" [parameter_list] ":" expressionThat is to sayLambda parameter sequences: expressions

This is a convenient way to define a function. If it is translated into a well-known function form, it will look like this:

def <lambda>(parameter_list):
    return expression

in other words,The lambda function in Python is a function that can receive multiple parameters, and the return value is an expression.

Its biggest advantage is the simplicity of a single line, without the need for function naming and line feed indentation.

It has to be said that anonymous functions are sometimes very useful. For example, some common usages will be introduced below, so they are highly praised by many people.

However, anonymous functions usually make the code difficult to read and easy to be abused. In addition, python only provides “disabled” support for it, so there are some views that do not recommend using anonymous functions.

in fact,Guido van Rossum, the father of python, belongs to the “not recommended group”. He even wanted to remove lambda (in 2005), but finally compromised.

Why does the father of Python dislike lambda anonymous functions?


Lambda, a feature contributed by other developers (borrowed from LISP language), has existed for more than ten years, but it was rejected by the creator (chief designer) of this language, and finally miraculously survived. Do you think this story is quite dramatic?

Next, let’s talk about this awkward but tenacious lambda anonymous function!

1. How to use lambda?

Lambda function is usually used in combination with map (), reduce (), filter (), sorted (), etcCan receive other functions as parameters.

For example, the following examples:

my_list = [3, 1, 5, 4, 10]

#The results are as follows: [4, 2, 6, 5, 11]
list(map(lambda i:i+1, my_list)) 

#Filter elements less than 10, result: [3, 1, 5, 4]
list(filter(lambda i:i<10, my_list)) 

#Element accumulation, result: 33
from functools import reduce
reduce(lambda i,j:i+j, my_list, 10)

#The dictionary is sorted by value, and the result is: [('b ', 1), ('a', 3), ('d ', 4), ('c', 5)]
my_dict = {'a':3, 'b':1, 'c':5, 'd':4}
sorted(my_dict.items(), key=lambda item:item[1])

Beginners may not understand the code, but just remember“Functions in Python are first-class citizens”It’s easy to understand when you know that a function can be used as a parameter or return value of another function.

For example, for the map() function, you can understand it in this form:

my_func = lambda i:i+1
list(map(my_func, my_list)) 

It can even be reduced to a normal function:

def add_one(i):
    return i+1

list(map(add_one, my_list)) 

The first parameter of the map () function is a function, and the second parameter is an iterative object. The first parameter iteratively calls the element in the second parameter, and the result of the call is returned as an iterator.

In this example, list () is used to make it easy to take out the elements in the iterator at one time and show them intuitively. In actual use, it is likely to be based on the iterator.

From these usages, we can sum up the rules of using lambda function

  • It appears where functions are needed
  • It is suitable for simple functions
  • It is a one-time use and cannot be reused elsewhere
  • It is generally not used independently and is always part of other functions

2. What’s wrong with lambda?

It can be seen from the above usage that the code using lambda function is compact and concise, so some people say it embodies the elegant idea of “Python”.

But is there any defect in lambda function?

yes! The biggest problem of the current lambda function is that it only supports single line expressions and can not achieve rich functions. For example, it can’t use statement when creating a function, it can’t use if else judgment conditions, it can’t use try except exception capture mechanism, and so on.

This greatly limits its ability, leading to its being criticized as “disabled”.

From the perspective of technology implementation,This problem can be solved by the design of grammar.

In the mail group discussion of that year, some solutions were put forward, such as this email:

Why does the father of Python dislike lambda anonymous functions?


It raises a questionlambda args::suiteIt supports the idea of writing in this form:

ss = sorted(seq, key=(lambda x::
            try: return abs(x)
            except TypeError: return 0))

But Guido quickly rejected the idea.

He wrote an article “language design is not just solving puzzles” to respond:

Why does the father of Python dislike lambda anonymous functions?


The basic viewpoints are as followsIf we can’t solve a problem or realize a function, we should introduce a language design lacking “pythonicity”.

So why does Guido think it’s a bad design?

I try to summarize the reasons

  • Double colon ‘::’ is introduced here, but it is completely different from ‘::’ in slicing syntax, and it is also different from the usage of scope operator in C + + / Perl
  • Even if you don’t use double colons, it’s still hard to use other symbols (such as single colon), because it will embed an indented code block in an expression. This is just as unacceptable as using curly braces and begin / end keywords to group statements
  • It’s not important to implement other functions in lambda, which also makes the parser more complicated (it’s necessary to distinguish whether there is indentation or record indentation level), which makes it a fuss

In short,He thinks that simple and friendly user experience is more important. If simple syntax can’t meet the needs, it should be written in the form of named function instead of designing complex anonymous function.

3. Why does Guido want to remove lambda?

The multi statement lambda event mentioned above happened in 2006. We can see why Guido didn’t want to introduce complex design to lambda.

However, as early as 2005, Guido wanted to remove lambda from python. His “aversion” to it is a “long history” tradition

In the short article “the fate of reduce() in Python 3000”, Guido proposed to remove reduce(), map(), filter() and lambda at one time.

The reasons for removing lambda are as follows:

  • For users who are not familiar with LISP or scheme, the name lambda is easy to cause confusion
  • Many people mistakenly think that anonymous functions can do what nested functions can’t, but there is no difference; The existence of lambda will lead to unnecessary choices. Reducing choices can simplify thinking
  • After removing reduce (), map (), and filter (), there is no need to write short local functions

Looking back on the four rules of using lambda summarized in the previous paper, we can find that it has a strong “parasitic relationship” with several higher-order functions (functions that can accept other functions as parameters). If they can be removed, lambda really has no independent significance.

So, why does Guido think we should remove those higher-order functions?

The main reasons are as follows:

  • For example, filter (P, s) can be written as [x for X in s if P (x)], map (F, s) can be written as [f (x) for X in S]
  • As for reduce (), he said it was the most annoying. Except for a few usages involving + and *, he always had to take out a pen and paper to draw a diagram. In addition to explicitly writing loops, he also proposed several alternative usages for several usages of reduce (), including the introduction of new any () and all () functions

In general, Guido’s idea coincides with this one in the Zen of Python:There should be one– and preferably only one –obvious way to do it。

But back to reality, in order to take care of some people’s habits, as well as compatibility considerations, Guido finally conservatively gave up the “clean up heresy” plan.

As a result, lambda was able to escape from the hands of Python’s supreme dictator. It wasn’t until a year later, when it tried to make waves (multiline expressions), that it was crushed.

I seem to hear Guido’s inner OS: when I wanted to delete things, you tried every means to obstruct, now you want to add things, hum, no way

Why does the father of Python dislike lambda anonymous functions?

Ha ha, I’m kidding.

All of Guido’s decisions reflect his design aesthetics of python, self consistent logic and the balance of community voice.

As for lambda, I agree with him, and by looking back at the history of syntax development, I feel that my understanding of Python has become richer. I don’t know if you feel the same way?

Finally, several articles related to python programming are attached for further reading

1、Len (x) defeats X. len (), the design idea of Python from the perspective of built-in functions

2、Programming language: when to borrow and when to create?

3、Why does Python keep explicit self?

4、Why does Python use indentation to divide code blocks?