Lambda Expressions

原文:https://treyhunner.com/2018/09/stop-writing-lambda-expressions/

这篇文章讲的是Python中lambda滥用的情况。

在实际操作中,Python的匿名函数有着诸多的缺点和限制,比如不能有函数名字,不能超过一行等。这种表达式给语义带来了额外的复杂度。相反,Python中的具名函数(def)是非常实用且应该被使用的。文中有一个PEP的引用,是这么说的:

PEP8, the official Python style guide, advises never to write code like this:


normalize_case = lambda s: s.casefold()

The above statement makes an anonymous function and then assigns it to a variable. The above code ignores the reason lambda functions are useful: lambda functions can be passed around without needing to be assigned to a variable first.

这里让用户注意,如果这样赋值Lambda表达式,就会失去了原来的意义。

但是,在Javascript中,大家经常会写出这种东西:


let myFunc = () => {

        ...

        return val

};

为什么会这样?因为Javascript中的function(){}语义实在是太过复杂了。不仅仅是有着提前执行,提前声明等特性,还会让this的指向变得很奇怪。在这种情况下,大家使用Arrow Function取代原有的function() 声明也是情有可原的了。

这里有一篇文章:https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/

里面对比了各种语言的Function表达式,实际上,Javascript 还真是最差的一个


// A very simple function in six languages.
function (a) { return a > 0; } // JS
[](int a) { return a > 0; } // C++
(lambda (a) (> a 0)) ;; Lisp
lambda a: a > 0 # Python
a => a > 0 // C#
a -> a > 0 // Java

然后this指向的问题:


{
  ...
  addAll: function addAll(pieces) {
    var self = this;
    _.each(pieces, function (piece) {
      self.add(piece);
    });
  },
  ...
}

箭头函数对于bind/apply不敏感,这个也是后话了。

然后箭头函数不绑定arguments。

所以,Javascript中的箭头函数并不是“匿名函数”,而是一种取代原有的Functions Declaration的全新语法。这样的区别下,使用function原语法只在一些非常少见的情况下有着更好的结果。在我看来,我更加希望Arrow Function能被用的更多,而不是像Python那样限制使用。