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


当前回答

因为我在这里看不到C++11示例,所以我将继续在这里发布这个很好的示例。经过搜索,这是我能找到的最清晰的语言特定示例。

你好,Lambdas,版本1

template<typename F>

void Eval( const F& f ) {
        f();
}
void foo() {
        Eval( []{ printf("Hello, Lambdas\n"); } );
}

你好,Lambdas,版本2:

void bar() {
    auto f = []{ printf("Hello, Lambdas\n"); };
    f();
}

其他回答

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演算是一种一致的替代数学理论。例如,在学校数学中,人们可以看到x+y=5与x−y=1配对。除了处理单个方程的方法外,还可以将这两个方程的信息放在一起,前提是交叉方程的替换是合乎逻辑的。Lambda演算编纂了进行这些替换的正确方法。

假设y=x−1是第二个方程的有效重排,这:λy=x–1表示用符号x−1代替符号y的函数。现在想象将λy应用于第一个方程中的每个项。如果项是y,则执行替换;否则什么都不做。如果你在纸上这样做,你会看到应用λy将如何使第一个方程可解。

这是一个没有任何计算机科学或编程的答案。

我能想到的最简单的编程示例来自http://en.wikipedia.org/wiki/Joy_(编程语言)#如何工作:

下面是如何在命令中定义平方函数编程语言(C):int平方(int x){返回x*x;}变量x是一个形式参数,由实际调用函数时要平方的值。在函数中语言(方案)将定义相同的功能:(定义正方形(λ(x)(*x x)))这在很多方面都不同,但它仍然使用形式参数x以相同的方式。


补充:http://imgur.com/a/XBHub

lambda函数可以接受任意数量的参数,但它们只包含一个表达式。。。Lambda函数可用于返回函数对象。语法上,lambda函数仅限于一个表达式。

lambda是一种内联定义的函数类型。除了lambda之外,通常还有某种类型的变量类型,可以保存对函数lambda或其他函数的引用。

例如,这里有一段不使用lambda的C#代码:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

这调用Calculator,不仅传递两个数字,还传递要在Calculator中调用的方法以获得计算结果。

在C#2.0中,我们得到了匿名方法,这将上述代码缩短为:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

然后在C#3.0中,我们得到了lambdas,这使得代码更短:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}

@Brian我一直在C#、LINQ和非LINQ运算符中使用lambdas。例子:

string[] GetCustomerNames(IEnumerable<Customer> customers)
 { return customers.Select(c=>c.Name);
 }

在C#之前,我在JavaScript中使用匿名函数来回调AJAX函数,甚至在AJAX这个词出现之前:

getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});

不过,C#lambda语法的有趣之处在于,它们本身的类型无法推断(即,您不能键入var foo=(x,y)=>x*y),但根据它们被分配给的类型,它们将被编译为表示表达式的委托或抽象语法树(这就是LINQ对象映射器如何实现“语言集成”的魔力)。

LISP中的Lambdas也可以传递给引号运算符,然后作为列表列表进行遍历。一些强大的宏是这样生成的。