Qual è la differenza tra una funzione e una lambda?


54

Sono un po 'confuso su "funzione" e "lambda". Ho visto alcuni esempi che mostrano che la parola chiave schema lambdafunziona in modo molto simile alla parola chiave JavaScript function, ma non so davvero come siano correlate.

Mi è stato detto che 'funzione' e 'metodo' possono essere usati in modo intercambiabile quando si parla di oggetti in .net. Mi chiedo se "lambda" e "funzione" abbiano lo stesso significato. Mi chiedo se 'lambda' abbia un significato esoterico, visto che la lettera greca lambda (λ) appare in così tanti avatar su questo sito. Per rendere le cose ancora più confuse, in .net, le parti funzionali di C # si riferiscono a espressioni di funzioni passate ad un'altra funzione come "espressioni lambda", quindi la parola sembra davvero essere ovunque.

Ho anche vagamente familiarità con il termine "calcolo lambda".

Qual è la differenza tra una funzione e una lambda?


3
Nitpick - sono chiamati "espressioni lambda", non "funzioni lambda", almeno per quanto riguarda la documentazione C # /. NET.
Oded,

@ TWith2Sugars: leggi il messaggio. La tua risposta è di bassa qualità in quanto praticamente è solo un link, quindi è stato convertito in un commento.
Oded,

17
I wonder if 'lambda' has some esoteric meaning, seeing that the Greek letter lambda (λ) appears in so many avatars on this site.Si spera che sia in riferimento al calcolo lambda, ma ho una strana sensazione che Half Life sia la colpa degli avatar lambda.
yannis,

3
Fiera abbastanza, ecco il link alla risposta StackOverflow: stackoverflow.com/questions/16501/what-is-a-lambda-function
TWith2Sugars

@ZaphodBeeblebrox: sospetto che tu abbia ragione sull'influenza di Half-Life. : /
FrustratedWithFormsDesigner

Risposte:


44

La parola "lambda" o "espressioni lambda" si riferisce più spesso a funzioni anonime. Quindi in quel senso un lambda è un tipo di funzione, ma non tutte le funzioni sono un lambda (cioè le funzioni con nome non sono di solito indicate come lambdas). A seconda della lingua, le funzioni anonime sono spesso implementate in modo diverso rispetto alle funzioni con nome (in particolare nelle lingue in cui le funzioni anonime sono chiusure e le funzioni con nome non lo sono), quindi può avere senso riferirsi ad esse con termini diversi.

La differenza tra la parola chiave lambda dello schema e la parola chiave della funzione Javascript è che quest'ultima può essere utilizzata per creare sia funzioni anonime che funzioni nominate mentre la prima crea solo funzioni anonime (e che useresti defineper creare funzioni denominate).

Il calcolo lambda è un linguaggio di programmazione minimo / modello matematico di calcolo, che utilizza le funzioni come unica "struttura di dati". Nel calcolo lamdba il simbolo lambda viene utilizzato per creare funzioni (anonime). È da qui che deriva l'uso del termine "lambda" in altre lingue.


1
Questo è estremamente approssimativo. Usi define(o letuno dei suoi parenti o una definizione interna) per creare nomi - tutto qui. Non c'è niente di speciale definerispetto alle funzioni.
Eli Barzilay,

2
@EliBarzilay Beh, define ha una forma speciale per le funzioni di definizione (ad esempio è possibile scrivere (define (f x) (foo))al posto di (define f (lambda (x) (foo)))), ma il mio punto è che non è possibile creare una funzione denominata utilizzando lambdasolo, per esempio, si può qualcosa non scrivere come (lambda f (x) (foo))definire una funzione denominata fche accetta un argomento come puoi con la functionparola chiave Javascript .
sepp2k,

1
defineha questo come uno zucchero sintattico, quindi non è così importante come il suo ruolo come uno strumento di associazione dei nomi per tutti i valori. Per quanto riguarda lambdanon creare un nome da solo: questa è una caratteristica importante, poiché separa il dare il nome dai moduli di funzione ... IMO JS sta facendo la cosa giusta nel consentire la separazione accettando anche un nome opzionale per quelle masse che sarebbero inorridite l'idea di una funzione senza nome. (E per fortuna le dimensioni di quelle masse sono in declino generale ...)
Eli Barzilay,

18

Una lambda è semplicemente una funzione anonima - una funzione senza nome.


