Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 如何将可选宏参数传递给函数_Clojure - Fatal编程技术网

Clojure 如何将可选宏参数传递给函数

Clojure 如何将可选宏参数传递给函数,clojure,Clojure,这里是Clojure宏noob。我有一个带有一些可选参数的函数,例如 (defn mk-foo [name & opt] (vec (list* name opt))) 鉴于此: user> (mk-foo "bar" 1 2 3) ["bar" 1 2 3] 我正在尝试编写一个宏,它接受相同的可选参数,并将它们透明地传递给调用mk foo。到目前为止,我有: (defmacro deffoo [name & opt] `(def ~name ~(apply m

这里是Clojure宏noob。我有一个带有一些可选参数的函数,例如

(defn mk-foo [name & opt]
  (vec (list* name opt)))
鉴于此:

user> (mk-foo "bar" 1 2 3)
["bar" 1 2 3]
我正在尝试编写一个宏,它接受相同的可选参数,并将它们透明地传递给调用
mk foo
。到目前为止,我有:

(defmacro deffoo [name & opt]
  `(def ~name ~(apply mk-foo (str name) opt)))
达到了预期的效果:

user> (macroexpand '(deffoo bar 1 2 3))
(def bar ["bar" 1 2 3])

使用
apply
压扁列表
opt
感觉很笨拙。有没有一种惯用的方法可以做到这一点?我猜需要
~@
,但我不能正确引用。非常感谢。

在这种情况下,您使用apply的直觉很好地帮助了您。当你有一个带引号的表单,然后把它们全部解压时,考虑把不带引号的部分移到最小的部分或列表中会有所帮助。这避免了使用代码生成可以简单编写的表单

user=> (defmacro deffoo [name & opt] `(def ~name [~(str name) ~@opt]))       
#'user/deffoo
user=> (macroexpand '(deffoo "bar" 1 2 3))                            
(def "bar" ["bar" 1 2 3])
下面是对mk foo的呼叫:

(defmacro deffoo [name & opt] `(def ~name (mk-foo ~(str name) ~@opt)))     
#'user/deffoo
user=> (macroexpand '(deffoo "bar" 1 2 3))                                   
(def "bar" (user/mk-foo "bar" 1 2 3))

在第二种情况下,我们将
~
移动到一个级别,并让对mk foo的调用保持被引用,并且只解压缩构建参数列表所需的参数(如您所怀疑的那样使用拼接解压缩)

我对clojure不是特别擅长,但对我来说它看起来不错!谢谢你迅速的回答。不幸的是,我现实生活中的mk foo比上面的插图要复杂得多。手动内联扩展它不是一个选项。我必须进行调用。从以前的一次编辑中使用mk foo恢复了该示例。此操作有效,+1,但代价是将对
mk foo
的调用推迟到运行时。