lisp - 普通口齿不清 : unable to get the uncompress function in Paul Graham's book working

标签 lisp common-lisp

这里是 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))))

最佳答案

如果使用编辑器缩进工具,代码如下所示:

(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 中,IFLET 都是具有内置语法的特殊运算符

在 Lisp 中,LET 的语法通常是:

let ({var | (var [init-form])}*) form* => result*

在 Common Lisp 中,可以在 LET 的主体形式之上添加声明:

let ({var | (var [init-form])}*) declaration* form* => result*

IF 在 Common Lisp 中的语法是:

if test-form then-form [else-form] => result*

缩进

通常手动缩进 Lisp 代码不是一个好主意。让编辑器或IDE来做吧。确保所有代码都正确缩进。

如果您遇到语法问题:首先重新缩进表达式 -> 这可确保代码正确缩进,然后更容易发现问题。接下来编译代码并阅读编译器错误消息。 Common Lisp 有很棒的编译器,有些编译器有很好的错误报告。

代码

无论如何代码都不是很好:它在存在高阶函数或循环会更好的地方使用递归

这个版本同时拥有:高阶 MAPCANLOOP:

(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 - 普通口齿不清 : unable to get the uncompress function in Paul Graham's book working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32363409/

相关文章:

lisp - 成员和默认参数

lisp - 获取字符串而不是数字

scheme - Racket - 需要整个目录的文件

macros - Franz LISP 到 Common LISP 的转换 2 - 生成宏的宏

function - SBCL 时间函数返回什么?

deployment - 使用 asdf 我可以加载仅提供以前制作的 FASL 的系统吗

python - 相当于 python 习语的常见 lisp

loops - 从循环内的格式返回

emacs - 如何在 LispBox 中调试 LISP 编译器错误?

lisp - 函数错误地返回 Nil