让窗体:如何访问宏中的解构符号? [英] let forms : How to access destructured symbols in a macro?

查看:84
本文介绍了让窗体:如何访问宏中的解构符号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个宏,它展开为一个let形式与解构。我的问题是,我想有let形式定义的符号列表,包括通过破坏获得的符号。



用例



我试图考虑这种行为,例如验证:

 (let [a(foo bar)
{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)
))
/ pre>

建议解决方案



某种类型的和-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屋!

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