我正在尝试做 Lisp 黑客所说的“符号宏”。也就是说,这就是我现在使用的:
global ghypers = Dict()
macro hyp(variable, value); ghypers[:($variable)] = :($value); end
macro hyp(variable); ghypers[:($variable)]; end
@hyp foo 5
println(ghypers)
println(@hyp foo)
println(@hyp(foo)+1)
到目前为止一切顺利,但最后一件事很难看,我想这样做:
@foo+1
有点像这样:
macro foo(); ghypers[:foo]; end
println(@foo)
println(@foo()+1)
关闭,并且有效,但不完全是我想要的,这又是:
println(@foo+1)
MethodError: no method matching @foo(::LineNumberNode, ::Module, ::Expr)
除非那不起作用。
Lisp 有符号宏的概念,您可以将宏扩展绑定(bind)到符号,例如 foo,以便该符号将扩展为值。
现在,一个明显但同样糟糕(在不卫生的意义上)的方法就是将全局 var foo 绑定(bind)到该值,但我不希望全局(或者更确切地说,我希望它们本地化) ghypers)。
有什么办法可以实现我在 Julia 中寻求的功能吗?
(
最佳答案
有两种直接的方法。如果事物是卫生且引用透明的,则只需使用 const
值。这在您的示例中不起作用。
否则,您必须在调用语法中使用宏:@foo()
。没有其他办法,这就是 Julia 语法的工作原理。尽管我也不建议这样做。
但恕我直言,更好的选择是“照应上下文宏”,例如:
@withhyper (stuff) begin
println(foo+1)
end
其中foo
是某个本地范围内的名称esc
aped。将 block 扩展为以下内容的变体
let foo = setup_hyper(stuff, ...)
println(foo+1)
end
关于macros - Julia 相当于一个 Lisp 符号宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65113509/