Scheme 为什么我会得到#<;未定义>;这不是函数错误吗?
这是我的代码,我有点困惑为什么我会收到这个错误。我的代码就是找到一个二次方程的根Scheme 为什么我会得到#<;未定义>;这不是函数错误吗?,scheme,Scheme,这是我的代码,我有点困惑为什么我会收到这个错误。我的代码就是找到一个二次方程的根 (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
(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)
(定义(根a b c)
(定义det)
((*4B)(*4C))
)
(如果(>det 0)(
(显示(/(+(*b-1)(sqrt数据))(*2A)))
(显示(/((*b-1)(sqrt数据))(*2A)))
)
)
(如果(=det 0)(
(显示(/(*b-1)(*2A)))
(显示(/(*b-1)(*2A)))
)
)
(如果(
我相信你的意思是在你的单臂if的身体中添加一个开始。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)))
)
)
)
(定义(根a b c)
(定义det)
((*4B)(*4C))
)
(如果(>det 0)(开始
(显示(/(+(*b-1)(sqrt数据))(*2A)))
(显示(/((*b-1)(sqrt数据))(*2A)))
)
)
(如果(=det 0)(开始
(显示(/(*b-1)(*2A)))
(显示(/(*b-1)(*2A)))
)
)
(如果(
我相信你的意思是在你的单臂if的身体中添加一个开始。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)))
)
)
)
(定义(根a b c)
(定义det)
((*4B)(*4C))
)
(如果(>det 0)(开始
(显示(/(+(*b-1)(sqrt数据))(*2A)))
(显示(/((*b-1)(sqrt数据))(*2A)))
)
)
(如果(=det 0)(开始
(显示(/(*b-1)(*2A)))
(显示(/(*b-1)(*2A)))
)
)
(如果(
方案中的括号非常特殊。它们的意思是应用
:
(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))))
不幸的是,运算符位置中的表达式返回#
。实际上,根据规范,它可以返回任何内容,因为它在规范中未定义。Ib是您的特定实现,但它不是一个函数,因此它类似于:
((test 'symbol) 4 5); ==> Error: symbol is not a function
正如您在前面看到的,调用test
之前确实有效,因此运算符位置的表达式是完全有效的代码,几乎不可能在编译时进行推理,但在运行时,当apply获得非函数时,显然不可能继续
现在有一些宏使用括号表示应用程序以外的内容,您只需了解或阅读文档即可。例如cond
(cond ((= 3 5) #t)
(else #f))
; ==> #f
如果您以前从未见过cond,那么很容易假设(=35)#t)
是一个表达式,当然,通过查看它,它不应该起作用,因为(=35)
不会计算为函数对象,而是布尔值。但是,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)
(定义(根a b c)
(定义det)
(((*BB)(*4C)))
(条件((>det 0)
(列表(/(+(*b-1)(sqrt det))(*2A))
(/((*b-1)(sqrt数据))(*2A)))
(=det 0)
(列表(/(*b-1)(*2A)))
((2 -2)
(根10-4);==>(2)
(根4 0 4);==>(0+1i 0-1i)
方案中的括号非常特殊。它们的意思是应用
:
(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))))
不幸的是,运算符位置中的表达式返回#
。实际上,根据规范,它可以返回任何内容,因为它在规范中未定义。Ib是您的特定实现,但它不是一个函数,因此它类似于:
((test 'symbol) 4 5); ==> Error: symbol is not a function
正如您在前面看到的,调用test
之前确实有效,因此运算符位置的表达式是完全有效的代码,几乎不可能在编译时进行推理,但在运行时,当apply获得非函数时,显然不可能继续
现在有一些宏使用parenthe