O que é um lambda (function)?

Para uma pessoa sem histórico de comp-sci, o que é um lambda no mundo da ciência da computação?

O Lambda vem do Lambda Calculus e se refere a funções anônimas na programação.

Por que isso é legal? Ele permite que você escreva funções de eliminação rápida sem nomeá-las. Ele também fornece uma boa maneira de escrever encerramentos. Com esse poder você pode fazer coisas assim.

Python

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

Como você pode ver no snippet do Python, o sumdor da function aceita um argumento x e retorna uma function anônima, ou lambda, que recebe outro argumento y. Essa function anônima permite criar funções a partir de funções. Este é um exemplo simples, mas deve transmitir o poder que os lambdas e os fechamentos têm.

Exemplos em outros idiomas

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 

Esquema

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

C # 3.5 ou superior

 Func> adder = (int x) => (int y) => x + y; // `int` declarations optional Func 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 addWithClosure = (x) => x + yEnclosed; Debug.Assert(addWithClosure(2) == 3); 

Rápido

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

PHP

 $a = 1; $b = 2; $lambda = function () use (&$a, &$b) { echo $a + $b; }; echo $lambda(); 

Haskell

 (\xy -> x + y) 

Java ver este post

 // The following is an example of Predicate : // a functional interface that takes an argument // and returns a boolean primitive type. Predicate 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 

Um lambda é um tipo de function, definido em linha. Juntamente com um lambda, você normalmente também tem algum tipo de variável que pode conter uma referência a uma function, lambda ou outra.

Por exemplo, aqui está um trecho de código C # que não usa um lambda:

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

Isso chama a Calculadora, passando não apenas dois números, mas qual método chamar dentro da Calculadora para obter os resultados do cálculo.

No C # 2.0, obtivemos methods anônimos, o que encurta o código acima para:

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

E então, no C # 3.0, obtivemos lambdas, o que torna o código ainda mais curto:

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

Refere-se ao cálculo lambda , que é um sistema formal que apenas possui expressões lambda, que representam uma function que assume uma function para seu único argumento e retorna uma function. Todas as funções no cálculo lambda são desse tipo, ou seja, λ : λ → λ .

Lisp usou o conceito de lambda para nomear seus literais de function anônimos. Este lambda representa uma function que recebe dois argumentos, x e y, e retorna seu produto:

 (lambda (xy) (* xy)) 

Pode ser aplicado em linha como este (avalia a 50 ):

 ((lambda (xy) (* xy)) 5 10) 

O nome “lambda” é apenas um artefato histórico. Tudo o que estamos falando é uma expressão cujo valor é uma function.

Um exemplo simples (usando o Scala para a próxima linha) é:

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

onde o argumento para o método foreach é uma expressão para uma function anônima. A linha acima é mais ou menos o mesmo que escrever algo assim (código não muito real, mas você terá a idéia):

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

exceto que você não precisa se preocupar com:

  1. Declarando a function em outro lugar (e tendo que procurá-la quando você revisitar o código mais tarde).
  2. Nomeando algo que você está usando apenas uma vez.

Uma vez que você está acostumado a funcionar com valores, ter que passar sem eles parece tão bobo quanto ser necessário para nomear todas as expressões, como:

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

em vez de apenas escrever a expressão onde você precisa:

 println(2 * a + b) 

A notação exata varia de idioma para idioma; O grego nem sempre é obrigatório! 😉

O cálculo lambda é uma teoria matemática consistente de substituição. Na matemática escolar, vemos por exemplo x+y=5 emparelhado com x−y=1 . Juntamente com maneiras de manipular equações individuais, também é possível juntar as informações dessas duas partes, desde que as substituições de equações cruzadas sejam feitas logicamente. O cálculo lambda codifica a maneira correta de fazer essas substituições.

