Common Lisp:无法使 Paul Graham 的书中的解压缩功能正常工作
Common Lisp: unable to get the uncompress function in Paul Graham's book working
这里是 Lisp 新手。
我正在阅读 Paul Graham 的书 ANSI Common Lisp。
第 38 页是一个 uncompress
函数。它需要一个成对列表,其中成对中的第一项是一个数字,表示应该有多少第二项。例如,解压这个:
((3 a) (2 b) c)
应该产生这个:
(A A A B B C)
我将 uncompress
函数输入到 Lisp 解释器 (GCL-2.6.2-ANSI) 中,然后像这样测试它:
(uncompress '((3 A) B (2 C) (5 D)))
产生此错误消息的原因:
Error in IF [or a callee]: Too many arguments.
Fast links are on: do (use-fast-links nil) for debugging
Broken at IF. Type :H for Help.
1 (Abort) Return to top level.
下面是uncompress
函数。我认为我忠实地打出了书中所写的内容。我已经测试了每一件,每一件似乎都能正常工作。说实话,我被卡住了。我不知道是什么导致了错误。非常感谢你的帮助。
(defun uncompress (lst)
(if (null lst)
nil
(let (elt (car lst))
(rest (uncompress (cdr lst))))
(if (consp elt)
(append (apply #'list-of elt)
rest)
(cons elt rest))))
(defun list-of (n elt)
(if (zerop n)
nil
(cons elt (list-of (- n 1) elt))))
你有最典型的常见 lisp 语法错误:括号的使用不正确!
这是正确的版本:
(defun uncompress (lst)
(if (null lst)
nil
(let ((elt (car lst))
(rest (uncompress (cdr lst))))
(if (consp elt)
(append (apply #'list-of elt)
rest)
(cons elt rest)))))
如果不使用专门的编辑器,此类错误很常见,我建议您使用 Emacs 或 Vim 等编辑器来编辑您的程序。
如果使用编辑器缩进工具,代码如下所示:
(defun uncompress (lst)
(if (null lst)
nil
(let (elt (car lst))
(rest (uncompress (cdr lst))))
(if (consp elt)
(append (apply #'list-of elt)
rest)
(cons elt rest))))
这样可以更容易地发现此错误。从句法上讲是错误的,因为 IF
不超过三种形式。
(defun uncompress (lst)
(if (null lst) ; the IF has four subforms, one too many
nil
(let (elt (car lst)) ;<- variables ELT and CAR? Makes no sense
(rest (uncompress (cdr lst)))) ; <- not using the result?
(if (consp elt) ; <- fourth form in IF? Does not make sense.
(append (apply #'list-of elt)
rest)
(cons elt rest))))
在 Common Lisp 中,IF
和 LET
都是具有内置语法的 特殊运算符 。
在 Lisp 中,LET
的语法通常是:
let ({var | (var [init-form])}*) form* => result*
在 Common Lisp 中,可以在 LET
:
的主体形式之上添加声明
let ({var | (var [init-form])}*) declaration* form* => result*
Common Lisp 中 IF
的语法是:
if test-form then-form [else-form] => result*
缩进
通常手动缩进 Lisp 代码不是一个好主意。让小编或者IDE去做吧。确保所有代码都正确缩进。
如果您遇到语法问题:首先重新缩进表达式 -> 这可确保代码正确缩进,然后更容易发现问题。接下来编译代码并阅读编译器错误消息。 Common Lisp 有很棒的编译器,有些有很好的错误报告。
代码
无论如何代码都不是很好:它在存在高阶函数的地方使用递归,否则循环会更好
这个版本同时获得了:高阶 MAPCAN
和 LOOP
:
(defun uncompress (list)
(mapcan #'expand-item list))
(defun expand-item (item)
(typecase item
(atom (list item))
(cons (destructuring-bind (n element) item
(loop repeat n collect element)))))
这里是 Lisp 新手。
我正在阅读 Paul Graham 的书 ANSI Common Lisp。
第 38 页是一个 uncompress
函数。它需要一个成对列表,其中成对中的第一项是一个数字,表示应该有多少第二项。例如,解压这个:
((3 a) (2 b) c)
应该产生这个:
(A A A B B C)
我将 uncompress
函数输入到 Lisp 解释器 (GCL-2.6.2-ANSI) 中,然后像这样测试它:
(uncompress '((3 A) B (2 C) (5 D)))
产生此错误消息的原因:
Error in IF [or a callee]: Too many arguments.
Fast links are on: do (use-fast-links nil) for debugging
Broken at IF. Type :H for Help.
1 (Abort) Return to top level.
下面是uncompress
函数。我认为我忠实地打出了书中所写的内容。我已经测试了每一件,每一件似乎都能正常工作。说实话,我被卡住了。我不知道是什么导致了错误。非常感谢你的帮助。
(defun uncompress (lst)
(if (null lst)
nil
(let (elt (car lst))
(rest (uncompress (cdr lst))))
(if (consp elt)
(append (apply #'list-of elt)
rest)
(cons elt rest))))
(defun list-of (n elt)
(if (zerop n)
nil
(cons elt (list-of (- n 1) elt))))
你有最典型的常见 lisp 语法错误:括号的使用不正确!
这是正确的版本:
(defun uncompress (lst)
(if (null lst)
nil
(let ((elt (car lst))
(rest (uncompress (cdr lst))))
(if (consp elt)
(append (apply #'list-of elt)
rest)
(cons elt rest)))))
如果不使用专门的编辑器,此类错误很常见,我建议您使用 Emacs 或 Vim 等编辑器来编辑您的程序。
如果使用编辑器缩进工具,代码如下所示:
(defun uncompress (lst)
(if (null lst)
nil
(let (elt (car lst))
(rest (uncompress (cdr lst))))
(if (consp elt)
(append (apply #'list-of elt)
rest)
(cons elt rest))))
这样可以更容易地发现此错误。从句法上讲是错误的,因为 IF
不超过三种形式。
(defun uncompress (lst)
(if (null lst) ; the IF has four subforms, one too many
nil
(let (elt (car lst)) ;<- variables ELT and CAR? Makes no sense
(rest (uncompress (cdr lst)))) ; <- not using the result?
(if (consp elt) ; <- fourth form in IF? Does not make sense.
(append (apply #'list-of elt)
rest)
(cons elt rest))))
在 Common Lisp 中,IF
和 LET
都是具有内置语法的 特殊运算符 。
在 Lisp 中,LET
的语法通常是:
let ({var | (var [init-form])}*) form* => result*
在 Common Lisp 中,可以在 LET
:
let ({var | (var [init-form])}*) declaration* form* => result*
Common Lisp 中 IF
的语法是:
if test-form then-form [else-form] => result*
缩进
通常手动缩进 Lisp 代码不是一个好主意。让小编或者IDE去做吧。确保所有代码都正确缩进。
如果您遇到语法问题:首先重新缩进表达式 -> 这可确保代码正确缩进,然后更容易发现问题。接下来编译代码并阅读编译器错误消息。 Common Lisp 有很棒的编译器,有些有很好的错误报告。
代码
无论如何代码都不是很好:它在存在高阶函数的地方使用递归,否则循环会更好
这个版本同时获得了:高阶 MAPCAN
和 LOOP
:
(defun uncompress (list)
(mapcan #'expand-item list))
(defun expand-item (item)
(typecase item
(atom (list item))
(cons (destructuring-bind (n element) item
(loop repeat n collect element)))))