Lisp 示例冗余?

发布于 2024-10-10 03:34:44 字数 1530 浏览 0 评论 0原文

我读过很多关于 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点燃)。)

但无论如何,问题是:
其中有 (cond... (lit ...) ((or caps lit) ...)) 。我的理解是,这将转换为 C 风格语法中的 if(lit){ ... } else if(caps || lit){...} 。那么 or 语句不是多余的吗?如果 caps 为 nil,是否存在调用 (或 caps lit) 条件的情况?

I've read a lot of good things about Land of Lisp so I thought that I might go through it to see what there was to see.

(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)))))))

(the comments are mine)
(FYI -- the method signature is (list-of-symbols bool-whether-to-caps bool-whether-to-treat-literally) but the author shortened these to (lst caps lit).)

But anyway, here's the question:
This has (cond... (lit ...) ((or caps lit) ...)) in it. My understanding is that this would translate to if(lit){ ... } else if(caps || lit){...} in a C style syntax. Isn't the or statement redundant then? Is there ever a condition where the (or caps lit) condition will be called if caps is nil?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

几味少女 2024-10-17 03:34:44

确实,你是对的。请参阅本书的勘误表

第 97 页:tweak-text 函数有两个小故障,尽管它在大多数 Lisp 实现上都可以正常运行。首先,它使用 eq 函数来比较字符 - 应始终根据 ANSI 规范使用 eql 或 char-equal 等其他函数检查字符。此外,还有不必要的检查(或大写字母点亮),可以简化为大写字母。

Indeed, you are correct. See the errata for the book.

Page 97: The function tweak-text has two glitches in it, though it will run OK on most Lisp implementations. First of all, it uses the eq function to compare characters- Characters should always be checked with other functions such as eql or char-equal as per the ANSI spec. Also, there's an unnecessary check of (or caps lit) that can be simplified to caps.

森林很绿却致人迷途 2024-10-17 03:34:44

我将其写为:

(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 也适用于角色,甚至可以与多个项目进行比较。我也喜欢排列相应表达式的代码布局样式 - 这仅对等宽字体有用。这有助于我直观地检测代码中的模式,并有助于检测可以简化的代码。

DESTRCTURING-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)))

I would write that as:

(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)))))))))

The CASE statement dispatches on the character. The COND statement then takes care of the other conditions. CASE compares with EQL. That means CASE works for also for characters and even can compare with multiple items. I'm also a fan of a code layout style that lines up corresponding expressions - this is only useful with monospaced fonts. This helps me to detect patterns visually in the code and helps detecting code that can be simplified.

DESTRUCTURING-BIND takes the list apart.

For fun, rewritten using 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)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文