Dado que y = x−1 é um rearranjo válido da segunda equação, isto: λ y = x−1 significa uma function substituindo os símbolos x−1 pelo símbolo y . Agora imagine aplicar λ y a cada termo na primeira equação. Se um termo é y , execute a substituição; caso contrário, não faça nada. Se você fizer isso no papel, verá como aplicar isso λ y tornará a primeira equação solucionável.

Essa é uma resposta sem qualquer ciência da computação ou programação.

O exemplo de programação mais simples que eu posso imaginar vem de http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works :

aqui está como a function quadrada pode ser definida em uma linguagem de programação imperativa (C):

 int square(int x) { return x * x; } 

A variável x é um parâmetro formal que é substituído pelo valor real a ser quadrado quando a function é chamada. Em uma linguagem funcional (Scheme) a mesma function seria definida:

 (define square (lambda (x) (* xx))) 

Isso é diferente em muitos aspectos, mas ainda usa o parâmetro formal x da mesma maneira.


Adicionado: http://imgur.com/a/XBHub

lambda

Um pouco supersimplificado: uma function lambda é aquela que pode ser passada para outras funções e sua lógica é acessada.

Em C # lambda, a syntax é frequentemente compilada para methods simples da mesma forma que os delegates anônimos, mas também pode ser dividida e sua lógica lida.

