我从一个较大的脚本中隔离了此函数,并通过https://www.jdoodle.com/execute-clisp-online/运行了它。即使抛出错误,除非我遗漏了一些显而易见的内容,否则它似乎仍然遵循LISP的规则。
(defun cannibals-can-eat (state start-state)
(let ((left-bank-missionaries 2)
(left-bank-cannibals 5)
(right-bank-missionaries (- 3 left-bank-missionaries))
(right-bank-cannibals (- 2 left-bank-cannibals)))
(if (or (> left-bank-cannibals left-bank-missionaries)
(> right-bank-cannibals right-bank-missionaries))
t
nil)))
错误有时是
The variable LEFT-BANK-MISSIONARIES is unbound.unmatched close parenthesis
或syntax error near unexpected token
('`。使用此版本的函数时,错误是后者。
最佳答案
在Common Lisp中,有两种形式的本地声明(let
):
(let ((var1 exp1)
(var2 exp2)
...
(varn expn))
exp)
和
(let* ((var1 exp1)
(var2 exp2)
...
(varn expn))
exp)
首先,在
expi
之前的环境中评估每个表达式let
。在第二个中,在包含所有先前声明expi
的环境中评估每个表达式var1 ... var(i-1)
。因此,在您的示例中,
right-bank-missionaries
的声明使用了未定义的left-bank-missionaries
,因为它是在相同的let
中声明的。只需使用
let*
即可在声明每个变量后立即使用它:(defun cannibals-can-eat (state start-state)
(let* ((left-bank-missionaries 2)
(left-bank-cannibals 5)
(right-bank-missionaries (- 3 left-bank-missionaries))
(right-bank-cannibals (- 2 left-bank-cannibals)))
(or (> left-bank-cannibals left-bank-missionaries)
(> right-bank-cannibals right-bank-missionaries))))
请注意,如果您想返回generalized boolean,则最后的
if
是没有用的。
关于syntax-error - 为什么这个简单的LISP函数会引发错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59223589/