der Unterschied zwischen if und cond?
Frage
Ich lerne jetzt SICP und mache den Ex2.23 Ich habe den folgenden Code: Ich habe den folgenden Code:
(define (for-each proc items)
(if (null? items)
#t
((proc (car items))
(for-each proc (cdr items)))))
Aber beim Laufen verursachen Fehler: Verfahrensanwendung: Erwartete Prozedur, gegeben: #; Argumente waren: ()
Ich glaube, ich kenne den Grund: Ich nenne die For-EECH
Aber wenn ich den Code geändert habe:
(define (for-each proc items)
(cond ((null? items) #t)
(else (proc (car items)) (for-each proc (cdr items)))))
Es läuft gut. Ich verstehe nicht, warum? in Kond, Muss jeder als For-Each den Wert zurückgeben?
Ich habe DrScheme verwendet und Sprache auswählte Sicp
Ich bin kein Muttersprachler von Englisch. Wenn es also STH gibt, was nicht klar beschrieben wird, sag mir bitte
Lösung
Aber beim Ausführen verursachen Fehler: Verfahrensanwendung: Erwartung> Verfahren, gegeben: #; Argumente waren: ()
Ich glaube, ich kenne den Grund: Ich nenne die For-EECH
Nein, es liegt daran, dass in der alternativen Klausel von if
Sie haben die Kombination ((proc (car items)) (for-each proc (cdr items)))
. Sie wollten die beiden Kombinationen bewerten (proc (car items))
und (for-each proc (cdr items))
Nacheinander und zu diesem Zweck dachten Sie, sie in ein anderes Klammern zu bringen würden funktionieren. Aber in Wirklichkeit haben Sie angegeben, dass das Ergebnis von (proc (car items))
ist ein Verfahren, das auf das Argument angewendet wird, das der Rückgabewert von ist (for-each proc (cdr items))
. Dies ist nicht der Fall, und Sie erhalten einen Fehler. Der entscheidende Punkt ist, dass Klammern in LISP nicht für die Gruppierung gelten, sondern eine eindeutige Bedeutung haben.
Das Problem ist, dass if
Kann nur eine einzige Kombination in dieser Position haben, während Sie zwei in Folge haben möchten. Auf der anderen Seite, cond
erleidet keine solche Einschränkung; Sie können so lange eine Abfolge einzelner Kombinationen im daraus resultierenden Teil von a setzen cond
Klausel wie Ihr Herz begehrt. Dieser Zustand ist einfach, wie die Sprache für die Arbeit definiert wird.
Sie können genauso gut verwenden cond
in diesen Situationen, aber wenn Sie noch verwenden möchten if
Es gibt einige Optionen, um mehrere Kombinationen in eine zu füllen. Z.B. Sie können ein Lambda -Verfahren erstellen, dessen Körper die beiden Kombinationen sind und sofort abfeuern:
(define (for-each proc items) (if (null? items) #t ((lambda () (proc (car items)) (for-each proc (cdr items)) )) ))
Oder Sie können verwenden begin
das soll tatsächlich für einen solchen Zweck verwendet werden:
(define (for-each proc items) (if (null? items) #t (begin (proc (car items)) (for-each proc (cdr items)) ) ))