2014-09-06 23 views
7

Ich versuche zu verstehen, Lambda Verwendung im Schläger und ich bin immer noch unklar. Ich verstehe, dass sie ungenannte (anonyme) Funktionen sind, aber warum ist das gut? Ich muss auf meine Funktionen von anderen Funktionen aus zugreifen, also wie würde ich sie nennen ??? Bitte erläutern Sie das kleine Programm unten und warum ist die Verwendung von Lambda besser? Vielen Dank.Lambda im Racket erklärt

; why is this better than below??? 
(define test 
    (lambda (x) 
    (lambda (y) 
     (+ x y)))) 

(define add27 
    (test 27)) 

; what's wrong with this??? 
(define (addTest x) 
    (+ x 27)) 

> (add27 2) 
29 
> (addTest 2) 
29 

Antwort

10

In Racket (und anderen funktionalen Programmiersprachen) lambda s sind sehr nützlich, wenn Sie eine in-line übergeben wollen, One-Shot-Funktion als Parameter ohne es zunächst zu definieren. Nehmen wir zum Beispiel an, dass wir eine Liste von Zahlen quadratisch machen wollen. Wir können den langen Weg gehen und eine square Funktion zuerst definieren, und verwenden Sie dann map:

(define (square x) 
    (* x x)) 

(map square '(1 2 3 4 5)) 
=> '(1 4 9 16 25) 

... Oder wir können einfach eine lambda, wie dies passieren:

(map (lambda (x) (* x x)) 
    '(1 2 3 4 5)) 

=> '(1 4 9 16 25) 

Wie Sie sehen können, gibt Es gibt Fälle, in denen wir nicht benötigen, um auf den Namen einer Funktion zu verweisen. Natürlich, wenn die durch die lambda vertreten Verfahren in mehreren Teilen wiederverwendet werden sollen, oder ob es rekursiv ist dann macht es Sinn, ihm einen Namen zu geben (so ist es nicht mehr anonym):

(define square 
    (lambda (x) (* x x))) 

Die oben ist entspricht der ersten Definition von square am Anfang. In der Tat ist die erste Definition nur syntaktischer Zucker, um eine Funktion zu definieren, aber am Ende sind alle Funktionen lambdas!

Jetzt sehen wir uns Ihr Beispiel an. Hier verwenden wir eine lambda auf eine etwas andere Art und Weise, und auch ein Beispiel, warum sie nützlich - wir nicht nur eine Funktion zu definieren, sondern eine Funktion als auch der Rückkehr:

(define test 
    (lambda (x) 
    (lambda (y) 
     (+ x y)))) 

Vielleicht wird es sein, etwas klarer, wenn wir es so schreiben (es ist gleichwertig, für die oben genannten Gründen):

(define (test x) 
    (lambda (y) 
    (+ x y))) 

Oder noch kürzer - in Racket wir auch diese Syntax für den gleichen Zweck verwendet werden können:

(define ((test x) y) 
    (+ x y)) 

Es ist nicht so, dass dies ein besser (oder schlechter) Weg ist, um eine Funktion zu definieren - es ist eine andere Sache! Wir definieren eine Prozedur namens test, die als Parameter x empfängt und als Ergebnis eine neue anonyme Funktion zurückgibt, die wiederum als Parameter y empfangen wird. Nun, in diesen Zeilen:

(define add27 
    (test 27)) 

... Wir nennen test mit einem x Wert von 27, die die anonyme Funktion zurückgibt, und wir Namen die add27 funktionieren. Merken Sie sich die lambda, die als Parameter y empfangen wurde? Jetzt, dass lambda wurde add27 benannt - und dies ist ein Beispiel für currying.Denken Sie daran: test ist eine Funktion, die zur Erzeugung von Funktionen verwendet wird, die einen festen Wert x zu einem bestimmten Parameter hinzuzufügen y, das erklärt, warum das funktioniert:

(add27 2) 
=> 29 

Auf der anderen Seite, wird diese Funktion immer hinzufügen 27 zu seinem Parameter mit keiner Möglichkeit, es zu ändern:

(define (addTest x) 
    (+ x 27)) 

(addTest 2) 
=> 29 

Sie sehen den Unterschied? test ermöglicht es uns, neue Funktionen zu generieren, die einen beliebigen Wert hinzufügen, während addTest immer einen festen Wert 27 hinzufügt. Was ist, wenn Sie hinzufügen möchten, 100? test Verwendung ist einfach:

(define add100 (test 100)) 

Aber addTest kann nicht geändert werden, würden wir eine neue Funktion schreiben müssen:

(define (addTest100 x) 
    (+ x 100)) 

Ich hoffe, das klärt die Dinge, fühlen Sie sich frei in den Kommentaren fragen irgendwelche zusätzlichen Fragen über meine Antwort.

+1

Vielen Dank für diese Erklärung. Ich versuche immer noch zu verstehen, wie alles funktioniert, aber das ist ein guter Anfang. Jetzt muss ich es nur 500 Mal neu lesen. =) – 1Raptor007

+0

Es tut mir leid, aber ich bin immer noch unklar, wie dies eine Funktion zurückgibt. Ich verstehe es nicht. – 1Raptor007

+1

@ 1Raptor007 Eine Funktion gibt den letzten Wert zurück. Zum Beispiel gibt dies "1" zurück, wenn es aufgerufen wird: '(define (f) 1)'. Und da ein "Lambda" auch ein Wert wie jeder andere ist, wenn wir dies schreiben: '(define (f) (lambda (x) x))' dann haben wir eine Funktion, die, wenn sie aufgerufen wird, als Ergebnis zurückkommt eine anonyme Funktion –