1

我正在阅读 Paul Graham 的On Lisp,并尝试在 Emacs Lisp 中实现这些功能。其中之一是扁平化:

(flatten '(a (b c) ((d e) f)))
;; Returns:
(a b c d e f)

然而由于某种原因,Paul Graham 给出的实现在 Emacs Lisp 上不起作用(总是返回 nil):

(defun flatten (x)
  (cl-labels ((rec (x acc))
              (cond ((null x) acc)
                    ((atom x) (cons x acc))
                    (t (rec (car x) (rec (cdr x) acc)))))
             (rec x nil)))

(flatten '(1 (3)))
;; Returns:
nil

和ELisp的动态绑定有关系吗?这段代码有什么问题?

4

1 回答 1

1

正如我在对该问题的评论中指出的那样,问题是括号放错了。定义应该是:

(defun flatten (x)
  (cl-labels ((rec (x acc)
                   (cond ((null x) acc)
                         ((atom x) (cons x acc))
                         (t (rec (car x) (rec (cdr x) acc))))))
    (rec x nil)))

在原文中,((rec (x acc))定义rec为返回的函数nil。通过将其更改((rec (x acc)cond表达式成为 的主体rec,然后通过在 的t子句后添加右括号再次平衡括号后cond,该flatten函数按预期工作:

(flatten '(1 (3)))
(1 3)
于 2019-06-23T21:04:25.980 回答