Clojure:使用for定义forv宏

时间:2016-09-06 15:15:54

标签: clojure macros

我正在尝试编写第二个宏,但我完全被困在这里。

我想避免每次(vec (for [...]))写作,所以我试图写一个forv宏,如filterv,mapv等。 我主要使用我的程序中的向量,因为我需要访问索引,因为我使用外部缓冲区/描述符来固定矩阵进程。 我写了很多类似函数的函数(也是像fmap这样的自适应函数),但我很喜欢。

所以我写了

(defmacro forv
  [seq-exprs body-expr]
  (vec (for (vec seq-exprs) body-expr)))

我单独尝试使用seq-exprs,但它不起作用。说实话,我也试过〜等等但我不知道它是如何工作的,我在第一个宏中取得成功因为它更容易。

Clojure告诉我,因为需要一个载体进行绑定。

有人可以帮助我并解释我缺少的东西吗?谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用构建的into the Tupelo Library。源代码在这里:https://github.com/cloojure/tupelo/blob/master/src/tupelo/core.cljc#L181

(defmacro forv
  "Like clojure.core/for but returns results in a vector.  Equivalent to (into [] (for ...)). Not
   lazy."
  [& body]
  `(vec (for ~@body)))

答案 1 :(得分:0)

;;
;; you want something like that in the end: (forv [x (range 2)] x)  => (vec (for [x (range 2)] x))
;;

(defmacro forv
  [seq-exprs body-expr]
  `(vec (for [~@seq-exprs] ~body-expr)))
;;
;; check quote and unquote
;; in particular, check the tricky bit is https://clojuredocs.org/clojure.core/unquote-splicing
;;

编辑:我的答案基于模仿问题中的原始代码,但艾伦的回答比我的好。