Por exemplo (em C # 3):

 LinqToSqlContext.Where( row => row.FieldName > 15 ); 

LinqToSql pode ler essa function (x> 15) e convertê-lo para o SQL real para executar usando trees de expressão.

A declaração acima se torna:

 select ... from [tablename] where [FieldName] > 15 --this line was 'read' from the lambda function 

Isso é diferente dos methods normais ou delegates anônimos (que são apenas mágicos de compilador) porque não podem ser lidos .

Nem todos os methods em C # que usam syntax lambda podem ser compilados para trees de expressão (isto é, funções lambda reais). Por exemplo:

 LinqToSqlContext.Where( row => SomeComplexCheck( row.FieldName ) ); 

Agora a tree de expressões não pode ser lida – SomeComplexCheck não pode ser dividido. A instrução SQL será executada sem o where e todas as linhas nos dados serão colocadas no SomeComplexCheck .

As funções do Lambda não devem ser confundidas com methods anônimos. Por exemplo:

 LinqToSqlContext.Where( delegate ( DataRow row ) { return row.FieldName > 15; } ); 

Isso também tem uma function ‘inline’, mas desta vez é apenas mágica do compilador – o compilador C # irá dividir isso em um novo método de instância com um nome gerado automaticamente.

Métodos anônimos não podem ser lidos e, portanto, a lógica não pode ser traduzida como pode para funções lambda.

Eu gosto da explicação de Lambdas neste artigo: A evolução do LINQ e seu impacto no design do C # . Isso fez muito sentido para mim, pois mostra um mundo real para Lambdas e o constrói como um exemplo prático.

Sua explicação rápida: Lambdas são uma maneira de tratar o código (funções) como dados.

Um exemplo de um lambda em Ruby é o seguinte:

 hello = lambda do puts('Hello') puts('I am inside a proc') end hello.call 

Gerará a seguinte saída:

 Hello I am inside a proc 

@ Brian eu uso lambdas o tempo todo em C #, em operadores LINQ e não-LINQ. Exemplo:

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

Antes do C #, eu usava funções anônimas em JavaScript para retornos de chamada para funções AJAX, antes mesmo que o termo Ajax fosse cunhado:

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

O interessante da syntax lambda do C #, no entanto, é que o tipo deles não pode ser inferido (isto é, você não pode digitar var foo = (x, y) => x * y), mas dependendo de qual tipo eles são Para eles, eles serão compilados como delegates ou trees de syntax abstrata representando a expressão (que é como os mapeadores de object LINQ fazem sua mágica “integrada à linguagem”).

Lambdas no LISP também pode ser passado para um operador de cotação e, em seguida, percorrido como uma lista de listas. Algumas macros poderosas são feitas dessa maneira.

A pergunta é formalmente respondida muito, então eu não vou tentar adicionar mais sobre isso.

Em palavras muito simples e informais para alguém que sabe muito pouco ou nada sobre matemática ou programação, eu o explicaria como uma pequena “máquina” ou “checkbox” que toma alguma input, faz algum trabalho e produz alguma saída, não tem nome específico , mas nós sabemos onde é e apenas por este conhecimento, nós o usamos.

Praticamente falando, para uma pessoa que sabe o que é uma function, eu diria a eles que é uma function que não tem nome, geralmente colocada em um ponto na memory que pode ser usado apenas referenciando a essa memory (geralmente através do uso de uma variável – se eles tiverem ouvido falar sobre o conceito dos pointers de function, eu os usaria como um conceito similar) – esta resposta cobre os princípios básicos (sem mencionar os fechamentos etc), mas pode-se entender facilmente.

Você pode pensar nisso como uma function anônima – eis mais algumas informações: Wikipedia – Função Anônima

Eu tenho dificuldade em envolver minha cabeça em torno de expressões lambda porque eu trabalho no Visual FoxPro, que tem substituição de macro e as funções de ExecScript {} e Evaluate (), que parecem servir a mesma finalidade.

 ? Calculator(10, 23, "a + b") ? Calculator(10, 23, "a - b"); FUNCTION Calculator(a, b, op) RETURN Evaluate(op) 

Um benefício definitivo para o uso de lambdas formais é (eu suponho) verificação em tempo de compilation: A Fox não saberá se você digitar a string de texto acima até tentar executá-la.

Isso também é útil para o código orientado por dados: você pode armazenar rotinas inteiras em campos de memorando no database e, em seguida, apenas avaliá-las em tempo de execução. Isso permite ajustar parte do aplicativo sem realmente ter access à fonte. (Mas esse é outro assunto completamente diferente)

Só porque eu não posso ver um exemplo de C ++ 11 aqui, eu vou em frente e posto este bom exemplo daqui . Depois de pesquisar, é o exemplo específico de idioma mais claro que pude encontrar.

Olá, Lambdas, versão 1

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

Olá, Lambdas, versão 2:

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

Para uma pessoa sem histórico de comp-sci, o que é um lambda no mundo da ciência da computação?

Ilustrarei intuitivamente passo a passo em códigos python simples e legíveis.

Em suma, um lambda é apenas uma function anônima e inline.

Vamos começar a partir da tarefa de entender lambdas como um calouro com histórico de aritmética básica.

O plano de designação é ‘o nome = valor’, consulte:

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

‘x’, ‘y’ são nomes e 1, ‘valor’ são valores. Tente uma function em matemática

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

Relatórios de erros
você não pode escrever uma matemática diretamente como código, ‘n’ deve ser definido ou ser atribuído a um valor.

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

Funciona agora, e se você insistir em combinar as duas linhas seperarte em uma. Lá vem lambda

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

Nenhum erro relatado.

Este é um relance no lambda , ele permite que você escreva uma function em uma única linha como você faz em matemática diretamente no computador.

Nós veremos mais tarde.

Vamos continuar cavando mais fundo em ‘atribuição’.

Como ilustrado acima, o símbolo de igual = funciona para dados simples (1 e ‘valor’) tipo e expressão simples (n ** 2 + 2 * n + 1).

Tente isto:

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

Ele funciona para instruções simples, há 11 tipos deles em Python 7. Instruções Simples – Documentação do Python 3.6.3

Como sobre declaração composta,

 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 

Lá vem def habilitá-lo trabalhando

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

Tada, analise, ‘m’ é nome, ‘n ** 2 + 2 * n + 1’ é o valor. : é uma variante de ‘=’.
Encontrá-lo, se apenas para entender, tudo começa a partir de atribuição e tudo é atribuição.

Agora volte para lambda , temos uma function chamada ‘m’

Experimentar:

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

Existem dois nomes de ‘m’ aqui, a function m já tem um nome duplicado.

Está formatando como:

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

Não é uma estratégia inteligente, então relatórios de erros

Temos que deletar um deles, definir uma function sem nome.

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

É chamado de ‘function anônima’

Em conclusão,

  1. lambda em uma function inline que permite escrever uma function em uma linha reta como na matemática
  2. lambda é anônimo

Espero que isto ajude.

É uma function que não tem nome. Por exemplo, em c # você pode usar

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

para retornar os números que são maiores que 5.

 number => number > 5 

é a parte lambda aqui. Representa uma function que recebe um parâmetro (número) e retorna um valor booleano (número> 5). GetMatchingItems método usa esse lambda em todos os itens na coleção e retorna os itens correspondentes.

Eu também entendi. Eu tentei em JS com este:

 var addAndMult = function(x) { return (function(y) { return (function(z) { return (x+y)*z; }); }); }; 

Ele adiciona 2 a 4, em seguida, mults o resultado por 6. No entanto, acho que às vezes é difícil ler 🙁

Também fiz uma function interessante para cada uma delas:

 var forEach = function(arr) { return (function(x) { for (var i=0; arr[i]; i++) { x(arr[i]); } }); } 

forEach ([1,2,3,4,5]) (console.log);

Este método irá iterar uma matriz e executa uma ação – no caso de impressão para o console. Agora eu também entendo porque os labmdas são poderosos.

No Javascript, por exemplo, as funções são tratadas como o mesmo tipo misto de todo o resto ( int , string , float , bool ). Assim, você pode criar funções rapidamente, atribuí-las a coisas e chamá-las de volta mais tarde. É útil, mas não é algo que você queira usar em demasia ou você confundirá todos que tiverem que manter seu código depois de você …

Este é um código com o qual eu estava jogando para ver o quão profundo é esse buraco de coelho:

 var x = new Object; x.thingy = new Array(); x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; } x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; } x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; } for(var i=0 ;i<3; i++) x.thingy[i]()()(); 

