Bri*_*haw 714 language-agnostic theory lambda computer-science terminology
对于没有comp-sci背景的人来说,计算机科学领域的lambda是什么?
mk.*_*mk. 1043
Lambda来自Lambda微积分,指的是编程中的匿名函数.
为什么这很酷?它允许您在不命名的情况下编写快速丢弃功能.它还提供了一种编写闭包的好方法.有了这种力量,你就可以做到这样的事情.
蟒蛇
def adder(x):
return lambda y: x + y
add5 = adder(5)
add5(1)
6
Run Code Online (Sandbox Code Playgroud)
正如您从Python的片段中看到的那样,函数加法器接受参数x,并返回一个匿名函数或lambda,它接受另一个参数y.该匿名函数允许您从函数创建函数.这是一个简单的例子,但它应该传达lambda和闭包的力量.
其他语言的例子
JavaScript的
sub adder {
my ($x) = @_;
return sub {
my ($y) = @_;
$x + $y
}
}
my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";
Run Code Online (Sandbox Code Playgroud)
JavaScript(ES6)
var adder = function (x) {
return function (y) {
return x + y;
};
};
add5 = adder(5);
add5(1) == 6
Run Code Online (Sandbox Code Playgroud)
方案
const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6
Run Code Online (Sandbox Code Playgroud)
(define adder
(lambda (x)
(lambda (y)
(+ x y))))
(define add5
(adder 5))
(add5 1)
6
Run Code Online (Sandbox Code Playgroud)
迅速
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);
Run Code Online (Sandbox Code Playgroud)
PHP
func adder(x: Int) -> (Int) -> Int{
return { y in x + y }
}
let add5 = adder(5)
add5(1)
6
Run Code Online (Sandbox Code Playgroud)
哈斯克尔
$a = 1;
$b = 2;
$lambda = function () use (&$a, &$b) {
echo $a + $b;
};
echo $lambda();
Run Code Online (Sandbox Code Playgroud)
Java看到这篇文章
(\x y -> x + y)
Run Code Online (Sandbox Code Playgroud)
LUA
// 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
Run Code Online (Sandbox Code Playgroud)
科特林
adder = function(x)
return function(y)
return x + y
end
end
add5 = adder(5)
add5(1) == 6 -- true
Run Code Online (Sandbox Code Playgroud)
红宝石
Ruby略有不同,因为你不能使用与调用函数完全相同的语法来调用lambda,但它仍然有lambdas.
val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true
Run Code Online (Sandbox Code Playgroud)
Ruby是Ruby,有一个lambdas的简写,所以你可以这样定义adder
:
def adder(x)
lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6
Run Code Online (Sandbox Code Playgroud)
ang*_*son 104
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);
}
Run Code Online (Sandbox Code Playgroud)
这会调用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;
});
}
Run Code Online (Sandbox Code Playgroud)
然后在C#3.0中我们得到了lambda,它使代码更短:
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);
}
Run Code Online (Sandbox Code Playgroud)
joe*_*ely 68
"lambda"这个名字只是一个历史文物.我们所谈论的只是一个表达式,其值是一个函数.
一个简单的例子(使用Scala作为下一行)是:
args.foreach(arg => println(arg))
Run Code Online (Sandbox Code Playgroud)
其中foreach
方法的参数是匿名函数的表达式.上面这行与写这样的东西大致相同(不是真正的代码,但你会得到这个想法):
void printThat(Object that) {
println(that)
}
...
args.foreach(printThat)
Run Code Online (Sandbox Code Playgroud)
除了你不需要打扰:
一旦习惯了函数值,不必使用它们就像要求命名每个表达式一样愚蠢,例如:
int tempVar = 2 * a + b
...
println(tempVar)
Run Code Online (Sandbox Code Playgroud)
而不是只在你需要的地方写表达式:
println(2 * a + b)
Run Code Online (Sandbox Code Playgroud)
确切的表示法因语言而异; 希腊语并不总是必需的!;-)
Mar*_*ade 62
它指的是lambda演算,它是一个只有lambda表达式的正式系统,它表示一个函数,它为其唯一的参数获取一个函数并返回一个函数.lambda演算中的所有函数都属于那种类型,即? : ? ? ?
.
Lisp使用lambda概念来命名它的匿名函数文字.这个lambda代表一个函数,它接受两个参数x和y,并返回它们的产品:
(lambda (x y) (* x y))
Run Code Online (Sandbox Code Playgroud)
它可以像这样在线应用(评估为50):
((lambda (x y) (* x y)) 5 10)
Run Code Online (Sandbox Code Playgroud)
iso*_*mes 50
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_(programming_language)#How_it_works:
这里是如何在命令式编程语言(C)中定义square函数:
Run Code Online (Sandbox Code Playgroud)int square(int x) { return x * x; }
变量x是形式参数,在调用函数时由实际值替换为平方.在函数式语言(Scheme)中,将定义相同的函数:
Run Code Online (Sandbox Code Playgroud)(define square (lambda (x) (* x x)))
这在许多方面是不同的,但它仍然以相同的方式使用形式参数x.
补充: http ://imgur.com/a/XBHub
Kei*_*ith 14
略微过度简化:lambda函数是一个可以传递给其他函数并且可以访问逻辑的函数.
在C#中,lambda语法通常以与匿名委托相同的方式编译为简单方法,但它也可以被分解并读取其逻辑.
例如(在C#3中):
LinqToSqlContext.Where(
row => row.FieldName > 15 );
Run Code Online (Sandbox Code Playgroud)
LinqToSql可以读取该函数(x> 15)并将其转换为实际的SQL以使用表达式树执行.
上述声明变为:
select ... from [tablename]
where [FieldName] > 15 --this line was 'read' from the lambda function
Run Code Online (Sandbox Code Playgroud)
这与普通方法或匿名委托(实际上只是编译器魔法)不同,因为它们无法读取.
并非C#中使用lambda语法的所有方法都可以编译为表达式树(即实际的lambda函数).例如:
LinqToSqlContext.Where(
row => SomeComplexCheck( row.FieldName ) );
Run Code Online (Sandbox Code Playgroud)
现在无法读取表达式树 - SomeComplexCheck无法分解.SQL语句将在没有where的情况下执行,并且数据中的每一行都将被接通SomeComplexCheck
.
Lambda函数不应与匿名方法混淆.例如:
LinqToSqlContext.Where(
delegate ( DataRow row ) {
return row.FieldName > 15;
} );
Run Code Online (Sandbox Code Playgroud)
这也有一个'内联'函数,但这次它只是编译器魔术 - C#编译器会将其拆分为具有自动生成名称的新实例方法.
匿名方法无法读取,因此逻辑无法转换为lambda函数.
\n\nA
\nLambda Function
或 aSmall Anonymous Function
是一个独立的功能块,可以在代码中传递和使用。Lambda 在不同的编程语言中有不同的名称 \xe2\x80\x93Lambda
在Python和Kotlin中,Closure
在Swift中,或者Block
在C和Objective-C中中。尽管 lambda 的含义对于这些语言非常相似,但有时也有细微的区别。
let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]\n
Run Code Online (Sandbox Code Playgroud)\nfunc backward(_ n1: String, _ n2: String) -> Bool {\n return n1 > n2\n}\nvar reverseOrder = coffee.sorted(by: backward)\n\n\n// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]\n
Run Code Online (Sandbox Code Playgroud)\nreverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in \n return n1 > n2\n})\n
Run Code Online (Sandbox Code Playgroud)\nreverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in \n return n1 > n2 \n})\n
Run Code Online (Sandbox Code Playgroud)\nreverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )\n
Run Code Online (Sandbox Code Playgroud)\nreverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )\n
Run Code Online (Sandbox Code Playgroud)\nreverseOrder = coffee.sorted(by: { $0 > $1 } )\n\n// $0 and $1 are closure\xe2\x80\x99s first and second String arguments.\n
Run Code Online (Sandbox Code Playgroud)\nreverseOrder = coffee.sorted(by: >)\n\n// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]\n
Run Code Online (Sandbox Code Playgroud)\n
我喜欢本文中对Lambdas的解释:LINQ的演变及其对C#设计的影响.它对我来说很有意义,因为它展示了Lambdas的真实世界,并将其作为一个实际例子构建出来.
他们的快速解释:Lambdas是一种将代码(函数)视为数据的方法.
Ruby中lambda的一个例子如下:
hello = lambda do
puts('Hello')
puts('I am inside a proc')
end
hello.call
Run Code Online (Sandbox Code Playgroud)
将生成以下输出:
Hello
I am inside a proc
Run Code Online (Sandbox Code Playgroud)
Lambda 是一个匿名函数。这意味着 lambda 是 Python 中的一个函数对象,之前不需要引用。让我们在这里考虑一下这段代码:
def name_of_func():
#command/instruction
print('hello')
print(type(name_of_func)) #the name of the function is a reference
#the reference contains a function Object with command/instruction
Run Code Online (Sandbox Code Playgroud)
为了证明我的主张,我打印出返回我们的 name_of_func 类型:
<class 'function'>
Run Code Online (Sandbox Code Playgroud)
函数必须有接口,但接口讲解员需要包含一些东西。这是什么意思?让我们仔细看看我们的函数,我们可能会注意到,除了函数的名称之外,我们还需要解释一些更多的细节才能理解函数是什么。
常规函数将使用语法“def”进行定义,然后输入名称并使用“()”确定接口,并使用语法“:”结束定义。现在我们使用指令/命令进入函数体。
那么让我们在这里考虑一下这段代码:
<class 'function'>
Run Code Online (Sandbox Code Playgroud)
在本例中,我们运行名为“print_my_argument”的函数并通过接口传递参数/参数。输出将是:
Hello
Run Code Online (Sandbox Code Playgroud)
现在我们知道什么是函数以及函数的架构如何工作,我们可以看一下匿名函数。让我们在这里考虑一下这段代码:
def print_my_argument(x):
print(x)
print_my_argument('Hello')
Run Code Online (Sandbox Code Playgroud)
这些函数对象几乎相同,除了上面的常规函数有一个名称而另一个函数是匿名函数这一事实之外。让我们仔细看看我们的匿名函数,以了解如何使用它。
那么让我们在这里考虑一下这段代码:
Hello
Run Code Online (Sandbox Code Playgroud)
所以上面代码我们所做的就是再写一次,一个常规函数和一个匿名函数。我们已将匿名函数分配给 var,这与为该函数命名几乎相同。无论如何,输出将是:
Hello Worl
Hello Worl
Run Code Online (Sandbox Code Playgroud)
为了充分证明 lambda 是一个函数对象,而不仅仅是模仿函数,我们在这里运行这段代码:
def name_of_func():
print('Hello')
lambda: print('Hello')
Run Code Online (Sandbox Code Playgroud)
输出将是:
Hello Worl
<class 'function'>
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的一点是,你应该知道 python 中的每个函数都需要返回一些东西。如果函数体中没有定义任何内容,则默认返回 None 。看看这里的这段代码:
def delete_last_char(arg1=None):
print(arg1[:-1])
string = 'Hello World'
delete_last_char(string)
f = lambda arg1=None: print(arg1[:-1])
f(string)
Run Code Online (Sandbox Code Playgroud)
输出将是:
Hello Worl
Hello Worl
None
None
Run Code Online (Sandbox Code Playgroud)
@Brian我一直在C#中使用lambdas,在LINQ和非LINQ运算符中.例:
string[] GetCustomerNames(IEnumerable<Customer> customers)
{ return customers.Select(c=>c.Name);
}
Run Code Online (Sandbox Code Playgroud)
在C#之前,我使用JavaScript中的匿名函数来回调AJAX函数,之后创建了Ajax这个术语:
getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});
Run Code Online (Sandbox Code Playgroud)
然而,C#的lambda语法的有趣之处在于它们自己的类型不能被推测(即,你不能输入var foo =(x,y)=> x*y)但是它们取决于它们的类型分配给它们,它们将被编译为表示表达式的委托或抽象语法树(这是LINQ对象映射器如何进行"语言集成"魔术).
LISP中的Lambdas也可以传递给报价运算符,然后作为列表列表遍历.一些强大的宏是以这种方式制作的.
仅仅因为我在这里看不到 C++11 示例,我将继续从这里发布这个不错的示例。搜索后,这是我能找到的最清晰的语言特定示例。
template<typename F>
void Eval( const F& f ) {
f();
}
void foo() {
Eval( []{ printf("Hello, Lambdas\n"); } );
}
Run Code Online (Sandbox Code Playgroud)
void bar() {
auto f = []{ printf("Hello, Lambdas\n"); };
f();
}
Run Code Online (Sandbox Code Playgroud)
这个问题正式得到了很好的回答,所以我不会试图在此上添加更多内容.
对于那些对数学或编程知之甚少或根本不知道的人来说,非常简单,非正式的话,我会把它解释为一个小的"机器"或"盒子",需要一些输入,做一些工作并产生一些输出,没有特别的名字,但我们知道它在哪里,只有这些知识,我们才能使用它.
实际上,对于一个知道函数是什么的人,我会告诉他们这是一个没有名字的函数,通常放在内存中只能通过引用该内存来使用(通常是通过使用一个变量 - 如果他们已经听说过函数指针的概念,我会将它们用作类似的概念) - 这个答案涵盖了漂亮的基础知识(没有提到闭包等),但是人们可以很容易地理解它.
\n\n\n对于没有计算机科学背景的人来说,计算机科学世界中的 lambda 是什么?
\n
我将用简单易读的Python代码一步步直观地说明。
\n\n简而言之,lambda 只是一个匿名内联函数。
\n\n让我们从作业开始,lambdas
以一个有基础算术背景的新生来理解。
赋值的蓝图是“名称=值”,参见:
\n\nIn [1]: x = 1\n ...: y = \'value\'\nIn [2]: x\nOut[2]: 1\nIn [3]: y\nOut[3]: \'value\'\n
Run Code Online (Sandbox Code Playgroud)\n\n\'x\'、\'y\' 是名称,1、\'value\' 是值。\n尝试数学函数
\n\nIn [4]: m = n**2 + 2*n + 1\nNameError: name \'n\' is not defined\n
Run Code Online (Sandbox Code Playgroud)\n\n错误报告,
\n您不能直接将数学编写为代码,\'n\' 应定义或分配给一个值。
In [8]: n = 3.14\nIn [9]: m = n**2 + 2*n + 1\nIn [10]: m\nOut[10]: 17.1396\n
Run Code Online (Sandbox Code Playgroud)\n\n现在可以了,如果你坚持将两条单独的线合并为一条会怎么样。\n出现lambda
In [13]: j = lambda i: i**2 + 2*i + 1\nIn [14]: j\nOut[14]: <function __main__.<lambda>>\n
Run Code Online (Sandbox Code Playgroud)\n\n没有报告错误。
\n\n这是一个概览lambda
,它使您能够像在数学中直接将函数写入计算机一样,在一行中编写函数。
我们稍后会看到。
\n\n让我们继续深入挖掘“作业”。
\n\n如上所述,等号=
适用于简单数据(1 和“值”)类型和简单表达式(n**2 + 2*n + 1)。
尝试这个:
\n\nIn [15]: x = print(\'This is a x\')\nThis is a x\nIn [16]: x\nIn [17]: x = input(\'Enter a x: \')\nEnter a x: x\n
Run Code Online (Sandbox Code Playgroud)\n\n它适用于简单语句,python 7 中有 11 种类型。简单语句 \xe2\x80\x94 Python 3.6.3 文档
\n\n复合语句怎么样,
\n\nIn [18]: m = n**2 + 2*n + 1 if n > 0\nSyntaxError: invalid syntax\n#or\nIn [19]: m = n**2 + 2*n + 1, if n > 0\nSyntaxError: invalid syntax\n
Run Code Online (Sandbox Code Playgroud)\n\n来def
让它工作
In [23]: def m(n):\n ...: if n > 0:\n ...: return n**2 + 2*n + 1\n ...:\nIn [24]: m(2)\nOut[24]: 9\n
Run Code Online (Sandbox Code Playgroud)\n\n多田,分析一下,\'m\'是名称,\'n**2 + 2*n + 1\'是值。:
是 \'=\' 的变体。
\n找到了,如果只是为了理解,一切都是从赋值开始,一切都是赋值。
现在返回到lambda
,我们有一个名为 \'m\' 的函数
尝试:
\n\nIn [28]: m = m(3)\nIn [29]: m\nOut[29]: 16\n
Run Code Online (Sandbox Code Playgroud)\n\n这里有两个\'m\'的名字,函数m
已经有名字了,重复了。
它的格式如下:
\n\nIn [27]: m = def m(n):\n ...: if n > 0:\n ...: return n**2 + 2*n + 1\n SyntaxError: invalid syntax\n
Run Code Online (Sandbox Code Playgroud)\n\n这不是一个明智的策略,因此会报告错误
\n\n我们必须删除其中一个,设置一个没有名称的函数。
\n\nm = lambda n:n**2 + 2*n + 1\n
Run Code Online (Sandbox Code Playgroud)\n\n它被称为“匿名函数”
\n\n综上所述,
\n\nlambda
在内联函数中,它使您能够像数学中一样在一条直线上编写函数lambda
是匿名的希望这可以帮助。
\n