macros - Julia 相当于一个 Lisp 符号宏?

标签 macros julia lisp

我正在尝试做 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 中寻求的功能吗?

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

最佳答案

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

否则,您必须在调用语法中使用宏:@foo()。没有其他办法,这就是 Julia 语法的工作原理。尽管我也不建议这样做。

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

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

其中foo是某个本地范围内的名称escaped。将 block 扩展为以下内容的变体

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

关于macros - Julia 相当于一个 Lisp 符号宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65113509/

相关文章:

macros - 生成访问器的 Julia 宏

c++ - 这样的宏有什么用?

java - Android 有用的调试/发布宏(使用 gradle?)

gcc - 为 Julia 中的 C lib 使用构建 C 包装器

emacs - 随后运行相同的函数,产生不同的结果

ruby - 如何编写解释器?

c - __FILE__ 宏显示完整路径

julia - 如何从 Julia 中拟合的 GLM 模型对象中提取数据分布类型(例如泊松、二项式)?

wolfram-mathematica - 如何提高这段代码的性能?

lisp - 如何使用 define 将 Racket 的多个返回值绑定(bind)到全局变量名?