(doc - >)clojure的解释

时间:2014-04-08 16:11:12

标签: clojure

如果您运行(doc ->),则说:

clojure.core/->
([x] [x form] [x form & more])
Macro
  Threads the expr through the forms. Inserts x as the
  second item in the first form, making a list of it if it is not a
  list already. If there are more forms, inserts the first form as the
  second item in second form, etc.

我不明白为什么它说second item in the first form,那个背景下的first item是什么?

即使您运行(source ->)

(source ->)
(defmacro ->
   "Threads the expr through the forms. Inserts x as the
    second item in the first form, making a list of it if it is not a
    list already. If there are more forms, inserts the first form as the
    second item in second form, etc."
    {:added "1.0"}
    ([x] x)
    ([x form] (if (seq? form)
          (with-meta `(~(first form) ~x ~@(next form)) (meta form))
          (list form x)))
     ([x form & more] `(-> (-> ~x ~form) ~@more)))

x作为第一个参数传递给form,所以我在这里错过了什么,为什么文档会调用x second item

2 个答案:

答案 0 :(得分:1)

调用每个函数,并将先前函数的结果作为列表中的第二个函数传递。它将放在函数名称后面:

(third-function 
  (second-function 
    (first-function :initial-value :second-arg-to-first-function) 
    :second-arg-to-second-function) 
  :second-arg-to-third-function)
如果我们使用线程宏代替(并标记列表位置),

将转换为此:

 (-> :initial-value
     (first-function      :second-arg-to-first-function) 
     ;;    1          2               3          

     (second-function     :second-arg-to-second-function)
     ;;    1          2               3 

     (third-function      :second-arg-to-third-function))
     ;;    1          2               3

前一个函数的值由此宏放在位置2中。

有一个非常相似的宏as->(发音为" thread-as"),它为线程值提供了一个显式名称,有助于使转换更加清晰:

user> (as-> 4 x ;; x starts as 4
        (+ x 4) ;; and it's value in each call is the result of the previous
        (- x 2 1) 
        (* x x 2))
50

答案 1 :(得分:0)

形式的第二项是函数的第一个参数。

这是一个列表

的表格
(println "world")

评估语义是进行函数调用,其中列表的第一项是函数,其余的是参数。

但是宏观并没有评估他们的论点。我们可以通过引用来查看正在进行的事情来抑制评估。

(def foo '(println "world"))

(first foo) ;=> foo
(second foo) ;=> "world"

如果我们插入"你好"作为此表格中的第二项

(def bar `(~(first foo) "hello" ~@(rest foo)))
bar ;=> (clojure.core/println "hello" "world")

(-> "hello" (println "world"))
;=>hello world