Clojure有没有类似于Mathematica的母猪/收获的功能?

时间:2013-11-13 20:40:15

标签: clojure clojure-contrib

Clojure中是否有函数模仿Mathemaica函数播种/收获?母猪和母猪的主要用途是收集在评估过程中产生的表达。

实施例)

在Mathematica中输入:收获[母猪[w = 2]; w + =母猪[w ^ 3]; w = Sqrt [w + w ^ 3]]

输出:{Sqrt [1010],{{2,8}}}

给出中间结果2和8。

1 个答案:

答案 0 :(得分:10)

像clojure这样的homoiconic语言的精彩之处在于你可以根据需要定义新的语法。

(defmacro reap
  [& body]
  `(let [state# (atom [])
         ~'sow (fn sow [v#] (swap! state# conj v#) v#)]
     [(do ~@body) @state#]))

为简单起见,我使用jvm interop进行数学运算,而不是使用clojure.numeric-tower,因此我们得到浮点而不是精确输出:

user> (reap (let [w (sow 2)
                  w (+ w (sow (Math/pow w 3)))
                  w (Math/sqrt (+ w (Math/pow w 3)))]
              w))

[31.78049716414141 [2 8.0]]
user> (= 31.78049716414141 (Math/sqrt 1010))
true

编辑:既然我看到了母猪的文档,它也支持标记和按标记选择

因为这是clojure按键抓取东西是微不足道的,所以我只会显示一个变量来制作标签:

(defmacro reap
  [& body]
  `(let [state# (atom {})
         ~'sew (fn sew [& [v# tag#]]
                 (swap! state# #(update-in % [tag#] conj v#)) v#)]
     [(do ~@body) @state#]))

user> (reap (let [w (sew 2 :a)
            w (+ w (sew (Math/pow w 3)))
            w (Math/sqrt (+ w (Math/pow w 3)))]
        w))

[31.78049716414141 {nil (8.0), :a (2)}]