971 Stimmen

Was ist der Unterschied zwischen einer "Closure" und einem "Lambda"?

Kann mir das jemand erklären? Ich verstehe die grundlegenden Konzepte dahinter, aber ich sehe oft, dass sie austauschbar verwendet werden, und das verwirrt mich.

Und wenn wir schon dabei sind, wie unterscheiden sie sich von einer normalen Funktion?

13voto

Wei Qiu Punkte 819

Aus der Sicht der Programmiersprachen handelt es sich um zwei völlig unterschiedliche Dinge.

Für eine vollständige Turing-Sprache benötigen wir im Grunde nur sehr wenige Elemente, z.B. Abstraktion, Anwendung und Reduktion. Abstraktion und Anwendung ermöglichen den Aufbau von Lambda-Ausdrücken, während die Reduktion die Bedeutung der Lambda-Ausdrücke ableitet.

Lambda bietet eine Möglichkeit, den Berechnungsprozess zu abstrahieren. Um beispielsweise die Summe zweier Zahlen zu berechnen, kann ein Prozess, der zwei Parameter x, y annimmt und x+y zurückgibt, abstrahiert werden. In einem Schema kann man das wie folgt schreiben

(lambda (x y) (+ x y))

Sie können die Parameter umbenennen, aber die Aufgabe, die sie erfüllt, ändert sich nicht. In fast allen Programmiersprachen kann man dem Lambda-Ausdruck einen Namen geben, der dann als Funktion bezeichnet wird. Aber es gibt keinen großen Unterschied, sie können konzeptionell als reiner Syntaxzucker betrachtet werden.

OK, jetzt stellen Sie sich vor, wie das umgesetzt werden kann. Wann immer wir den Lambda-Ausdruck auf einige Ausdrücke anwenden, z.B.

((lambda (x y) (+ x y)) 2 3)

Wir können die Parameter einfach durch den zu bewertenden Ausdruck ersetzen. Dieses Modell ist bereits sehr leistungsfähig. Aber dieses Modell ermöglicht es uns nicht, die Werte von Symbolen zu ändern, z.B. können wir die Änderung des Status nicht nachahmen. Wir brauchen also ein komplexeres Modell. Um es kurz zu machen, immer wenn wir die Bedeutung des Lambda-Ausdrucks berechnen wollen, legen wir das Paar aus Symbol und dem entsprechenden Wert in eine Umgebung (oder Tabelle). Dann wird der Rest (+ x y) durch Nachschlagen der entsprechenden Symbole in der Tabelle ausgewertet. Wenn wir nun einige Primitive zur Verfügung stellen, um direkt mit der Umgebung zu arbeiten, können wir die Statusänderungen modellieren!

Vor diesem Hintergrund sollten Sie diese Funktion überprüfen:

(lambda (x y) (+ x y z))

Wir wissen, dass, wenn wir den Lambda-Ausdruck auswerten, x und y in eine neue Tabelle gebunden werden. Aber wie und wo können wir z nachschlagen? Eigentlich ist z eine freie Variable. Es muss eine äußere eine Umgebung geben, die z enthält. Andernfalls kann die Bedeutung des Ausdrucks nicht allein durch die Bindung von x und y bestimmt werden. Um dies zu verdeutlichen, können Sie etwas wie folgt in Schema schreiben:

((lambda (z) (lambda (x y) (+ x y z))) 1)

In einer äußeren Tabelle würde z also an 1 gebunden sein. Wir erhalten immer noch eine Funktion, die zwei Parameter akzeptiert, aber die tatsächliche Bedeutung hängt auch von der äußeren Umgebung ab. Mit anderen Worten: Die äußere Umgebung schließt die freien Variablen ein. Mit Hilfe von set! können wir die Funktion zustandsabhängig machen, d. h. sie ist keine Funktion im Sinne der Mathematik. Was sie zurückgibt, hängt nicht nur von der Eingabe, sondern auch von z ab.

