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

53

Finora ho sentito parlare di:

  • Lambda calcolo
  • Programmazione Lambda
  • Espressioni Lambda
  • Funzioni lambda

Che tutto sembra essere correlato alla programmazione funzionale ...

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

link

Qualcuno può definire in breve cosa sono le cose lambda e dare un punto in cui può essere utile?

    
posta jokoon 10.12.2010 - 11:34
fonte

3 risposte

43
  • Lambda calcolo

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

Il calcolo lambda nella sua forma base ha due operazioni: Astrazione (creando una funzione (anonima)) e applicazione (applica una funzione). L'astrazione viene eseguita usando l'operatore λ, dando il nome al calcolo lambda.

  • Espressioni Lambda
  • Funzioni lambda

Le funzioni anonime sono spesso chiamate "lambda", "funzioni lambda" o "espressioni lambda" perché, come ho detto sopra, λ era il simbolo per creare funzioni anonime nel calcolo lambda (e la parola lambda è usata per creare funzioni anonime in molte lingue basate su Lisp per lo stesso motivo).

  • Programmazione Lambda

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

Un po 'più di informazioni su lambdas in C ++ 0x, la loro motivazione e il loro rapporto con i puntatori di funzione (molto probabilmente è una ripetizione di ciò che già sai, ma spero che aiuti a spiegare la motivazione di lambdas e in che modo differiscono dai puntatori di funzione):

I puntatori di funzione, che già esistevano in C, sono piuttosto utili ad es. passare una funzione di confronto a una funzione di ordinamento. Tuttavia ci sono dei limiti alla loro utilità:

Ad esempio, se si desidera ordinare un vettore di vettori mediante l'elemento i 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 elemento i th, dovrebbe prendere tre argomenti ( i e i due vettori), ma la funzione di ordinamento avrebbe bisogno di una funzione che prendesse due argomenti. Quello 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 problema, C ++ ha introdotto il concetto di "oggetti funzionali" o "funtori". Un functor è fondamentalmente un oggetto che ha un metodo operator() . Ora possiamo definire una classe CompareByIthElement , che accetta l'argomento i come argomento costruttore e quindi accetta i due vettori da confrontare come argomenti al metodo operator() . Per ordinare un vettore di vettori dall'elemento i th possiamo ora creare un oggetto CompareByIthElement con i come argomento e quindi passare quell'oggetto alla funzione di ordinamento.

Poiché gli oggetti funzione sono solo oggetti e non funzioni tecnicamente (anche se hanno lo scopo di comportarsi come loro), non è possibile creare una funzione puntatore a un oggetto funzione (si può ovviamente avere un puntatore a un oggetto funzione , ma avrebbe un tipo come CompareByIthElement* e quindi non dovrebbe essere un puntatore a funzione).

La maggior parte delle funzioni nella libreria standard C ++ che assumono funzioni come argomenti vengono definite utilizzando i modelli in modo che possano funzionare con i puntatori di funzione e gli oggetti funzione.

Now to lambdas:

Definire un'intera classe da confrontare con l'elemento i th è un po 'prolisso se lo utilizzerai solo una volta per ordinare un vettore. Anche nel caso in cui hai solo bisogno di un puntatore a funzione, la definizione di una funzione con nome è sub-ottimale se viene utilizzata una sola volta a causa del fatto che inquina lo spazio dei nomi eb) la funzione di solito sarà molto piccola e non c'è una buona ragione per astrarre la logica in una sua funzione (oltre a quella che non puoi avere puntatori di funzione senza definire una funzione).

Quindi per risolvere questo problema sono stati introdotti i lambda. Lambdas sono oggetti funzione, non indicatori di funzione. Se si utilizza un letterale lambda come [x1, x2](y1,y2){bla} viene generato il codice che fondamentalmente fa quanto segue:

  1. Definisci una classe che ha due variabili membro ( x1 e x2 ) e una operator() con gli argomenti ( y1 e y2 ) e il corpo bla .
  2. Crea un'istanza della classe, impostando le variabili membro x1 e x2 sui valori delle variabili x1 e x2 attualmente in ambito.

Quindi lambda si comporta come gli oggetti funzione, tranne per il fatto che non è possibile accedere alla classe generata per implementare un lambda in un modo diverso dall'uso del lambda. Di conseguenza, qualsiasi funzione che accetta i funtori come argomenti (che fondamentalmente significa qualsiasi funzione non-C nella libreria standard), accetterà lambda, ma non funzionerà alcuna funzione che accetta solo i puntatori di funzione.

    
risposta data 10.12.2010 - 14:02
fonte
18

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

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

Questo genererà 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 di some_functor solo per questa chiamata a std::for_each() , allora quella funzione lambda ha molti vantaggi su di essa:

  • ciò che viene fatto nel ciclo viene specificato esattamente dove viene chiamata la funzione di loop
  • ti libera di scrivere parte del codice della piastra della caldaia
  • non c'è un functor in giro in un ambito namespace che faccia vedere a tutti il codice chiedendosi a cosa serve
risposta data 10.12.2010 - 12:16
fonte
7

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

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

def add(a, b)
  return a+b

e quindi passando quella funzione in un'altra funzione come

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

Con un lambda devi semplicemente fare

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

Leggi altre domande sui tag