Die Klammern in Schema sind sehr speziell. Sie bedeuten apply
:
(define (test arg) arg)
((test +) 4 5) ; ==> 9
Das gleiche in JavaScript:
const plus = (a, b) => a+b; // Needed since + is not a function in JS
const test = arg => arg
test(plus)(4,5) // ==> 9
In Ihrem Code Sie haben:
((display (/ (+ (* b -1) (sqrt det)) (* 2 a)))
(display (/ (- (* b -1) (sqrt det)) (* 2 a))))
Leider ist der Ausdruck in Bedienerposition Rückkehr #<undef>
. Eigentlich entsprechend der Spezifikation kann alles zurückgeben, weil es undefined in der Spezifikation ist. Ib Ihre spezielle Implementierung obwohl es keine Funktion, so es heißt:
((test 'symbol) 4 5); ==> Error: symbol is not a function
Wie Sie bereits gesehen haben einen Aufruf an test
mit früher funktioniert so Ausdrücke in Bedienerposition sind perfekt gültige Code und fast unmöglich, bei der Kompilierung zur Vernunft über , aber in der Laufzeit wird es offensichtlich, dass es nicht möglich ist, fortzufahren, wenn die Anwendung eine Nicht-Funktion erhält.
Jetzt gibt es Makros, die Klammern für etwas anderes als Anwendung verwenden, und diese müssen Sie nur wissen oder lesen Sie die Dokumentation für. Ein Beispiel dafür ist cond
(cond ((= 3 5) #t)
(else #f))
; ==> #f
Wenn Sie noch nie cond
gesehen haben, bevor es einfach ist, ein Ausdruck anzunehmen ((= 3 5) #t)
ist und natürlich durch Blick auf sie es nicht, da (= 3 5)
funktionieren sollte zu einem Funktionsobjekt nicht bewerten würde, sondern ein boolesch. Jedoch bewertet jedes Glied in cond
es car
dann jedes Element im Rest des Ausdruckes, wenn es ein echter Wert war.
Um weitere Ausdrücke, um zu tun und den Wert des letzten Ausdrucks zurückgeben verwendet man begin
:
(begin 1 2 3)
; ==> 3
Hier 1
Bewertung und 2
ist eindeutig toter Code, da er nichts tun. So erbt er, dass die Verwendung begin
einen Nebeneffekt impliziert, bei dem der Rückgabewert keine Rolle spielt, aber der Nebeneffekt ist. Ich glaube nicht, dass Ihre Funktion wirklich Nebenwirkungen benötigt:
(define (roots a b c)
(define det
(- (* b b) (* 4 a c)))
(cond ((> det 0)
(list (/ (+ (* b -1) (sqrt det)) (* 2 a))
(/ (- (* b -1) (sqrt det)) (* 2 a))))
((= det 0)
(list (/ (* b -1) (* 2 a))))
((< det 0)
(list (/ (+ (* b -1) (make-rectangular 0 (sqrt (* det -1)))) (* 2 a))
(/ (- (* b -1) (make-rectangular 0 (sqrt (* det -1)))) (* 2 a))))))
(roots -1 4 -4) ; ==> (2 -2)
(roots 1 0 -4) ; ==> (2)
(roots 4 0 4) ; ==> (0+1i 0-1i)
Vielen Dank.Ja, ich wollte einen Anfang im Körper des ifs hinzufügen und jetzt sehe ich, warum die Anzeige den Fehler verursacht hat. Es funktioniert jetzt. –