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 lambda
viene utilizzata per creare funzioni anonime in molti lisp linguaggi basati sullo stesso motivo).
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 i
all'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 i
elemento th, dovrebbe prendere tre argomenti ( i
e 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 i
alla 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 i
come argomento del costruttore e quindi prende i due vettori da confrontare come argomenti al operator()
metodo. Per ordinare un vettore di vettori in base i
all'elemento th ora possiamo creare un CompareByIthElement
oggetto con i
come 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' i
elemento 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:
- Definire una classe che ha due variabili membro (
x1
e x2
) e una operator()
con gli argomenti ( y1
e y2
) e il corpo bla
.
- Creare un'istanza della classe, impostando le variabili membro
x1
e x2
i valori delle variabili x1
e x2
attualmente 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.