【问题标题】:Breaking a function into multiple lines将一个函数分成多行
【发布时间】:2010-11-18 01:36:47
【问题描述】:

以下是令人惊叹的《Land of Lisp》一书中的示例源代码:

(defun random-node ()
  (1+ (random *node-num*)))

(defun edge-pair (a b)
  (unless (eql a b)
     (list (cons a b) (cons b a))))

(defun make-edge-list ()
    (apply #'append (loop repeat *edge-num*
                          collect (edge-pair (random-node) (random-node)))))

由于我没有 Lisp 直觉,我发现将方法分成多行(作为命令式样式)然后尝试将其变形为函数式样式很有用。

你能帮我把 make-edge-list 函数分成多行吗?

【问题讨论】:

  • 至少用 let 表达式替换表达式的组成部分可能会有所帮助。我不确定您在这里使用的确切方言,但您应该能够将其分解为至少更具描述性的形式,例如(defun make-edge-list () (let ((pair (edge-pair (random-node) (random-node))) (... 等。如果您不熟悉,请查找 let 绑定以获取更多信息。
  • 我是否遗漏了什么——是否有理由首先分两步进行?这和(loop repeat *edge-num* append (edge-pair (random-node) (random-nome))) 有区别吗?

标签: functional-programming lisp land-of-lisp


【解决方案1】:

在 Lisp 中,行是没有意义的。 Lisp 表示法基于 s 表达式,并且在评估期间 Lisp 看不到文本行。您可以在空格上以任何方式拆分表达式。​​

(defun make-edge-list ()
   (apply #'append
          (loop repeat *edge-num*
                collect (edge-pair (random-node)
                                    (random-node)))))

你必须像这样阅读代码:

  • 每个边对都是一个 conses 列表。每个 cons 存储一个位置。
  • 循环返回边对列表。
  • 然后将 append 应用于此列表并返回 conses 列表。 conses 列表实际上是一个位置列表。

注意该函数有几个小问题:

  • APPLY 不适用于任意长度的列表。所以希望这份名单不会太长。

  • 更重要的是,如果我们稍微改变一下 LOOP,就不需要应用 APPEND 函数。 LOOP不仅可以COLLECT,还可以APPEND。

【讨论】:

  • 我想把方法分解成命令式,就像 Arlen 之前建议的那样。
  • 如果您想以命令式风格编写代码,您可能需要使用不同的编程语言。在上面的函数中它没有什么意义......
  • 请阅读我的原帖:“由于我没有 Lisp 的本能,我发现将一个方法分成多行(作为一种命令式风格)然后尝试将其变形为实用风格。”
猜你喜欢
  • 1970-01-01
  • 2021-11-04
  • 2023-01-12
  • 2020-11-19
  • 1970-01-01
  • 2015-12-08
  • 2013-06-11
  • 2016-03-14
相关资源
最近更新 更多