对于一个没有计算机科学背景的人来说,计算机科学界的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();
}

其他回答

@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也可以传递给引号运算符,然后作为列表列表进行遍历。一些强大的宏是这样生成的。

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);
}

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”这个名字只是一个历史产物。我们所谈论的只是一个表达式,其值是一个函数。

一个简单的例子(下一行使用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)

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

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

我将用简单易读的python代码一步一步直观地说明它。

简而言之,lambda只是一个匿名内联函数。

让我们从作业开始,了解兰达斯作为一名有基础算术背景的新生。

任务蓝图为“名称=值”,请参见:

In [1]: x = 1
   ...: y = 'value'
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: 'value'

“x”、“y”是名称,“1”、“value”是值。尝试数学中的函数

In [4]: m = n**2 + 2*n + 1
NameError: name 'n' is not defined

错误报告,不能将数学直接作为代码编写,“n”应该被定义或赋值。

In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396

它现在起作用了,如果你坚持将两条seperarte线合并为一条呢。lambda来了

In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>

未报告错误。

这是对lambda的一瞥,它使您能够像在数学中那样在单行中直接将函数写入计算机。

我们稍后再看。

让我们继续深入了解“任务”。

如上所示,等号=适用于简单数据(1和“value”)类型和简单表达式(n**2+2*n+1)。

试试看:

In [15]: x = print('This is a x')
This is a x
In [16]: x
In [17]: x = input('Enter a x: ')
Enter a x: x

它适用于简单的语句,在python7中有11种类型。简单语句-Python 3.6.3文档

复合陈述如何,

In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax

出现了def使其工作

In [23]: def m(n):
    ...:     if n > 0:
    ...:         return n**2 + 2*n + 1
    ...:
In [24]: m(2)
Out[24]: 9

Tada,分析一下,“m”是名称,“n**2+2*n+1”是值是“=”的变体。找到它,如果只是为了理解,一切都从任务开始,一切都是任务。

现在返回lambda,我们有一个名为“m”的函数

Try:

In [28]: m = m(3)
In [29]: m
Out[29]: 16

这里有两个“m”的名称,函数m已经有一个重复的名称。

它的格式如下:

In [27]: m = def m(n):
    ...:         if n > 0:
    ...:             return n**2 + 2*n + 1
    SyntaxError: invalid syntax

这不是一个明智的策略,因此错误报告

我们必须删除其中一个,设置一个没有名称的函数。

m = lambda n:n**2 + 2*n + 1

它叫做“匿名函数”

总之,

内联函数中的lambda,它使您能够像数学中那样在一条直线上编写函数lambda是匿名的

希望,这有帮助。