- Cálculo lambda
O cálculo lambda é um modelo de computação inventado por Alonzo Church nos anos 30. A sintaxe e a semântica da maioria das linguagens de programação funcionais são direta ou indiretamente inspiradas pelo cálculo lambda.
O cálculo lambda em sua forma mais básica tem duas operações: Abstração (criando uma função (anônima)) e aplicação (aplica uma função). A abstração é realizada usando o operador λ, dando o nome ao seu cálculo lambda.
- Expressões lambda
- Funções do Lambda
Funções anônimas são freqüentemente chamadas de "lambdas", "funções lambda" ou "expressões lambda" porque, como eu disse acima, λ era o símbolo para criar funções anônimas no cálculo lambda (e a palavra lambda
é usada para crie funções anônimas em muitas linguagens baseadas em lisp pelo mesmo motivo).
- Programação lambda
Este não é um termo comumente usado, mas eu suponho que significa programação usando funções anônimas ou programação usando funções de ordem superior.
Um pouco mais de informação sobre lambdas em C ++ 0x, sua motivação e como eles se relacionam com ponteiros de função (muito disso é provavelmente uma repetição do que você já sabe, mas espero que ajude a explicar a motivação de lambdas e como eles diferem dos ponteiros de função):
Os ponteiros de função, que já existiam em C, são bastante úteis para, e. passar uma função de comparação para uma função de classificação. No entanto, existem limites para a sua utilidade:
Por exemplo, se você quiser classificar um vetor de vetores pelo elemento i
th de cada vetor (onde i
é um parâmetro de tempo de execução), não será possível resolver isso com um ponteiro de função. Uma função que compara dois vetores pelo seu elemento i
th, precisaria ter três argumentos ( i
e os dois vetores), mas a função de classificação precisaria de uma função levando dois argumentos. O que precisamos é uma forma de fornecer o argumento i
para a função antes de passá-la para a função de ordenação, mas não podemos fazer isso com funções C simples.
Para resolver isso, o C ++ introduziu o conceito de "objetos de função" ou "functores". Um functor é basicamente um objeto que possui um método operator()
. Agora podemos definir uma classe CompareByIthElement
, que aceita o argumento i
como um argumento de construtor e, em seguida, usa os dois vetores para serem comparados como argumentos ao método operator()
. Para classificar um vetor de vetores pelo elemento i
th, podemos agora criar um objeto CompareByIthElement
com i
como argumento e então passar esse objeto para a função de classificação.
Como os objetos de função são apenas objetos e não são funções tecnicamente (mesmo que eles se comportem como eles), você não pode fazer um apontador de função apontar para um objeto de função (você pode ter um ponteiro para um objeto de função , mas ele teria um tipo como CompareByIthElement*
e, portanto, não seria um ponteiro de função).
A maioria das funções na biblioteca padrão C ++, que tomam funções como argumentos, é definida usando modelos para que trabalhem com ponteiros de função e com objetos de função.
Agora para lambdas:
Definir uma classe inteira para comparar pelo elemento i
th é um pouco detalhado se você for usá-lo apenas uma vez para classificar um vetor. Mesmo no caso em que você só precisa de um ponteiro de função, a definição de uma função nomeada é sub-ótima se for usada apenas uma vez porque a) polui o namespace e b) a função normalmente será muito pequena e não há realmente uma boa razão para abstrair a lógica em sua própria função (além de que você não pode ter ponteiros de função sem definir uma função).
Então, para corrigir este lambdas foram introduzidos. Lambdas são objetos de função, não ponteiros de função. Se você usar um literal lambda como [x1, x2](y1,y2){bla}
code será gerado, o que basicamente faz o seguinte:
- Defina uma classe que tenha duas variáveis de membro (
x1
ex2
) e umaoperator()
com os argumentos (y1
ey2
) e o corpobla
. - Crie uma instância da classe, definindo as variáveis de membro
x1
ex2
para os valores das variáveisx1
ex2
atualmente no escopo.
Assim, lambdas se comportam como objetos de função, exceto que você não pode acessar a classe que é gerada para implementar um lambda de qualquer outra forma que não seja o uso do lambda. Consequentemente, qualquer função que aceite functores como argumentos (basicamente significando qualquer função não-C na biblioteca padrão), aceitará lambdas, mas qualquer função que aceite apenas ponteiros de função não irá.