4
Nota Abbastanza: i lambda possono contenere lo stato (come in chiusura) che si strappano dal contesto in cui sono dichiarati.
Martin York,

7
Così potrebbe una funzione con nome, se la lingua ti consente di dichiarare funzioni nidificate.
cHao,

4
Complimenti per essere entrato nella scheda "post di bassa qualità" con una risposta votata.
yannis,

@ZaphodBeeblebrox - Non intenzionalmente, posso assicurarti.
Oded,

Non proprio, lambdaun'espressione in Scheme è proprio come functionun'espressione senza nome - ma non c'è nulla che ti impedisca di dargli un nome in seguito. Per esempio var f = [function(x){return x;}][0]. Si potrebbe sostenere che il valore della funzione stessa non ha un nome, ma sarebbe vero per tutte le funzioni ...
Eli Barzilay,


8

In C # La funzione anonima è un termine generale che include sia espressioni lambda che metodi anonimi (i metodi anonimi sono istanze delegate senza alcuna dichiarazione di metodo effettiva).

Le espressioni lambda possono essere suddivise in espressioni lambda e istruzioni lambda

Espressione lambda:

(int x, string y) => x == y.Length 

L'istruzione lambda è simile all'espressione lambda, ad eccezione delle istruzioni racchiuse tra parentesi graffe:

(int x, string y) => {
         if (x == y.Length) {
             Console.WriteLine(y);
         }
}

Quando parliamo di espressioni lambda in JavaScript, questo in pratica significa semplicemente usare una funzione come argomento in una chiamata a un'altra funzione.

var calculate = function(x, y, operation){
    return operation(x, y);
}

// we're passing anonymous function as a third argument
calculate(10, 15, function(x, y) {
    return x + y;
}); // 25

+1 Molte persone hanno affermato che le lambda sono funzioni anonime, ma c'è di più. Il corpo (lato destro) di una lambda è spesso un'espressione piuttosto che un blocco di istruzioni. Il corpo di una funzione denominata che è un'espressione è generalmente consentito (o richiesto) nei linguaggi funzionali, ma non nei linguaggi imperativi.
Zantier,

4

TL; DR Come altri hanno sottolineato: la notazione lambda è solo un modo per definire le funzioni senza essere costretti a dare loro un nome.

Versione lunga

Vorrei approfondire un po 'questo argomento perché lo trovo molto interessante. Disclaimer: ho seguito il mio corso sul calcolo lambda molto tempo fa. Se qualcuno con una migliore conoscenza trova delle imprecisioni nella mia risposta, sentiti libero di aiutarmi a migliorarlo.

Cominciamo con le espressioni, per esempio 1 + 2e x + 2. Letterali come 1e 2sono chiamati costanti perché associati a valori fissi specifici.

Un identificatore come xviene chiamato variabile e per valutarlo è necessario prima associarlo a un valore. Quindi, fondamentalmente, non puoi valutare x + 1finché non sai cosa xsia.

La notazione lambda fornisce uno schema per l'associazione di valori di input specifici alle variabili. Un'espressione lambda può essere formato aggiungendo λx .davanti un'espressione esistente, ad es λx . x + 1. Variabile xè detto di essere liberi in x + 1e rilegato inλx . x + 1

In che modo aiuta a valutare le espressioni? Se dai un valore all'espressione lambda, in questo modo

(λx . x + 1) 2

quindi puoi valutare l'intera espressione sostituendo (vincolando) tutte le occorrenze della variabile xcon il valore 2:

(λx . x + 1) 2
      2 + 1
      3

Quindi, la notazione lambda fornisce un meccanismo generale per legare le cose alle variabili che appaiono in un blocco di espressioni / programmi. A seconda del contesto, ciò crea concetti visivamente diversi nei linguaggi di programmazione:

  • In un linguaggio puramente funzionale come Haskell, le espressioni lambda rappresentano funzioni in senso matematico: un valore di input viene iniettato nel corpo di lambda e viene prodotto un valore di output.
  • In molti linguaggi (ad es. JavaScript, Python, Scheme) la valutazione del corpo di un'espressione lambda può avere effetti collaterali. In questo caso si può usare il termine procedura per contrassegnare la differenza rispetto alle funzioni pure.

A parte le differenze, la notazione lambda riguarda la definizione di parametri formali e il loro legame con parametri reali.

Il prossimo passo è dare un nome a una funzione / procedura. In diverse lingue, le funzioni sono valori come le altre, quindi puoi assegnare un nome a una funzione come segue:

