Was ist der Unterschied zwischen einer Funktion und einem Lambda?


54

Ich bin ein bisschen verwirrt über "Funktion" und "Lambda". Ich habe einige Beispiele gesehen, die zeigen, dass das Schema-Schlüsselwort lambdadem JavaScript-Schlüsselwort sehr ähnlich ist function, aber ich weiß wirklich nicht, wie sie zusammenhängen.

Mir wurde gesagt, dass 'function' und 'method' synonym verwendet werden können, wenn über Objekte in .net gesprochen wird. Ich frage mich, ob 'Lambda' und 'Funktion' dasselbe bedeuten. Ich frage mich, ob 'Lambda' eine esoterische Bedeutung hat, da der griechische Buchstabe Lambda (λ) in so vielen Avataren auf dieser Seite vorkommt. Um die Dinge in .net noch verwirrender zu machen, verweisen die funktionalen Teile von C # auf Funktionsausdrücke, die als 'Lambda-Ausdrücke' an eine andere Funktion übergeben wurden, sodass das Wort tatsächlich überall vorkommt.

Ich bin auch vage mit dem Begriff "Lambda-Kalkül" vertraut.

Was ist der Unterschied zwischen einer Funktion und einem Lambda?


3
Nitpick - Sie heißen "Lambda-Ausdrücke" und nicht "Lambda-Funktionen", zumindest was die C # / .NET-Dokumentation betrifft.
Oded

@ TWith2Sugars - Nachricht lesen. Ihre Antwort ist von geringer Qualität, da es sich eigentlich nur um einen Link handelt, und wurde in einen Kommentar umgewandelt.
Oded

17
I wonder if 'lambda' has some esoteric meaning, seeing that the Greek letter lambda (λ) appears in so many avatars on this site.Man würde hoffen, dass es in Bezug auf Lambda-Kalkül sein würde, aber ich habe ein seltsames Gefühl, dass Half Life für Lambda-Avatare verantwortlich ist.
Yannis

3
Fair genug, hier ist der Link zur Stackoverflow-Antwort: stackoverflow.com/questions/16501/what-is-a-lambda-function
TWith2Sugars

@ ZaphodBeeblebrox: Ich vermute, Sie haben Recht mit dem Half-Life-Einfluss. : /
FrustratedWithFormsDesigner

Antworten:


44

Das Wort "Lambda" oder "Lambda-Ausdrücke" bezieht sich meist auf anonyme Funktionen. In diesem Sinne ist ein Lambda eine Art von Funktion, aber nicht jede Funktion ist ein Lambda (dh benannte Funktionen werden normalerweise nicht als Lambdas bezeichnet). Abhängig von der Sprache werden anonyme Funktionen häufig anders implementiert als benannte Funktionen (insbesondere in Sprachen, in denen anonyme Funktionen abgeschlossen sind und benannte Funktionen nicht). Daher kann es sinnvoll sein, sie mit unterschiedlichen Begriffen zu bezeichnen.

Der Unterschied zwischen dem Lambda-Schlüsselwort des Schemas und dem Funktionsschlüsselwort von Javascript besteht darin, dass das letztere verwendet werden kann, um sowohl anonyme Funktionen als auch benannte Funktionen zu erstellen, während das erstere nur anonyme Funktionen erstellt (und Sie definezum Erstellen benannter Funktionen verwenden würden).

Der Lambda-Kalkül ist eine minimale Programmiersprache / ein mathematisches Rechenmodell, das Funktionen als einzige "Datenstruktur" verwendet. Im Lamdba-Kalkül werden mit dem Lambda-Symbol (anonyme) Funktionen erzeugt. Daher kommt die Verwendung des Begriffs "Lambda" in anderen Sprachen.


1
Das ist extrem rau. Sie verwenden define(oder leteinen seiner Verwandten oder eine interne Definition), um Namen zu erstellen - das ist alles. In defineBezug auf Funktionen gibt es nichts Besonderes .
Eli Barzilay

2
@EliBarzilay Nun, define es gibt eine spezielle Form zum Definieren von Funktionen (dh Sie können schreiben (define (f x) (foo))statt (define f (lambda (x) (foo)))), aber mein Punkt war, dass Sie eine benannte Funktion nicht lambdaalleine erstellen können, dh Sie können nicht so etwas wie (lambda f (x) (foo))das Definieren einer benannten Funktion schreiben fDas erfordert ein Argument, wie Sie es mit dem functionSchlüsselwort von Javascript können .
SEPP2K

1
definehat das als syntaktischen Zucker, also ist es nicht so wichtig wie seine Rolle als Werkzeug zur Namensbindung für alle Werte. Es lambdaist ein wichtiges Merkmal, keinen Namen für sich selbst zu erstellen, da es das Geben von Namen von Funktionsformen trennt ... IMO JS tut das Richtige, um die Trennung zuzulassen und gleichzeitig einen optionalen Namen für die Massen zu akzeptieren, die entsetzt wären die Idee einer Funktion ohne Namen. (Und zum Glück ist die Größe dieser Massen in einem allgemeinen Rückgang ...)
Eli Barzilay

