Che cos'è una lambda e perché sarebbe utile? [chiuso]


56

Finora ho sentito parlare di:

  • Calcolo lambda
  • Programmazione lambda
  • Espressioni Lambda
  • Funzioni lambda

Che tutto sembra essere correlato alla programmazione funzionale ...

Apparentemente sarà integrato in C ++ 1x, quindi potrei capire meglio ora:

http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions

Qualcuno può definire brevemente quali sono le cose lambdas e dare un dove può essere utile?


2
Si noti che la terminologia storicamente deriva dal voler un buon modo di parlare della funzione rappresentata da un'espressione. La funzione rappresentata da x + 1 viene quindi scritta lambda x. x + 1.
Kasterma,

In modo lambda, una funzione mangia un'altra funzione e / o un valore di input, produce un'altra funzione. Questo continua fino a quando una funzione produce una soluzione. Inoltre, uova di alligatore .
SD

È tutto greco per me. Penso che andrò a fare un giroscopio, mi piace l'agnello, duh.

Risposte:


44
  • Calcolo lambda

Il calcolo lambda è un modello di calcolo inventato dalla chiesa Alonzo negli anni '30. La sintassi e la semantica della maggior parte dei linguaggi di programmazione funzionale sono direttamente o indirettamente ispirati dal calcolo lambda.

Il calcolo lambda nella sua forma più semplice ha due operazioni: Astrazione (creazione di una funzione (anonima)) e applicazione (applicazione di una funzione). L'astrazione viene eseguita utilizzando l'operatore λ, dando il nome al calcolo lambda.

  • Espressioni Lambda
  • Funzioni lambda

Le funzioni anonime sono spesso chiamate "lambdas", "funzioni lambda" o "espressioni lambda" perché, come ho detto sopra, λ era il simbolo per creare funzioni anonime nel calcolo lambda (e la parola lambdaviene utilizzata per creare funzioni anonime in molti lisp linguaggi basati sullo stesso motivo).

  • Programmazione lambda

Questo non è un termine comunemente usato, ma presumo significhi programmare usando funzioni anonime o programmare usando funzioni di ordine superiore.


Un po 'più di informazioni su lambda in C ++ 0x, la loro motivazione e il modo in cui si collegano ai puntatori di funzione (molto di questo è probabilmente una ripetizione di ciò che già sai, ma spero che aiuti a spiegare la motivazione di lambda e come differiscono dai puntatori di funzione):

I puntatori a funzione, che già esistevano in C, sono molto utili per esempio per passare una funzione di confronto a una funzione di ordinamento. Tuttavia ci sono limiti alla loro utilità:

Ad esempio, se si desidera ordinare un vettore di vettori in base iall'elemento th di ciascun vettore (dove iè un parametro di runtime), non è possibile risolverlo con un puntatore a funzione. Una funzione che confronta due vettori con il loro ielemento th, dovrebbe prendere tre argomenti ( ie i due vettori), ma la funzione di ordinamento avrebbe bisogno di una funzione che prende due argomenti. Ciò di cui avremmo bisogno è un modo per fornire in qualche modo l'argomento ialla funzione prima di passarlo alla funzione di ordinamento, ma non possiamo farlo con semplici funzioni C.

Per risolvere questo, C ++ ha introdotto il concetto di "oggetti funzione" o "functors". Un funzione è sostanzialmente un oggetto che ha un operator()metodo. Ora possiamo definire una classe CompareByIthElement, che prende l'argomento icome argomento del costruttore e quindi prende i due vettori da confrontare come argomenti al operator()metodo. Per ordinare un vettore di vettori in base iall'elemento th ora possiamo creare un CompareByIthElementoggetto con icome argomento e quindi passare quell'oggetto alla funzione di ordinamento.

Poiché gli oggetti funzione sono solo oggetti e non tecnicamente funzioni (anche se sono pensati per comportarsi come loro), non è possibile puntare un puntatore funzione a un oggetto funzione (è possibile ovviamente avere un puntatore a un oggetto funzione, ma esso avrebbe un tipo simile CompareByIthElement*e quindi non sarebbe un puntatore a funzione).

