SBCL 中的生物医学信息学原理:这个 let 有什么问题?
Principles of Biomedical Informatics in SBCL: what's wrong with this let?
这里是 Lisp 新手,倾向于相信我肯定误解了一些东西,因为这是第二版相当长的书的第 35 页的问题。我一直在阅读 let
绑定,所以让我通过引用他来确保作者的*意图是明确的:
In the following code, the symbol pos
serves as a temporary storage
or variable that has as its value the result of the position
function expression. Finally, how will we accumulate the results? The recursive call should give us a list of the remaining positions, so the first one found should just be put on the front. We already have a function to do this, the cons
function
这是代码:
(defun all-pos (item seq start)
(let ((pos (position item seq :start start))
(if pos
(cons pos
(all-pos item seq (+ 1 pos)))
nil))))
这是错误:
Ch1_Notes.lisp:27:5:
error:
The LET binding spec (IF POS
(CONS POS (ALL-POS ITEM SEQ (+ 1 POS)))
NIL) is malformed.
Compilation failed.
这是不言而喻的错误吗?我还应该包括一些前面的代码吗?
*作者 Ira J. Kalet 已经去世,所以我不能问他。
您似乎遇到了不平衡的括号问题。一种查看方式是查看 NIL 之后的右括号。这将关闭 IF 语句。在那之后还有两个关闭的,它们将关闭 LET 和 DEFUN。但是,在那之后你还有一个。这就是导致问题的原因。
如果出现此类错误,重新缩进代码通常很有用。通常可以在编辑器中使用键盘命令来完成。
但 Lisp 还带有内置代码格式,称为 漂亮打印:
CL-USER > (let ((*print-right-margin* 60))
(pprint '
; your code follows:
(defun all-pos (item seq start)
(let ((pos (position item seq :start start))
(if pos
(cons pos
(all-pos item seq (+ 1 pos)))
nil))))
))
输出如下所示:
(DEFUN ALL-POS (ITEM SEQ START)
(LET ((POS (POSITION ITEM SEQ :START START))
(IF POS (CONS POS (ALL-POS ITEM SEQ (+ 1 POS)))
NIL))))
这样可以更容易地看出 if
与 pos
变量绑定处于同一缩进级别。 这不可能!
要使用 Lisp 格式化您的代码,您只需要:
(let ((*print-right-margin* 60))
(pprint '
; here goes your code
))
Lisp 会为您格式化...
正如我之前的回答者所提到的,一个简单的括号问题:
;; correct version:
(defun all-pos (item seq start)
(let ((pos (position item seq :start start)))
(if pos
(cons pos
(all-pos item seq (+ 1 pos)))
nil)))
;; e.g.
(all-pos '3 '(1 2 3 4 3 5 4) 0)
;; returns (2 4) - correctly
这里是 Lisp 新手,倾向于相信我肯定误解了一些东西,因为这是第二版相当长的书的第 35 页的问题。我一直在阅读 let
绑定,所以让我通过引用他来确保作者的*意图是明确的:
In the following code, the symbol
pos
serves as a temporary storage or variable that has as its value the result of theposition
function expression. Finally, how will we accumulate the results? The recursive call should give us a list of the remaining positions, so the first one found should just be put on the front. We already have a function to do this, thecons
function
这是代码:
(defun all-pos (item seq start)
(let ((pos (position item seq :start start))
(if pos
(cons pos
(all-pos item seq (+ 1 pos)))
nil))))
这是错误:
Ch1_Notes.lisp:27:5:
error:
The LET binding spec (IF POS
(CONS POS (ALL-POS ITEM SEQ (+ 1 POS)))
NIL) is malformed.
Compilation failed.
这是不言而喻的错误吗?我还应该包括一些前面的代码吗?
*作者 Ira J. Kalet 已经去世,所以我不能问他。
您似乎遇到了不平衡的括号问题。一种查看方式是查看 NIL 之后的右括号。这将关闭 IF 语句。在那之后还有两个关闭的,它们将关闭 LET 和 DEFUN。但是,在那之后你还有一个。这就是导致问题的原因。
如果出现此类错误,重新缩进代码通常很有用。通常可以在编辑器中使用键盘命令来完成。
但 Lisp 还带有内置代码格式,称为 漂亮打印:
CL-USER > (let ((*print-right-margin* 60))
(pprint '
; your code follows:
(defun all-pos (item seq start)
(let ((pos (position item seq :start start))
(if pos
(cons pos
(all-pos item seq (+ 1 pos)))
nil))))
))
输出如下所示:
(DEFUN ALL-POS (ITEM SEQ START)
(LET ((POS (POSITION ITEM SEQ :START START))
(IF POS (CONS POS (ALL-POS ITEM SEQ (+ 1 POS)))
NIL))))
这样可以更容易地看出 if
与 pos
变量绑定处于同一缩进级别。 这不可能!
要使用 Lisp 格式化您的代码,您只需要:
(let ((*print-right-margin* 60))
(pprint '
; here goes your code
))
Lisp 会为您格式化...
正如我之前的回答者所提到的,一个简单的括号问题:
;; correct version:
(defun all-pos (item seq start)
(let ((pos (position item seq :start start)))
(if pos
(cons pos
(all-pos item seq (+ 1 pos)))
nil)))
;; e.g.
(all-pos '3 '(1 2 3 4 3 5 4) 0)
;; returns (2 4) - correctly