Lisp土地的例子是什么?

我已经阅读了很多关于Land of Lisp的好东西,所以我想我可以通过它来看看有什么可看的。
(defun tweak-text (lst caps lit)
  (when lst
    (let ((item (car lst))
      (rest (cdr lst)))
      (cond 
       ; If item = space, then call recursively starting with ret
       ; Then, prepend the space on to the result.
       ((eq item #space) (cons item (tweak-text rest caps lit)))
       ; if the item is an exclamation point.  Make sure that the
       ; next non-space is capitalized.
       ((member item '(#! #? #.)) (cons item (tweak-text rest t lit)))
       ; if item = " then toggle whether we are in literal mode
       ((eq item #") (tweak-text rest caps (not lit)))
       ; if literal mode, just add the item as is and continue
       (lit (cons item (tweak-text rest nil lit)))
       ; if either caps or literal mode = true capitalize it?
       ((or caps lit) (cons (char-upcase item) (tweak-text rest nil lit)))
       ; otherwise lower-case it.
       (t (cons (char-downcase item) (tweak-text rest nil nil)))))))
(评论是我的) (仅供参考 - 方法签名为
(list-of-symbols bool-whether-to-caps bool-whether-to-treat-literally)
但作者将这些缩写为
(lst caps lit)
。) 但无论如何,这是一个问题: 这里有
(cond... (lit ...) ((or caps lit) ...))
。我的理解是,这将在C风格语法中转换为
if(lit){ ... } else if(caps || lit){...}
。这个或陈述不是多余的吗?如果上限是
nil
,是否有条件会调用
(or caps lit)
条件?     
已邀请:
的确,你是对的。请参阅本书的勘误表。   页面97:函数tweak-text有两个故障,虽然它在大多数Lisp实现上运行正常。首先,它使用eq函数来比较字符 - 应始终使用其他函数检查字符,例如根据ANSI规范的eql或char-equal。此外,还有一个不必要的检查(或上限)可以简化为上限。     
我会把它写成:
(defun tweak-text (list caps lit)
  (when list
    (destructuring-bind (item . rest) list
      (case item
        ((#space)             (cons item (tweak-text rest caps lit)))
        ((#! #? #.)         (cons item (tweak-text rest t    lit)))
        ((#")                 (tweak-text rest caps (not lit)))
        (otherwise (cond (lit  (cons item (tweak-text rest nil  lit)))
                         (caps (cons (char-upcase item)
                                     (tweak-text rest nil lit)))
                         (t    (cons (char-downcase item)
                                     (tweak-text rest nil nil)))))))))
CASE语句将调度该角色。然后COND声明处理其他条件。 CASE与EQL进行比较。这意味着CASE也适用于角色,甚至可以与多个项目进行比较。我也是代码布局样式的粉丝,它排列了相应的表达式 - 这仅适用于等宽字体。这有助于我在代码中直观地检测模式,并帮助检测可以简化的代码。 DESTRUCTURING-BIND将列表分开。 为了好玩,使用LOOP重写:
(defun tweak-text (list)
  (loop with caps and lit

        for item in list

        when (eql item #space)
        collect item

        else when (member item '(#! #? #.))
        collect item and do (setf caps t)

        else when (eql item #")
        do (setf lit (not lit))

        else when lit
        collect item and do (setf caps nil)

        else when caps
        collect (char-upcase item) and do (setf caps nil)

        else
        collect (char-downcase item) and
        do (setf caps nil lit nil)))
    

要回复问题请先登录注册