让窗体:如何访问宏中的解构符号? [英] let forms : How to access destructured symbols in a macro?
问题描述
我试图写一个宏,它展开为一个let形式与解构。我的问题是,我想有let形式定义的符号列表,包括通过破坏获得的符号。
用例
我试图考虑这种行为,例如验证:
(let [a(foo bar)
/ pre>
{x:x,
y:y,
{u:u,v:v:as nested-map} :nested} some-map]
(and xy nested-map uv; testing truthiness
(valid-a?a)
(valid-x?x)
y?y)
(valid-nested?nested-map)
(valid-u-and-v?uv)
))
建议解决方案
某种类型的
和-let
宏,我可以这样调用:(and-let [a(foo bar)
{x:x,
y:y,
{u:u,v:v:as nested-map} map]
(valid-a? a)
(valid-x?x)
(valid-nested?nested-map)
(valid-u-and-v?uv))
我缺少的内容
缺少一些访问以let形式绑定的符号列表的方式。如果我有一个像
list-bound-symbols
函数,我可以这样做:(defmacro and-let
扩展到一个AND关闭,先前检查绑定中声明的值是否为真,然后是测试。
[bindings& tests]
(let〜bindings
(和
〜
) @ bound-symbols
〜@ tests)
)))
解决方案解构由
clojure.core / destructure
函数。它是公共的,所以我们可以自己调用它,并提取所有本地人的名字,包括命名结构中使用的中间结果:(defmacro and-let [bindings& testing]
(let [destructured(destructure bindings)]
`(let〜destructured
(and〜@ $ b〜@ tests))))
看起来有效:
(let [foo nil]
(and-let [a 1
[bc] [2 3]]
nil?foo)))
; = true
I'm trying to write a macro which expands to a let form with destructuring. My problem is that I would like to have the list of the symbols that are defined in the let form, including those obtained by destruturing.
Use case
I'm trying to factor out this kind of behavior, for validation for example :
(let [a (foo bar) {x :x, y :y, {u :u, v: v :as nested-map} :nested} some-map] (and x y nested-map u v ; testing truthiness (valid-a? a) (valid-x? x) (valid-y? y) (valid-nested? nested-map) (valid-u-and-v? u v) ))
Proposed solution
It would be really nice to achieve this through some sort of
and-let
macro which I could call like this:(and-let [a (foo bar) {x :x, y :y, {u :u, v: v :as nested-map} :nested} some-map] (valid-a? a) (valid-x? x) (valid-nested? nested-map) (valid-u-and-v? u v))
What I'm missing
But I'm missing some way of accessing the list of the symbols that are bound in the let form. If I had something like a
list-bound-symbols
function, I could do it like this :(defmacro and-let "Expands to an AND close that previouly checks that the values declared in bindings are truthy, followed by the tests." [bindings & tests] (let [bound-symbols (list-bound-symbols bindings) ;; what I'm missing ] `(let ~bindings (and ~@bound-symbols ~@tests) )))
Has anyone got a clue how I might do this?
解决方案Destructuring is handled by the
clojure.core/destructure
function. It's public, so we can call it ourselves and extract the names of all locals, including those naming intermediate results used in destructuring:(defmacro and-let [bindings & tests] (let [destructured (destructure bindings)] `(let ~destructured (and ~@(take-nth 2 destructured) ~@tests))))
Seems to work:
(let [foo nil] (and-let [a 1 [b c] [2 3]] (nil? foo))) ;= true
这篇关于让窗体:如何访问宏中的解构符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!