18

Ein Lambda ist einfach eine anonyme Funktion - eine Funktion ohne Namen.


4
Hinweis: Lambdas können (wie in Closure) den Status enthalten, den sie aus dem Kontext entfernen, in dem sie deklariert wurden.
Martin York

7
So könnte eine benannte Funktion sein, wenn Sie in der Sprache verschachtelte Funktionen deklarieren können.
CHAO

4
Ein großes Lob dafür, dass Sie es in den Bewertungs-Tab "Beiträge von geringer Qualität" geschafft haben.
Yannis

@ ZaphodBeeblebrox - Nicht absichtlich, das kann ich Ihnen versichern.
Oded

Nicht wirklich, ein lambdaAusdruck in Schema ist wie ein functionAusdruck ohne Namen - aber nichts hindert Sie daran, ihnen später einen Namen zu geben. Zum Beispiel var f = [function(x){return x;}][0]. Man könnte argumentieren, dass der Funktionswert selbst keinen Namen hat, aber das würde für alle Funktionen zutreffen ...
Eli Barzilay


8

In C # ist die Funktion Anonymous ein allgemeiner Begriff, der sowohl Lambda-Ausdrücke als auch anonyme Methoden enthält (anonyme Methoden sind Delegate-Instanzen ohne tatsächliche Methodendeklaration).

Lambda-Ausdrücke können in die Ausdrücke Lambda und Statement Lambda zerlegt werden

Ausdruck Lambda:

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

Die Anweisung lambda ähnelt dem Ausdruck lambda, mit der Ausnahme, dass die Anweisung (en) in geschweifte Klammern eingeschlossen sind:

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

Wenn wir über Lambda-Ausdrücke in JavaScript sprechen, bedeutet das im Grunde nur, eine Funktion als Argument in einem Aufruf einer anderen Funktion zu verwenden.

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 Viele Leute haben erwähnt, dass Lambdas anonyme Funktionen sind, aber es steckt noch mehr dahinter. Der Körper (rechte Seite) eines Lambda ist oft eher ein Ausdruck als ein Anweisungsblock. Der Hauptteil einer benannten Funktion, der ein Ausdruck ist, ist in der Regel in funktionalen Sprachen zulässig (oder erforderlich), jedoch nicht in imperativen Sprachen.
Zantier

4

TL; DR Wie andere betonten: Die Lambda-Notation ist nur eine Möglichkeit, Funktionen zu definieren, ohne gezwungen zu sein, ihnen einen Namen zu geben.

Lange Version

Ich würde gerne ein bisschen auf dieses Thema eingehen, weil ich es sehr interessant finde. Haftungsausschluss: Ich habe vor langer Zeit meinen Kurs über Lambda-Kalkül belegt. Wenn jemand mit besseren Kenntnissen Ungenauigkeiten in meiner Antwort findet, kann er mir gerne helfen, diese zu verbessern.

Beginnen wir mit Ausdrücken, zB 1 + 2und x + 2. Literale wie 1und 2werden Konstanten genannt, weil sie an bestimmte feste Werte gebunden sind.

Ein Bezeichner wie x" Variable" muss zuerst an einen Wert gebunden werden, um ihn auszuwerten. Sie können also grundsätzlich nicht bewerten x + 1, solange Sie nicht wissen, was xist.

Die Lambda-Notation bietet ein Schema zum Binden bestimmter Eingabewerte an Variablen. Ein Lambda-Ausdruck kann gebildet werden, indem λx .vor einem existierenden Ausdruck hinzugefügt wird , z λx . x + 1. Variable xwird gesagt, dass frei in x + 1und gebunden inλx . x + 1

Wie hilft dies bei der Auswertung von Ausdrücken? Wenn Sie dem Lambda-Ausdruck einen Wert hinzufügen, wie folgt

(λx . x + 1) 2

Dann können Sie den gesamten Ausdruck auswerten, indem Sie alle Vorkommen der Variablen xdurch den Wert 2 ersetzen (binden) :

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

Die Lambda-Notation bietet also einen allgemeinen Mechanismus, um Dinge an Variablen zu binden, die in einem Ausdrucks- / Programmblock vorkommen. Je nach Kontext entstehen so in den Programmiersprachen sehr unterschiedliche Konzepte:

  • In einer rein funktionalen Sprache wie Haskell stellen Lambda-Ausdrücke Funktionen im mathematischen Sinne dar: Ein Eingabewert wird in den Lambda-Körper injiziert und ein Ausgabewert wird erzeugt.
  • In vielen Sprachen (z. B. JavaScript, Python, Schema) kann die Bewertung des Körpers eines Lambda-Ausdrucks Nebenwirkungen haben. In diesem Fall kann man den Begriff Prozedur verwenden , um die Differenz für reine Funktionen zu kennzeichnen.

