macros - 从函数构建高阶函数的 Clojure 宏

标签 macros clojure

我正在尝试编写一个宏来构建类似于 compojure 中使用的中间件。

我希望能够调用:

(def-middleware plus-two [x]
  (+ 2 x))

结果如下:

(defn plus-two [f]
 (fn [x]
   (f (+ 2 x)))

我距离阅读在线指南还很远,但它对我来说不起作用:

(defmacro def-middleware [fn-name args & body]
  '(defn ~fn-name [f]
     (fn ~args
       (f ~@body))))

任何帮助或指向更好的宏编写指南的指针都会很棒,谢谢。

最佳答案

让我们看看macroexpand-1给了我们什么:

user=> (clojure.pprint/pprint (macroexpand-1 '(def-middleware plus-two [x] (+ 2 x))))
(defn
~fn-name
[f]
$
(fn ~args$ (f (clojure.core/unquote-splicing body))))

这不正是我们所追求的!首先,如果你想取消宏中的引用,你需要使用“`”(准引用/语法引用运算符),而不是“'”。另外,我不确定您对这些美元符号的追求是什么,但可能是您想要使用 clojure 的便捷快捷方式来使用 gensym 来保持卫生。但是,在每次使用它的标识符之后,您都需要立即使用它(因此 [f#],而不是 [f]$),并且每次出现标识符时都需要它。而且您不需要使用args。将所有这些放在一起:

user=> (defmacro def-middleware [fn-name args & body] `(defn ~fn-name [f#] (fn ~args (f# ~@body))))
#'user/def-middleware
user=> (clojure.pprint/pprint (macroexpand-1 '(def-middleware plus-two [x] (+ 2 x))))
(clojure.core/defn
 plus-two
 [f__594__auto__]
 (clojure.core/fn [x] (f__594__auto__ (+ 2 x))))
nil
user=> 

关于macros - 从函数构建高阶函数的 Clojure 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10986611/

相关文章:

c - 宏参数不会接受传递的参数(nvcc)

java - 同时测试 Clojure 和 Java

java - 如何使用 swing 和 clojure 制作动画?

c - 使用类 C 函数的宏作为函数别名

c - 将可变长度数组声明为宏

android - Cocos2d-x 项目中的宏

function - 在多个命名空间中使用记录

authentication - 如何让 Swagger UI 让我提供身份验证 header ?

Clojure:`和~@是什么意思?

c++ - 在 C++ 中定义带条件的宏