La maggior parte delle funzioni nella libreria standard C ++ che accettano funzioni come argomenti sono definite utilizzando modelli in modo che funzionino con puntatori e oggetti funzione.

Ora a lambdas:

Definire un'intera classe da confrontare con l' ielemento th è un po 'prolisso se la userai solo una volta per ordinare un vettore. Anche nel caso in cui sia necessario solo un puntatore a funzione, definire una funzione con nome non è ottimale se viene utilizzata una sola volta perché a) inquina lo spazio dei nomi eb) la funzione di solito sarà molto piccola e non c'è davvero un buon motivo per astrarre la logica nella sua stessa funzione (a parte questo non è possibile avere puntatori di funzione senza definire una funzione).

Quindi per risolvere questo lambdas sono stati introdotti. Le lambda sono oggetti funzione, non puntatori di funzione. Se si utilizza un [x1, x2](y1,y2){bla}codice letterale lambda simile viene generato che sostanzialmente fa quanto segue:

  1. Definire una classe che ha due variabili membro ( x1e x2) e una operator()con gli argomenti ( y1e y2) e il corpo bla.
  2. Creare un'istanza della classe, impostando le variabili membro x1e x2i valori delle variabili x1e x2attualmente nell'ambito.

Quindi i lambda si comportano come oggetti funzione, tranne per il fatto che non è possibile accedere alla classe generata per implementare un lambda in alcun modo diverso dall'uso del lambda. Di conseguenza, qualsiasi funzione che accetta i funzioni come argomenti (che significa sostanzialmente qualsiasi funzione non C nella libreria standard), accetterà lambdas, ma nessuna funzione che accetta solo i puntatori a funzione.


Le funzioni anonime possono essere utilizzate con i puntatori a funzione? In caso contrario, qual è la differenza?
jokoon il

1
@jokoon: No, le funzioni anonime non possono essere passate come parametri alle funzioni che accettano solo i puntatori a funzione. Tuttavia, la maggior parte delle funzioni che accettano funzioni come argomenti sono definite usando modelli in modo che possano prendere qualsiasi tipo di oggetto funzione come argomento, non solo puntatore a funzione. Vale a dire nella maggior parte dei luoghi in cui è possibile utilizzare i puntatori a funzione ( std::sortad esempio), sarà invece possibile utilizzare funzioni anonime. Tuttavia, quando si definisce una funzione che dovrebbe assumere una funzione anonima come argomento, è necessario utilizzare un modello o utilizzare std::functioncome tipo di argomento.
sepp2k,

quindi un puntatore a funzione non può contenere un lambda ...
jokoon il

1
+1 Ottima spiegazione - Neanche io ero stato in grado di scoprirlo.
Michael K,

2
Sono con Michael su questo. Questo è molto completo. +1da me.
sabato

18

Fondamentalmente, le funzioni lambda sono funzioni create "al volo". In C ++ 1x potrebbero essere utilizzati per migliorare il suo supporto per la programmazione funzionale:

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

Ciò comporterà approssimativamente un codice simile a questo:

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

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

Se hai bisogno some_functorsolo per questa chiamata a std::for_each(), allora quella funzione lambda ha diversi vantaggi:

  • ciò che viene fatto nel loop viene specificato proprio dove viene chiamata la funzione di loop
  • ti allevia dalla scrittura del codice della piastra della caldaia
  • non c'è alcun funzione in giro in qualche ambito dello spazio dei nomi che induca tutti a guardare il codice chiedendosi a cosa serve

7

Una funzione lambda è un altro nome per una funzione anonima, essenzialmente una funzione senza nome.

Di solito lo usi in lingue in cui dovrai usare la funzione una sola volta. Ad esempio invece di

def add(a, b)
  return a+b

e quindi passare quella funzione in un'altra funzione in questo modo

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

Con una lambda faresti semplicemente

reduce(lambda x, y: a+b, [5,3,2])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.