在clojure中,我如何评估从另一个宏的宏的参数? [英] In clojure, how can I evaluate the arguments to a macro from another macro?

查看:122
本文介绍了在clojure中,我如何评估从另一个宏的宏的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个宏。第一个将一个符号作为唯一的参数(因为它传递给def,它需要一个符号)。第二个函数接受一个符号列表,并且应该单独调用每个符号的第一个。

I have two macros. The first one takes a symbol as the only parameter (because it's passed to def, which needs a symbol). The second function takes a list of symbols and should call the first with each symbol individually.

(defmacro m1 [s]
  '(let [f# ... dynamic function definition ...]
      (def ~s f#))

第二个宏应该使用符号列表最好我能想出以下:

The second macro should take a list of symbols and pass them to the first, but I can't get it to work. The best I could come up with was the following:

(defmacro m2 [symbols]
   `(for [s# ~symbols] (eval (read-string (str "(name.of.current.namespace/m1 " s# ")")))))

这将强制 s#它被传递到第一个宏,它也被调用一个字符串列表,而不是一个符号列表。

which forces the s# to be evaluated before it is passed to the first macro. It is also invoked with a list of strings, rather than a list of symbols.

这对我使用的库很有用其中的所有函数都使用相同的两个第一个参数我试图在我的命名空间中为一些函数创建包装器函数,它自动提供所有的共同的前两个参数值。

This is useful for a library which I am using for which all of the functions in the library takes the same two first parameters. I am trying to create wrapper functions, in my namespace, for some of the functions, which automatically provides the first two parameter values which are common to all of them.

有什么想法可以改善吗?

Any ideas to improve this?

推荐答案

如何获得两个宏合作,答案是不要使它们都是宏。我认为我的有关宏编写宏的博文有助于澄清。对于这种特殊情况,我可能会合并两个建议从评论:

Usually when you ask how to get two macros to cooperate, the answer is to not make them both macros. I think my blog post on macro-writing macros will help clarify. For this particular situation I'd probably combine two suggestions from the comments:

(defmacro build-simpler-functions [& names]
  (cons 'do
        (for [name names]
          `(def ~(symbol (str "simple-" name))
             (partial ~name 5 10))))) ; if you always pass 5 and 10

(build-simpler-functions f1 f2)

这扩展到

(do
  (def simple-f1 (clojure.core/partial f1 5 10))
  (def simple-f2 (clojure.core/partial f2 5 10)))



<

which looks like basically what you want.

编辑:如果args的alwayspass对于每个函数都是不同的,你可以这样做:

if the args you "always" pass are different for each function, you can do this:

(defmacro build-simpler-functions [& names]
  (cons 'do
        (for [[name & args] names]
          `(def ~(symbol (str "simple-" name))
             (partial ~name ~@args)))))

(build-simpler-functions [f1 5 10] [f2 "Yo dawg"]) ; expansion similar to the previous

这篇关于在clojure中,我如何评估从另一个宏的宏的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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