【发布时间】:2017-02-17 06:31:19
【问题描述】:
我想编写一个简单的宏来显示变量的名称和值。在 Common Lisp 中是
(defmacro dprint (&rest vars)
`(progn
,@(loop for v in vars
collect `(format t "~a: ~a~%" ',v ,v))))
在 Julia 中我有两个问题:
- 如何将生成的
Expr对象收集到一个块中? (在 Lisp 中,这是通过将带有,@的列表拼接到progn来完成的。)我能想到的最好的方法是创建一个Expr(:block),并将其args设置为列表,但这还很远来自优雅。 - 我需要同时使用变量的名称和值。字符串内插值和带引号的表达式都使用
$,这会使问题复杂化,但即使我使用string进行连接,我也无法打印变量的名称——至少:($v)与@987654330 不一样@ 在 CL 中...
我当前的宏是这样的:
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println(string(:($v), " = ", $v))) for v in vars]
ex
end
查看宏展开说明问题:
julia> macroexpand(:(@dprint x y))
quote
println(string(v," = ",x))
println(string(v," = ",y))
end
我想得到
quote
println(string(:x," = ",x))
println(string(:y," = ",y))
end
有什么提示吗?
编辑:结合答案,解决方案似乎如下:
macro dprint(vars...)
quote
$([:(println(string($(Meta.quot(v)), " = ", $v))) for v in vars]...)
end
end
... 即,使用$(Meta.quot(v)) 达到',v 的效果,使用$(expr...) 达到,@expr 的效果。再次感谢!
【问题讨论】:
标签: macros metaprogramming julia