Dies ist etwas, das Sie bereits sehr gut kennen, eine Methode von Objekten stützt sich fast immer auf den Zustand von Objekten. Deshalb sagen manche Leute: "Schließungen sind die Objekte des armen Mannes. "Aber wir könnten Objekte auch als die Closures des armen Mannes betrachten, da wir Funktionen erster Klasse wirklich mögen.

Ich verwende Schema zur Veranschaulichung der Ideen, da Schema eine der frühesten Sprachen ist, die echte Abschlüsse hat. Das gesamte Material hier wird viel besser in SICP Kapitel 3 dargestellt.

Zusammenfassend lässt sich sagen, dass Lambda und Closure wirklich unterschiedliche Konzepte sind. Ein lambda ist eine Funktion. Eine Closure ist ein Paar aus Lambda und der entsprechenden Umgebung, die das Lambda abschließt.

11voto

Developer Punkte 23523

Das Konzept ist dasselbe wie oben beschrieben, aber wenn Sie PHP-Kenntnisse haben, wird dies anhand von PHP-Code weiter erläutert.

$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, function ($v) { return $v > 2; });

function ($v) { return $v > 2; } ist die Definition der Lambda-Funktion. Wir können sie sogar in einer Variablen speichern, damit sie wiederverwendet werden kann:

$max = function ($v) { return $v > 2; };

$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max);

Was aber, wenn Sie die maximal zulässige Anzahl im gefilterten Array ändern wollen? Dann müssten Sie eine weitere Lambda-Funktion schreiben oder eine Closure erstellen (PHP 5.3):

$max_comp = function ($max) {
  return function ($v) use ($max) { return $v > $max; };
};

$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max_comp(2));

Eine Closure ist eine Funktion, die in ihrer eigenen Umgebung ausgewertet wird und eine oder mehrere gebundene Variablen hat, auf die beim Aufruf der Funktion zugegriffen werden kann. Sie stammen aus der Welt der funktionalen Programmierung, wo eine Reihe von Konzepten im Spiel sind. Closures sind wie Lambda-Funktionen, aber intelligenter in dem Sinne, dass sie die Möglichkeit haben, mit Variablen aus der Umgebung, in der die Closure definiert ist, zu interagieren.

Hier ist ein einfacheres Beispiel für eine PHP-Schließung:

$string = "Hello World!";
$closure = function() use ($string) { echo $string; };

$closure();

Das wird in diesem Artikel gut erklärt.

9voto

philippe lhardy Punkte 2964

Diese Frage ist alt und wurde schon oft beantwortet.
Jetzt mit Java 8 und Official Lambda, die inoffizielle Abschlussprojekte sind, stellt sich die Frage erneut.

Die Antwort im Java-Kontext (über Lambdas und Schließungen - was ist der Unterschied? ):

"Ein Closure ist ein Lambda-Ausdruck, der mit einer Umgebung gepaart ist, die jede seiner freien Variablen an einen Wert bindet. In Java werden Lambda-Ausdrücke mit Hilfe von Closures implementiert, daher werden die beiden Begriffe in der Community synonym verwendet."

6voto

feilengcui008 Punkte 67

Vereinfacht gesagt, ist closure ein Trick über den Anwendungsbereich, lambda ist eine anonyme Funktion. Wir können Closure mit Lambda eleganter realisieren und Lambda wird oft als Parameter verwendet, der an eine höhere Funktion übergeben wird

6voto

yoAlex5 Punkte 20661

Lambda vs. Schließung

Lambda es anonyme Funktion(Methode)

Closure ist eine Funktion, die schließt sich um (Einfangen) von Variablen aus dem umschließenden Bereich (z. B. nicht-lokale Variablen)

Java

interface Runnable {
    void run();
}

class MyClass {
    void foo(Runnable r) {

    }

    //Lambda
    void lambdaExample() {
        foo(() -> {});
    }

    //Closure
    String s = "hello";
    void closureExample() {
        foo(() -> { s = "world";});
    }
}

Schnell [Schließung]

class MyClass {
    func foo(r:() -> Void) {}

    func lambdaExample() {
        foo(r: {})
    }

    var s = "hello"
    func closureExample() {
        foo(r: {s = "world"})
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X