(define f (lambda (x) (+ x 1)))      ;; Scheme

f = \x -> x + 1                      -- Haskell

val f: (Int => Int) = x => x + 1     // Scala

var f = function(x) { return x + 1 } // JavaScript

f = lambda x: x + 1                  # Python

Come ha sottolineato Eli Barzilay, queste definizioni associano il nome fa un valore, che sembra essere una funzione. Quindi, sotto questo aspetto, funzioni, numeri, stringhe, caratteri sono tutti valori che possono essere associati ai nomi allo stesso modo:

(define n 42)   ;; Scheme

n = 42          -- Haskell

val n: Int = 42 // Scala

var n = 42      // JavaScript

n = 42          # Python

In queste lingue puoi anche associare una funzione a un nome usando la notazione più familiare (ma equivalente):

(define (f x) (+ x 1))         ;; Scheme

f x = x + 1                    -- Haskell

def f(x: Int): Int = x + 1     // Scala

function f(x) { return x + 1 } // JavaScript

def f(x): return x + 1         # Python

Alcune lingue, ad esempio C, supportano solo quest'ultima notazione per la definizione di funzioni (denominate).

chiusure

Alcune osservazioni finali sulle chiusure . Considera l'espressione x + y. Questo contiene due variabili libere. Se ti leghi xusando la notazione lambda otterrai:

\x -> x + y

Questa non è (ancora) una funzione perché contiene ancora una variabile libera y. Puoi anche farne una funzione vincolando y:

\x -> \y -> x + y

o

\x y -> x + y

che è esattamente la stessa della +funzione.

Ma puoi legare, diciamo, yin un altro modo (*):

incrementBy y = \x -> x + y

Il risultato dell'applicazione della funzione incrementBy a un numero è una chiusura, ovvero una funzione / procedura il cui corpo contiene una variabile libera (ad esempio y) che è stata vincolata a un valore dall'ambiente in cui è stata definita la chiusura.

Così incrementBy 5è la funzione (chiusura) che incrementa i numeri di 5.

NOTA (*)

Sto tradendo un po 'qui:

incrementBy y = \x -> x + y

è equivalente a

incrementBy = \y -> \x -> x + y

quindi il meccanismo di legame è lo stesso. Intuitivamente, penso a una chiusura come a rappresentare un pezzo di un'espressione lambda più complessa. Quando viene creata questa rappresentazione, alcuni dei vincoli dell'espressione madre sono già stati impostati e la chiusura li utilizza in seguito quando viene valutata / invocata.


Sono solo un mendicante, ma penso che questo possa essere un po 'confuso se stai cercando di capire il calcolo λ in senso matematico, dal momento che quelle che chiami costanti sono chiamate variabili e indicate dai simboli a, b, c ... Cosa hai le variabili di chiamata sarebbero una variabile indeterminata x . D'altra parte 1 è λ f x . f x , 2 è λ f x . f ( f x ) e così via.
jinawee,

@jinawee: ammetto di non aver cercato la definizione esatta. Ricordo di aver usato i termini variabili e costanti in logica. Lì, una costante è un simbolo che è mappato su un dominio, mentre una variabile è un simbolo su cui puoi quantificare. Ma, ancora una volta, (1) è passato molto tempo da quando ho seguito un corso di logica e (2) lambda-calcolo non ha bisogno di seguire 1-1 i concetti di logica matematica. Se mi indichi un riferimento, posso provare a correggere la mia terminologia.
Giorgio,

0

"Lambda" nella programmazione di solito significa "funzione lambda" (o anche "espressione lambda", "termine lambda"). Quando la funzione è un blocco di codice denominato definito prima del suo utilizzo, "funzione lambda" è un blocco di codice (o un'espressione) definito al posto dell'uso che può essere utilizzato come cittadino di prima classe in un linguaggio di programmazione.

In JavaScript ES6 (2015) c'è una breve sintassi per definire lambdas chiamato "Funzioni freccia" . In C # tale sintassi è stata introdotta in .NET 3.0 (intorno al 2006) .

In matematica una nozione di "funzione" ha diversi significati in cui uno dei significati riguarda la notazione di una funzione (cioè come scriverla), quindi "funzione lambda" (in calcolo) è un tipo speciale di notazione di funzione. Per ulteriori discussioni, controlla le funzioni lambda nei linguaggi di programmazione .

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.