我正在研究一个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)))
在此代码段中,我的if
语句在语法或语义上是否存在任何内在错误? EXPAND-FORM
错误来自/表示Lisp是什么意思?
非常感谢任何帮助。谢谢!
答案 0 :(得分:3)
if
只能为结果提供单表达式,而对于备选项(“其他”部分)则只有一个单个表达式。如果您需要编写多个表达式,请将它们打包在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-d1
,new-d2
和new-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)))))
答案 1 :(得分:3)
当您在"SYS"
包中看到提及符号的消息时(在不同的实现中也称为"SI"
和"SYSTEM"
),特别是当符号是内部的时(以两个冒号为前缀) ,此外,它们的名称包含非字母数字字符(例如%
或$
),此消息可能是特定于实现的,您可以通过提及您的实现来帮助我们使用
也就是说,我认为您使用的是CLISP
,在这种情况下,此40
不在您的文件中命名一行。
您在文件中的不适当位置有文字40
,或者您有一个值40
的变量,您在宏展开期间使用错误的逗号评估该值。