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 有符号宏的概念,您可以在其中将宏扩展绑定到符号,如 foo,以便符号将扩展为值。
现在,一个明显但同样糟糕(在不卫生的意义上)的方法就是将全局 var foo 绑定到值,但我不希望全局(或者,更确切地说,我希望它们本地化在 ghypers 中)。
有什么办法可以做我在 Julia 中寻求的事情吗?
(<flame> 40 多年来一直是一个快乐的 lisp 露营者,Julia 是第一个我可以说我实际上甚至有点喜欢的编程语言。但没有意识到同音性的重要性,他们的宏系统是......好吧,在我看来,一团糟,Lisp 像雨水一样清澈。</flame> :-)
解决方案
有两种直接的方法。如果事物是卫生的并且引用透明,则只需使用一个const
值。这在您的示例中不起作用。
否则,您必须在调用语法中使用宏:@foo()
. 没有周围的,这就是 Julia 语法的工作方式。虽然我也不建议这样做。
但是一个更好的选择,恕我直言,将是一个“照应上下文宏”,例如:
@withhyper (stuff) begin
println(foo+1)
end
在哪里foo
是esc
某个本地范围内的名称。将块扩展为
let foo = setup_hyper(stuff, ...)
println(foo+1)
end
推荐阅读
- java - LocalDate 的休眠模式验证失败 - 找到日期,但需要时间戳
- java - Spring Boot/Kotlin 忽略 @QueryParam 的值字段
- python - 如何从以相同字母开头和结尾的单词创建单词部分词典
- c# - .NET,远程服务器返回错误:(405) Method Not Allowed
- powershell - 使用 ListBox Powershell 列出每台网络打印机
- c# - 条目上的多种行为(Xamarin Forms)
- c++ - C++ 用不重复的随机数填充数组
- flutter - 如何修复这个 Flutter xcode 构建?
- javascript - 从 DB 解析 JSON 并在前端显示
- javascript - 有条件地更改 Javascript 对象中键的顺序