【问题标题】:Where can I place the print function inside a loop/recur in Clojure?我在哪里可以将打印函数放在 Clojure 中的循环/递归中?
【发布时间】:2017-08-14 14:25:49
【问题描述】:

Clojure 和函数式编程入门。查看尚未出版的 Clojure 编程书第三版第 10 章中在一个范围内添加数字的慢速示例。

如何在这个循环中添加一个 println 以便我可以看到 sum 的值变化?

; performance demo only, don't write code like this 
(defn sum-to [n]
  (loop [i 1 sum 0]
    (if (<= i n)
      (recur (inc i) (+ i sum))
      sum)))

【问题讨论】:

    标签: recursion clojure


    【解决方案1】:

    loop 宏接受多个主体表达式,因此您可以在 if 表达式之前插入一个有副作用的 println 表达式:

    (defn sum-to [n]
      (loop [i 1 sum 0]
        (println sum)
        (if (<= i n)
          (recur (inc i) (+ i sum)) sum)))
    

    这里 Clojure 将使用正文中最后一个表达式的结果作为整个 loop 表达式的返回值。示例:

    (sum-to 5)
    ;; 0
    ;; 1
    ;; 3
    ;; 6
    ;; 10
    ;; 15
    ;;=> 15
    

    【讨论】:

      【解决方案2】:

      在我看来,另一个方便的工具也可以解决您的问题,但以更简洁的方式而不是打印方式是跟踪。在调试时非常有用。

      (use 'clojure.tools.trace)
      
        (defn sum-to
        [n]
        (loop [i 1 sum 0]
          (if (<= i n)
            (recur (inc i) (trace (+ i sum))) sum)))
      
      (sum-to 10)
      TRACE: 1
      TRACE: 3
      TRACE: 6
      TRACE: 10
      TRACE: 15
      TRACE: 21
      TRACE: 28
      TRACE: 36
      TRACE: 45
      TRACE: 55
      55
      

      【讨论】:

      • 谢谢。在寻找解决方案时,我发现许多这样的工具和编写自己工具的人。我的印象是没有社区同意的工具。我决定暂时忍受打印,直到我知道足以评估其他解决方案。在任何其他语言中,我都使用日志包。我真的很喜欢这种跟踪不需要更改代码,但我的部分目标是知道将它放在哪里。
      【解决方案3】:

      不是你的问题的答案,但是

        (reductions + (range 6))
      

      为您提供所需的内容。

      【讨论】:

      • 是的,请参阅我的代码示例中的注释“不要这样编写代码”书中的首选示例是:(defn best-sum-to [n] (/ (* n (公司 n)) 2))
      【解决方案4】:

      为此我经常使用的一个方便的工具是spyxfrom the Tupelo library

      它是这样工作的:

      (ns tst.demo.core
        (:use demo.core tupelo.test)
        (:require
          [tupelo.core :as t] ))
      (t/refer-tupelo)
      
      (defn sum-to [n]
        (loop [i 1 sum 0]
          (if (<= i n)
            (recur (inc i) (spyx (+ i sum)))
            sum)))
      
      (spyx (sum-to 5))
      

      结果:

      (+ i sum) => 1
      (+ i sum) => 3
      (+ i sum) => 6
      (+ i sum) => 10
      (+ i sum) => 15
      
      (sum-to 5) => 15
      

      【讨论】:

      • 我会将 Tupelo 列入我的评估工具列表
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-31
      • 2022-07-06
      • 1970-01-01
      • 2021-11-16
      • 2016-03-06
      • 1970-01-01
      • 2012-05-15
      相关资源
      最近更新 更多