为何以下几段Scheme代码并非全部可正常运行?
Scheme代码运行异常原因分析
代码#1:可正常运行
这段代码完全符合Scheme语法规范,能正常执行:
(define *o (lambda (x y z) (if (= y 0) z (*o x (sub1 y) (+ z x))))) (*o 7 3 0)
- 用
define配合lambda正确定义了递归函数*o - 递归调用时严格遵循
(函数名 参数...)的语法,是合法的函数调用 if表达式的终止条件和递归步骤逻辑清晰,通过累加实现了乘法计算
代码#2:无法运行的原因
代码存在三处关键错误:
(define *o (x y z) (cond ((0? y) z) (else *o x (sub1 y) (+ z x)))) (print (*o 7 3 0)) (define *o (lambda (x y z) (cond ((0? y) z) (else *o x (sub1 y) (+ z x))))) (*o 7 3 0)
- 函数定义语法错误:第一个
define用了错误的简写形式,Scheme中省略lambda的函数定义必须写成(define (*o x y z) ...),把函数名和参数列表放在同一个括号内,而不是(define *o (x y z) ...),这种写法解释器无法识别。 - 递归调用语法错误:两处
cond的else分支里,*o x (sub1 y) (+ z x)没有用括号包裹,Scheme中函数调用必须是(函数名 参数...)的形式,直接写标识符序列会被当成变量引用,不是调用函数。 - 非标准过程引用:
0?不是Scheme标准内置过程,标准写法应该是(zero? y)或者(= y 0),多数Scheme实现不会识别0?,会报未定义错误。
代码#3:无法运行的原因
代码存在和代码#2相同的核心错误:
(define *o (x y z) (cond ((0? y) z) (else *o x (sub1 y) (+ z x)))) (print (*o 7 3 0))
- 函数定义语法错误:同样用了错误的
define简写,正确的省略lambda写法是(define (*o x y z) ...),当前写法不符合Scheme语法规范。 - 递归调用缺少括号:
else分支的*o x (sub1 y) (+ z x)没有包裹成合法的函数调用形式(*o x (sub1 y) (+ z x))。 - 非标准过程
0?:和代码#2一样,0?不是标准内置过程,会导致未定义错误。
内容的提问来源于stack exchange,提问作者Peter Hodgson
相关产品推荐
相关产品推荐

