【问题标题】:Error in LISP - SYSTEM::%EXPAND-FORM: invalid form (40)LISP 中的错误 - SYSTEM::%EXPAND-FORM: 无效形式 (40)
【发布时间】:2013-12-08 19:30:05
【问题描述】:

我正在开发一个 Lisp 程序,其中包含读取框尺寸的代码,然后将它们从最短到最长排序(并将这些新长度中的每一个设置为新变量)。

当我尝试将文件加载到解释器中时,我收到以下错误:

 - SYSTEM::%EXPAND-FORM: invalid form (40)

假设这个错误源于我的代码的第 40 行,这里是第 34-45 行:

(defun get-box ()
    (let ((d1) (d2) (d3))
        (setf d1 (read))
        (setf d2 (read))
        (setf d3 (read))
        (list d1 d2 d3))
        (if (= -1 d1)
            (exit)
            (setf new-d1 (first (sort (d1 d2 d3)) #'<))
            (setf new-d2 (second (sort (d1 d2 d3)) #'<))
            (setf new-d3 (third (sort (d1 d2 d3)) #'<))
            (next-part-of-program (new-d1, new-d2, new-d3)))

此代码 sn-p 中的 if 语句在语法或语义上是否存在固有的错误? EXPAND-FORM 错误在 Lisp 中来自/意味着什么?

非常感谢任何帮助。谢谢!

【问题讨论】:

  • 这个(40)与行号无关。这意味着您的代码中的文字 40 位于不适当的位置,或者您用逗号评估的变量评估为 40。
  • 哇,这肯定会改变一些事情。谢谢;我将在我的程序开始时进行调查,因为我确实将一些变量设置为值 40。
  • 非常感谢您指出这一点。我发现我的错误来自没有初始化我设置为 40 的变量。再次感谢!!
  • 这与other question 中的代码存在相同的问题(如果不是其他问题),(sort (d1 d2 d3)) 将是一个错误,因为d1 可能不是函数,而@987654329 @ 有一堆不属于的逗号(逗号?)。
  • if 最多有三个参数,一个条件、一个 then-part 和一个(可选)else-part。你的if 有一大堆。另请注意,您可以将(setf w x) (setf y z) 组合成(setf w x y z)

标签: if-statement functional-programming lisp common-lisp clisp


【解决方案1】:

if 只能有一个 single 表达式作为结果,而一个单一的表达式用于替代(“else”部分)。如果您需要编写多个表达式,请将它们打包在progn 中。我相信这就是您的意图:

(if (= d1 -1) ; condition. It's bad style to write Yoda conditions!
    (exit) ; consequent
    (progn ; alternative
     …))

另外,请注意,此行末尾似乎有一个放错位置的括号:

(list d1 d2 d3))

... 反正上面这行什么都没做,你直接删掉就行了。这部分也是错误的:

(sort (d1 d2 d3)) #'<)

应该是:

(sort (list d1 d2 d3) #'<)

在这里,逗号是错误的:

(new-d1, new-d2, new-d3)

另外,在这一行中,变量应该有一个初始值,你还应该声明new-d1new-d2new-d3

(let ((d1) (d2) (d3))

所有修复都到位后,代码应该是这样的:

(defun get-box ()
  (let ((d1 0) (d2 0) (d3 0) (new-d1 0) (new-d2 0) (new-d3 0))
    (setf d1 (read))
    (setf d2 (read))
    (setf d3 (read))
    (if (= d1 -1)
        (exit)
        (progn
          (setf new-d1 (first  (sort (list d1 d2 d3) #'<)))
          (setf new-d2 (second (sort (list d1 d2 d3) #'<)))
          (setf new-d3 (third  (sort (list d1 d2 d3) #'<)))
          (next-part-of-program new-d1 new-d2 new-d3)))))

【讨论】:

  • @user1462294 对吗?我不确定(exit) 部分是否应该仅在(= -1 d1) 或始终执行时才执行。您可以看到您的代码错误的原因,无法判断结果从哪里开始以及替代从哪里开始!
  • 感谢您的意见!你是对的 exit 应该只在 d1=-1 时发生...但是,我尝试使用 progn 并且在第 40 行我得到了相同的 EXPAND-FORM 错误。还有什么 EXPAND-FORM 错误可能会在这个if 声明中指出?
  • @user1462294 也是,我相信这行末尾有一个错误的右括号:(list d1 d2 d3))。删除它,并确保正确关闭其他括号
  • @user1462294 并且在您排序的部分还有另一个错误,这不是您构建列表的方式!查看我更新的代码
  • @user1462294 很遗憾,语法错误不断出现 :( 这次我检查了我的编译器,再次查看我重新更新的答案。我希望这个值得接受 ;)
【解决方案2】:

当您看到在"SYS" 包中提到符号的消息(在不同的实现中也称为"SI""SYSTEM"),尤其是当符号是内部的(以两个冒号为前缀),而且,它们的名称包含非字母数字字符(例如,%$),此消息可能是特定于实现的,您将通过提及您正在使用的实现来帮助我们帮助您。

也就是说,我认为您使用的是CLISP,在这种情况下,40 不会在您的文件中命名一行。

您的文件中的一个不适当的位置有一个文字 40,或者您有一个值为 40 的变量,您在宏展开期间用一个放错位置的逗号对其进行评估。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 2011-02-22
    • 1970-01-01
    相关资源
    最近更新 更多