clojure宏中的文本替换功能,如C';s#定义

clojure宏中的文本替换功能,如C';s#定义,clojure,macros,lisp,Clojure,Macros,Lisp,我想写一个宏 (defmacro params [] 'a 'b 'c) 这将在像这样的地方使用 ;; without macro (fnc a b c) ;; with macro (fnc params) => (fnc a b c) 如果你看到这可以通过C的define轻松完成,它只是一个文本替换 但是这只返回一个“c”Lisp风格宏的要点是它们对代码而不是文本(或者更具体地说,是对抽象语法树而不是标记序列)进行操作,这使得它们比c预处理器更有用 实际上,您似乎想说的是,要使用

我想写一个宏

(defmacro params [] 'a 'b 'c)
这将在像这样的地方使用

;; without macro
(fnc a b c)

;; with macro
(fnc params) => (fnc a b c)
如果你看到这可以通过C的define轻松完成,它只是一个文本替换


但是这只返回一个“c”

Lisp风格宏的要点是它们对代码而不是文本(或者更具体地说,是对抽象语法树而不是标记序列)进行操作,这使得它们比c预处理器更有用

实际上,您似乎想说的是,要使用三个参数调用函数,这三个参数恰好是每个调用站点上同名变量的值。这是相当多的假设。让我们看看这在实践中会是什么样子:

(def magic splat宏参数;无论如何,都不存在
a、b、c)
(傅德文[a]
(让[b(frob a)
(废话)]
(函数参数);我勒个去
我看不出这有什么用处,除了混淆

如果要定义标准参数,请执行以下操作:

(def标准参数[1“quux”:从不];价值观
(德文富[酒吧]
…
(应用func标准参数)

Lisp风格宏的要点是它们在代码上操作,而不是在文本上(或者更具体地说,在抽象语法树上而不是在标记序列上),这使得它们比C预处理器更有用

实际上,您似乎想说的是,要使用三个参数调用函数,这三个参数恰好是每个调用站点上同名变量的值。这是相当多的假设。让我们看看这在实践中会是什么样子:

(def magic splat宏参数;无论如何,都不存在
a、b、c)
(傅德文[a]
(让[b(frob a)
(废话)]
(函数参数);我勒个去
我看不出这有什么用处,除了混淆

如果要定义标准参数,请执行以下操作:

(def标准参数[1“quux”:从不];价值观
(德文富[酒吧]
…
(应用func标准参数)

我不太清楚为什么要这样做,但在clojure中,通常会使用以下idom:

(带参数的defmacro
[参数fncall]
`~(concat-fncall-params))
(定义myfn[x y z]
(spyx:myfn[x y z]))
(让[a]1
b 2
c 3]
(println:带参数)
(带参数[a b c]
(myfn))
结果:

:带参数
:myfn[x y z]=>[1 2 3]
但是,如果要硬编码代码以始终使用参数a、b和c,可以执行以下操作:

(带参数abc的defmacro
[电话]
`~(concat fncall'[a b c]))
(println:带参数abc)
(带参数abc)
(myfn))
结果:

:使用参数abc
:myfn[x y z]=>[1 2 3]

我不太清楚为什么要这样做,但在clojure中,通常会使用以下idom:

(带参数的defmacro
[参数fncall]
`~(concat-fncall-params))
(定义myfn[x y z]
(spyx:myfn[x y z]))
(让[a]1
b 2
c 3]
(println:带参数)
(带参数[a b c]
(myfn))
结果:

:带参数
:myfn[x y z]=>[1 2 3]
但是,如果要硬编码代码以始终使用参数a、b和c,可以执行以下操作:

(带参数abc的defmacro
[电话]
`~(concat fncall'[a b c]))
(println:带参数abc)
(带参数abc)
(myfn))
结果:

:使用参数abc
:myfn[x y z]=>[1 2 3]

另请参见:能否补充一点您为什么要这样做(一个更完整的示例)?我观察到,我正在编写的函数有一个共同的模式。即,我定义了一个带有参数a、b、c的函数。现在,这个函数的主体调用了许多具有相同参数的其他函数。现在,我不想到处重写a、b、c。如果每个defns arglist都有这样的宏,那么我可以在函数的位置使用它在我输入a、b、c的地方调用。但是我认为我可以使用代码转换工具(如postwalk replace)来实现这一点。如果我仍然不清楚@AlanThompsonSee,请告诉我:你能补充一下为什么要这样做吗(一个更完整的示例)?我观察到,我正在编写的函数有一个共同的模式。即,我定义了一个带有参数a、b、c的函数。现在,这个函数的主体调用了许多具有相同参数的其他函数。现在,我不想到处重写a、b、c。如果每个defns arglist都有这样的宏,那么我可以在函数的位置使用它在我输入a、b、c的地方调用。但是我认为我可以使用代码转换工具(如postwalk replace)实现这一点。如果我仍然不清楚@Alan Thompson,请告诉我