syntax-error - 为什么这个简单的LISP函数会引发错误?

标签 syntax-error lisp common-lisp clisp

我从一个较大的脚本中隔离了此函数,并通过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 parenthesissyntax 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/

相关文章:

syntax-error - php 7 支持按引用传递吗?

C解析器递归

string - LISP- 从字符串中删除元音

lisp - 如何使用不对称(未配对)的任意括号创建宏

sql - 数据资源管理器中的语法错误

gdb - Shellcode在gdb中提供SyntaxError

list - 从列表 LISP 中删除 NIL

documentation - 如何在 Common Lisp REPL 中查看文档字符串和其他符号信息?

lisp - 剪辑 : variable has no value

php - 如何修复 Wordpress 博客中主题的语法错误