只需学习几天的Lisp,但是教授为我分配了一个练习。但是,我的代码无法编译,有人可以告诉我我的编码部分哪里做错了吗?
(defun( MIN-2 a b)
(cond
((and (numberp a) (numberp b) (<= a b)) a b)
((and (numberp a) (numberp b) nil) ERROR)
)
)
答案 0 :(得分:2)
文学翻译:
(defun min-2 (a b) ; Define a Lisp function MIN-2 … takes two arguments A and B
(cond ((and (every #'numberp (list a b)) (<= a b)) a) ; if … A <= B, returns A
((and (every #'numberp (list a b)) (> a b)) b) ; if … A > B, returns B
(t 'error) ; if A or B is not a number (i. e. “else”), returns ERROR
改进:事先检查一次数字。
(defun min-2 (a b)
(cond ((not (every #'numberp (list a b))) 'error)
((<= a b) a)
((> a b) b)))
请缩进您的代码,不要在括号中留着括号。
答案 1 :(得分:1)
有人可以告诉我我的编码部分哪里做错了吗?
(defun( MIN-2 a b)
(cond
((and (numberp a) (numberp b) (<= a b)) a b)
((and (numberp a) (numberp b) nil) ERROR)
)
)
让我重新格式化代码(自动缩进+压缩括号):
(defun (MIN-2 a b) ;; << bad syntax, as already pointed out in another answer
(cond
((and (numberp a) (numberp b) (<= a b))
a
b)
((and (numberp a) (numberp b) nil)
ERROR)))
让我们修复defun
的语法:
(defun MIN-2 (a b)
(cond
((and (numberp a) (numberp b) (<= a b))
a
b)
((and (numberp a) (numberp b) nil)
ERROR)))
错误(我正在Emacs + SBCL下编译代码):
未定义变量:ERROR
实际上,error
是一个自由变量。您需要引用它。
(defun MIN-2 (a b)
(cond
((and (numberp a) (numberp b) (<= a b))
a
b)
((and (numberp a) (numberp b))
'ERROR)))
警告:
删除无法访问的代码(带下划线的错误)。
实际上,这里的条件是and
表达式,其中至少一个
表达式为NIL
,这表示连接始终为假。这种情况永远不会发生,这就是为什么优化了的原因。
此外,第一个子句的测试是:
(and (numberp a) (numberp b) (<= a b))
子句主体为a
,后跟b
,这意味着对a
进行求值,将其值丢弃(从不使用),然后对b
求值并它的值是cond
表达式的值:当两个输入都是b
这样的数字时,您总是返回a <= b
。
很显然,这不是您应该执行的操作。其他答案已经涵盖了好的解决方案。
我也在这里提供其他替代方法,不一定是对家庭作业友好的答案:
(defun min-2 (a b)
(handler-case (if (<= a b) a b)
(error () 'error)))
(defun min-2 (a b)
(or (ignore-errors (if (<= a b) a b))
'error))
(defgeneric min-2 (a b)
(:method ((a number) (b number)) (if (<= a b) a b))
(:method (a b) 'error))
答案 2 :(得分:0)
您使用错误的语法定义函数。使用defun function-name (args)
(defun MIN-2 (a b)
(cond
((and (numberp a) (numberp b) (<= a b)) a b)
((and (numberp a) (numberp b) nil) ERROR)
)
)
答案 3 :(得分:0)
我认为值得以这样的方式编写这样的函数,即明确什么是健全性检查以及什么是实际计算。因此,在这种情况下,健全性检查是:“两个参数都是数字吗?”如果他们是比较的话,计算就是它们的比较。因此,请将这两件事分开,而不是将它们捆绑为一个条件:
(defun min-2 (a b)
(if (and (numberp a) (numberp b))
;; sanity check OK, so compare them
(if (<= a b)
a
b)
'error))
不幸的是,当然,健全性检查还不够:
> (min-2 1 2)
1
> (min-2 1 'a)
error
> (min-2 1 #c(1 1))
Error: In <= of (1 #C(1 1)) arguments should be of type real.
糟糕:应该进行检查是两个参数是否为 real 数字。幸运的是,有一个谓词realp
。因此min-2
的正确版本是:
(defun min-2 (a b)
(if (and (realp a) (realp b))
;; sanity check OK, so compare them
(if (<= a b)
a
b)
'error))