No contexto de CS, uma function lambda é um conceito matemático abstrato que aborda um problema de avaliação simbólica de expressões matemáticas. Nesse contexto, uma function lambda é a mesma que um termo lambda .

Mas nas linguagens de programação é algo diferente. É um pedaço de código que é declarado “in loco” e que pode ser passado como um “cidadão de primeira class”. Esse conceito pareceu ser útil, de modo que chegou a quase todas as linguagens de programação modernas e populares (veja lambda functions everwhere post).

Na programação de computadores, lambda é um pedaço de código (declaração, expressão ou um grupo deles) que pega alguns argumentos de uma fonte externa. Nem sempre deve ser uma function anônima – temos muitas maneiras de implementá-las.

Temos uma separação clara entre expressões, declarações e funções, que os matemáticos não têm.

A palavra “function” na programação também é diferente – temos “function é uma série de passos para fazer” (do latim “executar”). Em matemática, é algo sobre correlação entre variables.

As linguagens funcionais estão tentando ser tão semelhantes às fórmulas matemáticas quanto possível, e suas palavras significam quase o mesmo. Mas em outras linguagens de programação, temos diferente.

A pergunta foi respondida completamente, não quero entrar em detalhes. Eu quero compartilhar o uso quando se escreve computação numérica em rust.

Existe um exemplo de um lambda (function anônima)

 let f = |x: f32| -> f32 { x * x - 2.0 }; let df = |x: f32| -> f32 { 2.0 * x }; 

Quando escrevia um módulo do método de Newton – Raphson, ele era usado como derivada de primeira e segunda ordem. (Se você quiser saber o que é o método de Newton – Raphson, por favor visite “ https://en.wikipedia.org/wiki/Newton%27s_method ”.

A saída como o seguinte

 println!("f={:.6} df={:.6}", f(10.0), df(10.0)) f=98.000000 df=20.000000