1

如果我有一个未知数量的参数,我想用“let”相互绑定,例如:

let [a "hello" b 55 ]

如果我在函数/宏或类似函数中绑定 let 并且我想遍历列表,我将如何执行此操作?

请注意,在 let 中有 4 个元素,但我只想遍历“键”。一个使用示例可能是检查绑定到键的值是否是像 b 这样的数字,即 55

编辑:作为一个例子:请注意,以下内容非常糟糕,但它只是为了解释问题:

(defn func [& arguments] 
 (let [ ~arguments] ((println "omg no way!") (for [x let-list] (number? x (println "roar") )))

输入:(func [a“你好”b 55]

所以基本上:我想要一个功能:

  • 将参数绑定到某种形式的列表,例如:[ab]
  • 打印“omg no way!”) - 不应该是循环的一部分,应该只在函数中打印一次
  • 某种循环,例如循环通过“let-list”的for循环,所以它会去:“a,是一个数字吗?不,是b数字吗?是的,打印“roar”

输出:omg 没办法咆哮

再一次: 我想知道是否有一种方法可以访问函数内部的关键字。正如 for 循环所示,我想访问每个单独的元素并使用该元素执行操作。如果我使用 (for [x arguments] 代替,它会给出:omg no way, roar roar (因为 b 绑定到 55 所以它是一个数字但 55 也是一个数字但没有必要使用 55 因为 55 是已经绑定到 b)

4

1 回答 1

1

这是一个宏的示例,它采用交替名称和值的列表,将它们绑定在一个 let 中,然后通过引入一个名为“locals”的符号保存它刚刚创建的绑定映射,该符号命名一个本地名称映射本地值。

(defmacro anaphoric-let [alternating-symbols-and-values & body]
  `(let [~@alternating-symbols-and-values
         names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values)))
         values#  ~(vec (flatten (partition 1 2 alternating-symbols-and-values)))
         ~'locals (zipmap names# values#)]
     ~@body))

任何名为 withing 的表达式anaphoric-let都可以使用locals名称中的值。

user> (anaphoric-let [a 1 b 2 c 3 d 4] [a locals])
[1 {d 4, c 3, b 2, a 1}]

在使用 let 定义它们之后和在正文之前将值保存在映射中对于防止多次执行和其他不卫生宏的罪过很重要。

然后可以使用此地图根据当地人做出决策:

user> (anaphoric-let [a 1 b 2 c 3 d 4 e "cat"] 
        (map (fn [[local val]] 
               (str local " is " (if (number? val) val "woof"))) 
              locals))
("e is woof" "d is 4" "c is 3" "b is 2" "a is 1")

或者:

user> (anaphoric-let [a 1 b 2 c 3 d 4 e "cat"] 
        (println "omg no way!") 
        (dorun (for [x (vals locals)] 
                 (if (number? x) (println "roar")))))
omg no way!                                                                                                                                                    
roar                                                                                                                                                           
roar                                                                                                                                                           
roar                                                                                                                                                           
roar                                                                                                                                                           
nil

ps: anaphoic 宏是在它创建的代码中引入一个名称的任何宏,该名称在传递给它的代码中不存在。

于 2013-01-13T22:52:59.713 回答