为什么我得到#不是函数错误?
问题描述:
这是我的代码,我有点困惑,为什么我收到这个错误。我的代码只是找到一个二次方程的根。为什么我得到#<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)
答
我相信你的意思是在正文中添加一个begin
你一个武装如果公司的。 display
过程具有无效返回值,额外的括号会尝试将该值作为过程应用。您可以通过运行((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)))
)
)
)
答
方案括号是非常特殊的。他们的意思是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
在你的代码有:
((display (/ (+ (* b -1) (sqrt det)) (* 2 a)))
(display (/ (- (* b -1) (sqrt det)) (* 2 a))))
不幸的是,在操作位置返回#<undef>
表达。实际上,根据规范,它可以返回任何东西,因为它在规范中未定义。 IB您的具体实现,虽然它不是一个功能,所以它是这样的:
((test 'symbol) 4 5); ==> Error: symbol is not a function
正如你前面看到的具有test
一个电话没工作较早所以在操作员位置表情是完全有效的代码,几乎不可能在编译时推理,但是在运行时它将变得很明显,当应用程序获得非函数时不可能继续。
现在有一些宏使用括号来表示应用程序以外的东西,而这些只是必须知道或阅读的文档。一个例子是cond
(cond ((= 3 5) #t)
(else #f))
; ==> #f
如果你从来没有见过cond
很容易承担((= 3 5) #t)
是看它,它不应该因为(= 3 5)
工作的表达,当然,也不会计算为一个函数对象但之前布尔值。然而,cond
中的每个术语评估它的car
,然后评估其余部分中的每个元素,如果它碰巧是一个真正的值。
,以便做更多的表达式并返回最后一个表达式的值使用begin
:
(begin 1 2 3)
; ==> 3
这里评估1
和2
显然是死代码,因为它没有做任何事情。因此,其继承使用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)
谢谢。是的,我打算在if的主体中添加一个开始,现在我明白为什么显示会导致错误。它现在有效。 –