Abgesehen von den Unterschieden geht es bei der Lambda-Notation darum, formale Parameter zu definieren und an tatsächliche Parameter zu binden.

Der nächste Schritt besteht darin, einer Funktion / Prozedur einen Namen zu geben. In mehreren Sprachen sind Funktionen Werte wie alle anderen, sodass Sie einer Funktion wie folgt einen Namen geben können:

(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

Wie Eli Barzilay betonte, binden diese Definitionen den Namen nur fan einen Wert, der zufällig eine Funktion ist. In dieser Hinsicht sind Funktionen, Zahlen, Zeichenfolgen und Zeichen alle Werte, die auf die gleiche Weise an Namen gebunden werden können:

(define n 42)   ;; Scheme

n = 42          -- Haskell

val n: Int = 42 // Scala

var n = 42      // JavaScript

n = 42          # Python

In diesen Sprachen können Sie eine Funktion auch unter Verwendung der bekannteren (aber äquivalenten) Notation an einen Namen binden:

(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

Einige Sprachen, z. B. C, unterstützen nur die letztere Notation zum Definieren von (benannten) Funktionen.

Verschlüsse

Einige abschließende Bemerkungen zu Schließungen . Betrachten Sie den Ausdruck x + y. Dieser enthält zwei freie Variablen. Wenn Sie xmit der Lambda-Notation binden , erhalten Sie:

\x -> x + y

Dies ist (noch) keine Funktion, da sie noch eine freie Variable enthält y. Sie könnten auch eine Funktion daraus machen, indem Sie Folgendes binden y:

\x -> \y -> x + y

oder

\x y -> x + y

Das ist genau das gleiche wie die +Funktion.

Aber Sie können zum Beispiel yauf andere Weise binden (*):

incrementBy y = \x -> x + y

Das Ergebnis der Anwendung von FunktionsinkrementBy auf eine Zahl ist ein Abschluss, dh eine Funktion / Prozedur, deren Hauptteil eine freie Variable (z. B. y) enthält, die an einen Wert aus der Umgebung gebunden wurde, in der der Abschluss definiert wurde.

Ebenso incrementBy 5die Funktion (Closure), die die Zahlen um 5 erhöht.

HINWEIS (*)

Ich betrüge hier ein bisschen:

incrementBy y = \x -> x + y

ist äquivalent zu

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

Der Bindemechanismus ist also derselbe. Intuitiv stelle ich mir einen Verschluss als Teil eines komplexeren Lambda-Ausdrucks vor. Wenn diese Repräsentation erstellt wird, wurden einige der Bindungen des Mutterausdrucks bereits festgelegt und der Abschluss verwendet sie später, wenn sie ausgewertet / aufgerufen wird.


Ich bin nur ein Anfänger, aber ich denke, das kann ein bisschen verwirrend sein, wenn Sie versuchen, λ-Kalkül im mathematischen Sinne zu verstehen, da das, was Sie Konstanten nennen, Variablen genannt und mit den Symbolen a, b, c bezeichnet werden ... Was Sie Aufrufvariablen wären eine unbestimmte Variable x . Andererseits ist 1 λ f x . f x , 2 ist λ f x . f ( f x ) und so weiter.
Jinawee

@jinawee: Ich gebe zu, ich habe die genaue Definition nicht nachgeschlagen. Ich erinnere mich an die Verwendung der Begriffe Variablen und Konstanten in der Logik. Dort ist eine Konstante ein Symbol, das einer Domäne zugeordnet ist, während eine Variable ein Symbol ist, über das Sie quantifizieren können. Aber auch hier ist (1) es lange her, dass ich einen Kurs über Logik belegt habe, und (2) Lambda-Kalkül muss nicht den Konzepten der mathematischen Logik 1-1 folgen. Wenn Sie mich auf eine Referenz verweisen, kann ich versuchen, meine Terminologie zu korrigieren.
Giorgio

0

"Lambda" in der Programmierung bedeutet üblicherweise "Lambda-Funktion" (oder auch "Lambda-Ausdruck", "Lambda-Term"). Wenn function ein benannter Codeblock ist, der vor seiner Verwendung definiert wurde, ist "lambda function" ein Codeblock (oder ein Ausdruck), der anstelle der Verwendung definiert wurde und als erstklassiger Bürger in einer Programmiersprache verwendet werden kann.

In JavaScript ES6 (2015) gibt es eine kurze Syntax zum Definieren von Lambdas mit der Bezeichnung "Pfeilfunktionen" . In C # wurde eine solche Syntax in .NET 3.0 eingeführt (um 2006) .

In der Mathematik hat ein "Funktions" -Begriff mehrere Bedeutungen, wobei sich eine der Bedeutungen auf die Notation einer Funktion bezieht (dh wie man sie aufschreibt), dann ist "Lambda-Funktion" (im Kalkül) eine spezielle Art von Funktionsnotation. Weitere Informationen finden Sie unter Lambda-Funktionen in Programmiersprachen .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.