朱莉娅相当于一个 lisp 符号宏?

Julia equivalent of a lisp symbol macro?

我正在尝试做 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 有符号宏的概念,您可以在其中将宏扩展绑定到一个符号,例如 foo,这样该符号就会扩展到值。

现在,一个明显但同样糟糕(在不卫生的意义上)的方法就是将全局变量 foo 绑定到值,但我不想要全局(或者更确切地说,我想要它们本地化为 ghypers)。

有什么方法可以实现我在 Julia 中寻找的东西吗?

( 40 多年来一直是一个快乐的 lisp 露营者,Julia 是我可以说我实际上有点喜欢的第一种编程语言。但是没有理解同质性的重要性,他们的宏系统是......好吧,在我看来,一团糟,而 Lisp 的系统就像雨水一样清澈。 :-)

有两种直接方式。如果事物卫生且引用透明,只需使用 const 值。这在您的示例中不起作用。

否则您必须在调用语法中使用宏:@foo()。没有办法,这就是 Julia 语法的工作方式。虽然我也不推荐这样做。

但是恕我直言,更好的选择是“照应上下文宏”,例如:

@withhyper (stuff) begin
    println(foo+1) 
end

其中 foo 是一个名称 escaped 在某个本地范围内。将块扩展为

的变体
let foo = setup_hyper(stuff, ...)
    println(foo+1)
end