2017-05-28 4 views
1

これは私のコードであり、私はこのエラーを受けている理由が少し混乱しています。私のコードは、二次方程式の根を見つけることだけです。#<undef>はなぜ機能エラーではありませんか?

(define (roots a b c) 
    (define det 
    (- (* b b) (* 4 a c)) 
) 
    (if (> det 0) (
        (display (/ (+ (* b -1) (sqrt det)) (* 2 a))) 
        (display (/ (- (* b -1) (sqrt det)) (* 2 a))) 
       ) 
) 
    (if (= det 0) (
        (display (/ (* b -1) (* 2 a))) 
        (display (/ (* b -1) (* 2 a))) 
       ) 
) 
    (if (< det 0) (
        (display "complex roots") 
        (display (/ (+ (* b -1) sqrt(* det -1)) (* 2 a))) 
        (display (/ (- (* b -1) sqrt(* det -1)) (* 2 a))) 
       )    
) 
) 

(roots -2 4 5) 
(roots -2 4 -5) 

答えて

2

私はあなたの1つが武装さんの身体にbeginを追加するためのものと考えています。 displayプロシージャにはvoid戻り値があり、追加のかっこではその値をプロシージャとして適用しようとします。 ((display 5))を実行すると、エラーを再現できます。 beginを使用すると、順序で式を代わりに評価することができます。


このコードは、例外なしに値が表示されます:

(define (roots a b c) 
    (define det 
    (- (* b b) (* 4 a c)) 
) 
    (if (> det 0) (begin 
        (display (/ (+ (* b -1) (sqrt det)) (* 2 a))) 
        (display (/ (- (* b -1) (sqrt det)) (* 2 a))) 
       ) 
) 
    (if (= det 0) (begin 
        (display (/ (* b -1) (* 2 a))) 
        (display (/ (* b -1) (* 2 a))) 
       ) 
) 
    (if (< det 0) (begin 
        (display "complex roots") 
        (display (/ (+ (* b -1) sqrt(* det -1)) (* 2 a))) 
        (display (/ (- (* b -1) sqrt(* det -1)) (* 2 a))) 
       )    
) 
) 
+0

ありがとう。はい、私はifの本体にbeginを追加するつもりでしたが、今度はディスプレイがエラーを引き起こした理由がわかります。それは今働く。 –

2

スキームの括弧は非常に特殊です。彼らはapplyを意味:

(define (test arg) arg) 

((test +) 4 5) ; ==> 9 

JavaScriptで同じ:あなたのコードで

const plus = (a, b) => a+b; // Needed since + is not a function in JS 
const test = arg => arg 

test(plus)(4,5) // ==> 9 

はあなたが持っている:オペレータ位置復帰#<undef>

((display (/ (+ (* b -1) (sqrt det)) (* 2 a))) 
(display (/ (- (* b -1) (sqrt det)) (* 2 a)))) 

残念ながら表現。実際には仕様に準じているので、何でもが仕様で定義されていないので返すことができます。 Ibのあなたの特定の実装、それは同様ですので、それは機能しませんけれども:

((test 'symbol) 4 5); ==> Error: symbol is not a function 

以前testへの呼び出しを有するオペレータ位置での式はコンパイル時で約推論する完全に有効なコードとほとんど不可能である、以前のように仕事をした見たように実行時には、applyが非関数を取得したときには続行することができないことが明らかになります。

ここで、アプリケーション以外のものにかっこを使用するマクロがあります。これらのマクロは、ドキュメントを知っていたり、読んだりするだけです。それは((= 3 5) #t)(= 3 5)は関数オブジェクトに評価されなくなるため、それが動作してはならない、それを見て表現し、もちろんであると仮定するのは簡単です前にcondを見たことがない場合の例では、cond

(cond ((= 3 5) #t) 
     (else #f)) 
; ==> #f 

ですブール値。しかし、condの各タームは、それが真の値になった場合には、そのタームの残りの部分の各要素を順番に評価します(car)。ために、複数の式を行うと、最後の式1の値を返すために

beginを使用しています:それは何もしませんので、ここで

(begin 1 2 3) 
; ==> 3 

12を評価することが明らかにデッドコードです。したがって、beginを使用することは、戻り値が重要ではない副作用を意味しますが、副作用があることを継承します。私はあなたの機能が実際に副作用を必要としているとは思わない:

(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) 
関連する問題