Clojure:在另一个宏内部获取宏元数据

huangapple go评论64阅读模式
英文:

Clojure: Take a macro metadata inside another macro

问题

在我其中一个宠物项目中,我有一堆宏,有时我想读取宏定义的元数据。原因是有时我的其他宏应该根据输入形式展开不同。当然,只是展开然后读取元数据更简单,但我想知道在宏正在展开时是否可能做到这一点。

考虑下面的宏:

(defmacro stackoverflow 
  {:example 23} 
  [& args] 
  (comment "This is just an example"))

在常规函数中从宏中读取元数据是非常简单的。

(defn- -example?
  [form-var]
  (-> form-var
      meta
      :example
      some?))

:=> (-example? #'stackoverflow)
true

在另一个宏中做这个也不难:

(defmacro example?-macro[form] 
  `(-example? (var ~form)))

:=> (example?-macro stackoverflow)
true

但我找不到一种在宏展开时获取元数据的方法:

(defmacro test-example? [form]
  (if (example?-macro form)
    (println "It is indeed an example")
    (println "It is not and example!")))

> Unable to resolve var: form in this context

我希望我的 test-example? 根据输入形式执行不同的工作,但找不到方法。

简而言之,整个问题 boils down to: How to take var from input macro inside macro without expanding like so:

;; 这是期望的行为

(defmacro imagining-solution
  [form]
  (if (:example `(meta (var ~form)))
    (println "It is indeed an example")
    (println "It is not and example!")))

;; 但这只能是梦想
英文:

On one of my pet projects I have a bunch of macros, and sometimes I want to be able to read metadata from macro definition. The reason being that sometimes my other macros should expand differently depending on input form. Of course, it is rather simpler to just expand and then read metadata, but I wonder if it's possible to do while macro is expanding.

Consider following macro:

(defmacro stackoverflow 
  {:example 23} 
  [& args] 
  (comment "This is just an example"))

It is perfectly simple to read metadata from macro in regular function.

(defn- -example?
  [form-var]
  (-> form-var
      meta
      :example
      some?))

:=> (-example? #'stackoverflow)
true

It is not hard to do inside another macro as well:

(defmacro example?-macro[form] 
  `(-example? (var ~form)))

:=> (example?-macro stackoverflow)
true

But I couldn't find a way to get meta while macro is expanding:

(defmacro test-example? [form]
  (if (example?-macro form)
    (println "It is indeed an example")
    (println "It is not and example!")))

> Unable to resolve var: form in this context

I want my test-example? to do different job depending on the input form, but couldn't find a way to do it.

In short the whole question boils to: How to take var from input macro inside macro without expanding like so:

;; This is desired behaviour

(defmacro imagining-solution
  [form]
  (if (:example `(meta (var ~form)))
    (println "It is indeed an example")
    (println "It is not and example!")))

;; But one can only dream about

答案1

得分: 0

立刻在发布这个问题后 Clojure:在另一个宏内部获取宏元数据 在这里找到了解决方案:https://stackoverflow.com/questions/30679637/accessing-arguments-metadata-in-clojure-macro?rq=2

只需使用 resolve 函数!

英文:

Immediately after posting this question Clojure:在另一个宏内部获取宏元数据 found a solution here:
https://stackoverflow.com/questions/30679637/accessing-arguments-metadata-in-clojure-macro?rq=2

Just use resolve function!

huangapple
  • 本文由 发表于 2023年6月5日 06:06:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76402588.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定