Conad Barski的lisp函数的条件是多余的?

时间:2016-05-12 00:23:01

标签: lisp common-lisp

这个问题与Conrad Barski的书的第6章代码Land of Lisp有关。

代码如下

(defun tweak-text (lst caps lit)
  (when lst
    (let ((item (car lst))
          (rest (cdr lst)))
      (cond ((eq item #\space) (cons item (tweak-text rest caps lit)))
            ((member item '(#\! #\? #\.)) (cons item (tweak-text rest t lit)))
            ((eq item #\") (tweak-text rest caps (not lit)))
            (lit (cons item (tweak-text rest nil lit)))
            ((or caps lit) (cons (char-upcase item) (tweak-text rest nil lit)))
            (t (cons (char-downcase item) (tweak-text rest nil nil)))))))

现在查看(lit ..)部分及其下方的内容.. ((or caps nil) ..),所以我的问题如下

  • 如果lit为真,则将在前面的表达式
  • 中进行评估
  • 如果不成立,后一个表达将始终评估为(or caps false) => (or caps false)这几乎没用?

所以后一个表达式不应该只是(caps (cons (char ...))吗?

这本书已被数以千计阅读,所以我一定是错的,我不是约翰贝尔。

2 个答案:

答案 0 :(得分:8)

是的,更简单的表达方式是等效的。在第97页勘误表http://landoflisp.com/errata.html

中提到了它

答案 1 :(得分:2)

其中一个问题是使用递归,它限制了函数能够处理的列表的长度。

(defun tweak-text (list &aux (caps t) (lit nil))
  (mapcon (lambda (c)
            (case c
              (#\space (list c))
              ((#\! #\? #\.)
               (setf caps t)
               (list c))
              (#\"
               (setf lit (not lit))
               ())
              (otherwise
               (cond (lit (setf caps nil) (list c))
                     (caps (setf caps nil) (list (char-upcase c)))
                     (t (setf caps nil lit nil)
                        (list (char-downcase c)))))))
          list))