O que é um lambda e por que seria útil? [fechadas]

53

Até agora eu ouvi falar sobre:

  • Cálculo lambda
  • Programação lambda
  • Expressões lambda
  • Funções do Lambda

Tudo parece estar relacionado à programação funcional ...

Aparentemente, ele será integrado ao C ++ 1x, então eu posso entender melhor agora:

link

Alguém pode definir brevemente o que são coisas de lambdas e dar um lugar onde possa ser útil?

    
por jokoon 10.12.2010 / 11:34
fonte

3 respostas

43
  • 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:

  1. Defina uma classe que tenha duas variáveis de membro ( x1 e x2 ) e uma operator() com os argumentos ( y1 e y2 ) e o corpo bla .
  2. Crie uma instância da classe, definindo as variáveis de membro x1 e x2 para os valores das variáveis x1 e x2 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á.

    
por 10.12.2010 / 14:02
fonte
18

Basicamente, funções lambda são funções que você cria "on the fly". Em C ++ 1x eles poderiam ser usados para melhorar seu suporte para programação funcional:

std::for_each( begin, end, [](int i){std::cout << i << '\n';} );

Isso resultará aproximadamente em código semelhante a este:

struct some_functor {
  void operator()(int i) {std::cout << i << '\n';}
};

std::for_each( begin, end, some_functor() );

Se você precisar de some_functor apenas para essa chamada para std::for_each() , essa função lambda terá várias vantagens sobre ela:

  • o que é feito no loop é especificado exatamente onde a função de loop é chamada
  • alivia você de escrever um pouco do código da placa de caldeira
  • não há nenhum functor por aí em algum escopo de namespace que faça todo mundo olhar o código imaginando o que é necessário para
por 10.12.2010 / 12:16
fonte
7

Uma função lambda é outro nome para uma função anônima - essencialmente uma função sem nome.

Geralmente você usa isso em idiomas, onde você só precisará usar a função uma vez. Por exemplo, em vez de

def add(a, b)
  return a+b

e, em seguida, passando essa função para outra função, como assim

reduce(add, [5,3,2])

Com um lambda você simplesmente faria

reduce(lambda x, y: a+b, [5,3,2])
    
por 20.05.2013 / 06:22
fonte