对于一个没有计算机科学背景的人来说,计算机科学界的lambda是什么?


当前回答

在CS的上下文中,lambda函数是一个抽象的数学概念,它解决了数学表达式的符号求值问题。在这种情况下,lambda函数与lambda项相同。

但在编程语言中,这是不同的。这是一段被宣布为“到位”的代码,可以作为“一流公民”传递。这个概念似乎很有用,因此它几乎进入了所有流行的现代编程语言(参见lambda函数everwhere post)。

其他回答

Lambda函数或小型匿名函数是一个自包含的功能块,可以在代码中传递和使用。Lambda在不同的编程语言中有不同的名称——Python和Kotlin中的Lambda,Swift中的闭包,或者C和Objective-C中的Block。虽然lambda在这些语言中的含义非常相似,但有时会有细微差别。

让我们看看Closure(Lambda)在Swift中的工作原理:

let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]

1.正则函数

func backward(_ n1: String, _ n2: String) -> Bool {
    return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)


// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

2.闭包表达式

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in   
    return n1 > n2
})

3.内联闭包表达式

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in 
    return n1 > n2 
})

4.根据上下文推断类型

reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )

5.单表达式闭包的隐式返回

reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )

6.速记参数名称

reverseOrder = coffee.sorted(by: { $0 > $1 } )

// $0 and $1 are closure’s first and second String arguments.

7.操作员方法

reverseOrder = coffee.sorted(by: >)

// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

Lambda来自Lambda演算,指编程中的匿名函数。

为什么这么酷?它允许您在不命名的情况下编写快速丢弃函数。它还提供了一种编写闭包的好方法。有了这种力量,你可以做这样的事情。

蟒蛇

def adder(x):
    return lambda y: x + y
add5 = adder(5)
add5(1)
6

从Python片段中可以看到,函数加法器接受一个参数x,并返回一个接受另一个参数y的匿名函数或lambda。该匿名函数允许您从函数创建函数。这是一个简单的例子,但它应该传达lambdas和闭包的强大功能。

其他语言示例

Perl 5

sub adder {
    my ($x) = @_;
    return sub {
        my ($y) = @_;
        $x + $y
    }
}

my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";

JavaScript

var adder = function (x) {
    return function (y) {
        return x + y;
    };
};
add5 = adder(5);
add5(1) == 6

JavaScript(ES6)

const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6

计划

(define adder
    (lambda (x)
        (lambda (y)
           (+ x y))))
(define add5
    (adder 5))
(add5 1)
6

C#3.5或更高

Func<int, Func<int, int>> adder = 
    (int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure = 
    (x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

敏捷的

func adder(x: Int) -> (Int) -> Int{
   return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = fn () => $a + $b;

echo $lambda();

哈斯克尔

(\x y -> x + y) 

Java查看此帖子

// The following is an example of Predicate : 
// a functional interface that takes an argument 
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
    return function(y)
        return x + y
    end
end
add5 = adder(5)
add5(1) == 6        -- true

科特林

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true

Ruby

Ruby稍有不同,因为不能使用与调用函数完全相同的语法调用lambda,但它仍然有lambda。

def adder(x)
  lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6

Ruby是Ruby,有一个lambdas的简写,所以您可以这样定义加法器:

def adder(x)
  -> y { x + y }
end

R

adder <- function(x) {
  function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6

“lambda”这个名字只是一个历史产物。我们所谈论的只是一个表达式,其值是一个函数。

一个简单的例子(下一行使用Scala)是:

args.foreach(arg => println(arg))

其中foreach方法的参数是匿名函数的表达式。上面的一行与编写类似的代码大致相同(不是真正的代码,但你会明白的):

void printThat(Object that) {
  println(that)
}
...
args.foreach(printThat)

除了你不需要麻烦:

在其他地方声明函数(稍后重新访问代码时必须查找它)。命名你只使用一次的东西。

一旦你习惯了函数值,就不得不不使用它们,就像需要命名每个表达式一样愚蠢,比如:

int tempVar = 2 * a + b
...
println(tempVar)

而不是只在需要的地方编写表达式:

println(2 * a + b)

确切的符号因语言而异;希腊语并不总是必需的!;-)

它是一个没有名称的函数。例如,在c#中,您可以使用

numberCollection.GetMatchingItems<int>(number => number > 5);

返回大于5的数字。

number => number > 5

这里是lambda部分。它表示一个接受参数(数字)并返回布尔值(数字>5)的函数。GetMatchingItems方法对集合中的所有项使用此lambda并返回匹配项。

这个问题已经得到了正式的回答,因此我不会试图对此做更多的补充。

对于一个对数学或编程知之甚少或一无所知的人来说,用非常简单、非正式的话来说,我会把它解释为一个小的“机器”或“盒子”,它接受一些输入,产生一些工作,产生一些输出,没有特定的名称,但我们知道它在哪里,就凭这些知识,我们使用它。

实际上,对于一个知道函数是什么的人来说,我会告诉他们这是一个没有名字的函数,通常放在内存中的一个点上,只需引用该内存即可使用(通常通过使用一个变量-如果他们听说过函数指针的概念,我会将其用作类似的概念)-这个答案涵盖了非常基本的内容(没有提到闭包等),但人们可以很容易地理解这一点。