clojure使用线程宏来表示方程式

时间:2015-02-10 13:20:50

标签: clojure

我在java中有这个等式,我想将其翻译成clojure:

limit = (int)(n*(Math.log(n) + Math.log(Math.log(n)))) + 3;

我想避免它变成嵌套括号的海洋,在clojure中使这个可读的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

您可以使用let表格将公式分解为更简单的部分:

(defn calc-limit [n]
  (let [log (Math/log n)
        loglog (Math/log log)
        logsum (+ log loglog)]
    (-> n (* logsum) int (+ 3))))

(calc-limit 256) ; => 1861

答案 1 :(得分:2)

我必须同意其他答案,let带有一些描述性名称更具启发性。但是如果你想只使用线程宏来实现它,可以使用ìterate

(defn calc-limit [n]
      (->> n
           (iterate #(Math/log %))
           (drop 1) ;;The first value is just n, with no logarithms applied
           (take 2) ;;Taking the 1st and 2nd iterations of Math/log on n
           (reduce +)
           (* n)
           int
           (+ 3)))

答案 2 :(得分:2)

你也可以使用Graph,特别是如果你的公式会变大,而且速度不是很大的问题:

(use 'plumbing.core)
(require '[plumbing.graph :as graph])

(def limit-graph
  {:log    (fnk [n]  (Math/log n))
   :loglog (fnk [log] (Math/log log))
   :logsum (fnk [log loglog] (+ log loglog))
   :limit  (fnk [n logsum] (-> logsum (* n) int (+ 3)))})

(def calc-limit (graph/compile limit-graph))

(:limit (calc-limit {:n 5}))

答案 3 :(得分:1)

你在问题​​的标题中提到了线程宏,所以我将提供一个主要关注的变体,使用let来避免计算(Math/log n)两次:

(let [x (Math/log n)]
  (-> (Math/log x)
      (+ x)
      (* n)
      (int)
      (+ 3)))

旁注:在

时使用let是有意义的
  • 你的价值必须多次使用,
  • 您希望通过明确命名中间结果来提高可理解性,或者
  • 您希望通过将问题分成更小的部分来提高可读性。