Les parenthèses dans le schéma sont très spéciaux. Ils veulent dire apply
:
(define (test arg) arg)
((test +) 4 5) ; ==> 9
Le même en JavaScript:
const plus = (a, b) => a+b; // Needed since + is not a function in JS
const test = arg => arg
test(plus)(4,5) // ==> 9
Dans votre code que vous avez:
((display (/ (+ (* b -1) (sqrt det)) (* 2 a)))
(display (/ (- (* b -1) (sqrt det)) (* 2 a))))
Malheureusement, l'expression en position opérateur retour #<undef>
. En fait accoring à la spécification, il peut retourner quoi que ce soit car son indéfini dans la spécification. Ib votre implémentation particulière si ce n'est pas une fonction il est comme:
((test 'symbol) 4 5); ==> Error: symbol is not a function
Comme vous avez vu plus tôt avoir un appel à test
ne travail plus tôt si les expressions dans la position de l'opérateur est un code parfaitement valide et presque impossible de raisonner sur au moment de la compilation , mais en cours d'exécution, il deviendra évident qu'il n'est pas possible de continuer quand apply obtient une fonction non.
Maintenant, il existe des macros qui utilisent des parenthèses pour autre chose que l'application et il vous suffit de connaître ou de lire la documentation. Un exemple est cond
(cond ((= 3 5) #t)
(else #f))
; ==> #f
Si vous ne l'avez jamais vu cond
avant qu'il est facile de supposer ((= 3 5) #t)
est une expression et bien sûr en le regardant, il ne devrait pas fonctionner car (= 3 5)
n'évaluerait pas à un objet de fonction mais une booléen Cependant chaque terme dans cond
évalue c'est car
alors chaque élément dans le reste du terme dans l'ordre s'il s'est avéré être une vraie valeur.
Pour faire plus d'expressions dans l'ordre et retourner la valeur de la dernière expression on utilise begin
:
(begin 1 2 3)
; ==> 3
Ici 1
et évaluent 2
est un code bien mort car il ne fait rien. Ainsi, son héritage que l'utilisation begin
implique un effet secondaire où la valeur de retour est sans importance, mais l'effet secondaire est. Je ne pense pas que votre fonction a vraiment besoin d'effets secondaires:
(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)
Merci.Oui, je voulais ajouter un début dans le corps de la si et maintenant je vois pourquoi l'affichage a causé l'erreur. Ça fonctionne maintenant. –