我正在研究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的动态绑定有关吗?此代码有什么问题?
答案 0 :(得分: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
子句之后添加右括号来再次平衡括号1}},cond
函数将按预期工作:
flatten