如何在Clojure中的映射函数中的宏中获取嵌套参数? [英] How do I get the nested argument in a macro inside a mapped function in Clojure?

查看:110
本文介绍了如何在Clojure中的映射函数中的宏中获取嵌套参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我把我的宏传递给一个map操作。我有一些麻烦得到我的价值观。下面是一个例子:

 (def num-vec [1 2 3 4 5])

(doa1(map#(describe-args(+ 1))
$ b(doAn(arg) 42%))num-vec))

这会返回:

 (+ 42 p1__437#)= 43 
(+ 42 p1__437#)= 44
(+ 42 p1__437#)= 45
(+ 42 p1__437#)= 46
(+ 42 p1__437#)= 47

我的问题是:如何在Clojure中的映射函数内的宏中获取嵌套参数?



问题到其他地图/宏已经问过的问题,因为这是 嵌套参数检索)。

解决方案

宏在编译时展开。

 (doall(map#(describe-args(+ 42%))num-vec))

会扩展为以下类似的内容:

 (doall(map(fn [tmpvarname] 
(describe-args(+ 42 tmpvarname))
num-vec))

tmpvarname 是唯一的,并且会在每次展开宏时更改,然后代码进一步展开:

 (doall(map(fn [tmpvarname] 
(println'(+ 42 tmpvarname)=(+ 42 tmpvarname) ))
num-vec))

这将在代码执行之前完成,宏扩展器不知道 num-vec 不是一个变量符号,实际上它不会知道 map println 是因为在宏扩展时代码是数据。 map 只是一个符号。 / p>

现在当这段代码运行时,运行时不需要知道有一个宏开始。当 map 没有宏的时候。



宏在运行之前更改代码。它的目的是减少复杂性和代码大小,但它增加了一些混乱,因为程序员读代码需要了解什么是她正在阅读的代码库中的自定义宏。 Paul Graham在 Lisp 中建议您可能需要使用宏十到二十次才能获得可读性的净改善。


I'm passing my macro to a map operation. I'm having some trouble getting my values out. Here is an example:

(def num-vec [1 2 3 4 5])

(defmacro describe-args [first-arg]
  `(println '~first-arg " = " ~first-arg))

(doall (map #(describe-args (+ 42 %)) num-vec))

This returns:

(+ 42 p1__437#)  =  43
(+ 42 p1__437#)  =  44
(+ 42 p1__437#)  =  45
(+ 42 p1__437#)  =  46
(+ 42 p1__437#)  =  47

My question is: How do I get the nested argument in a macro inside a mapped function in Clojure?

(I believe this is a different question to the other map/macro questions already asked as this is about nested argument retrieval).

解决方案

Macros expand at compile time.

(doall (map #(describe-args (+ 42 %)) num-vec))

gets expanded to something like:

(doall (map (fn [tmpvarname] 
              (describe-args (+ 42 tmpvarname))
            num-vec))

tmpvarname is unique and will change each time the macro is expanded. Then the code gets further expanded:

(doall (map (fn [tmpvarname] 
              (println '(+ 42 tmpvarname) " = " (+ 42 tmpvarname))) 
            num-vec))

This gets done before the code gets executed and the macro expander doesn't know what num-vec is other than being a variable symbol. Actually it won't know what map or println is either since at the macro expansion time the code is data. map is just a symbol.

Now when this code is run the runtime need not know there ever was a macro there to begin with. When map does its thing there are no macros.

Macros change code before it is run. Its purpose is to reduce complexity and code size but it adds some confusion since the programmer who reads code needs to learn what is a custom macro in the code base she is reading. Paul Graham suggests in On Lisp that you might have to use the macro ten or twenty times before it yields a net improvement in readability.

这篇关于如何在Clojure中的映射函数中的宏中获取嵌套参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