【问题标题】:Is using do* without a body expression considered a bad practice in Common Lisp?在 Common Lisp 中使用不带正文表达式的 do* 是否被认为是一种不好的做法?
【发布时间】:2021-09-26 04:22:54
【问题描述】:

我正在尝试通过Common Lisp:符号计算的简单介绍这本书来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。

在第 11 章中,作者介绍了用于迭代的do* 函数。之前,本书展示了do 函数的模板:

(DO ((var1 init1 [update1])
     (var2 init2 [update2])
     ...)
    (test action-1 ... action-n)
 body)

本书没有显示do* 的模板。可能是因为它是相同的,尽管dodo* 之间存在差异。

在练习 11.11 中,本书要求:

11.11 Rewrite the following function to use DO* instead of DOLIST.

(defun find-largest (list-of-numbers)
  (let ((largest (first list-of-numbers)))
    (dolist (element (rest list-of-numbers)
                     largest)
      (when (> element largest)
        (setf largest element)))))

这是答卷中的实现:

(defun do*-find-largest-answer-sheet (list-of-numbers)
  (do* ((largest (first list-of-numbers))
        (z (rest list-of-numbers) (rest z))
        (element (first z) (first z)))
       ((null z) largest)
    (when (> element largest)
      (setf largest element))))

我的实现返回正确的结果,但风格不同:

(defun do*-find-largest (list-of-numbers)
  (do* ((x list-of-numbers (rest x))
        (e (first x) (first x))
        (largest (car list-of-numbers) (if (> e largest) e largest)))
       ((null (rest x)) (return largest))))

如您所见,与书中的答案不同,我在通常为身体表达保留的空间中使用任何东西。另外,我在局部变量更新中插入了条件表达式。我喜欢我的方法更短的事实。

我的方法在 Common Lisp 中会被认为是一种不好的风格或不好的做法吗?可以接受吗?

既然“你不知道你不知道什么”,那么我的实现有什么我不知道的缺点吗?

【问题讨论】:

  • 你不需要调用return

标签: iteration common-lisp


【解决方案1】:

编写没有正文的do* 循环没有任何问题。 这是一个替代版本:

(defun do*-find-largest (list-of-numbers)
  (do* ((x list-of-numbers (cdr x))
        (largest (car x) (max largest (car x))))
       ((null (cdr x)) largest)))

【讨论】:

    【解决方案2】:

    一般来说,这不被认为是不好的做法。但是,您应该避免仅仅因为您不想要 do(*) 主体而过于复杂的更新和结束测试。

    【讨论】:

      猜你喜欢
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 2013-04-12
      • 2017-12-18
      相关资源
      最近更新 更多