julia - 如何将变量传递给宏并在宏执行之前对其进行评估?
问题描述
如果我有方法
macro doarray(arr)
if in(:head, fieldnames(typeof(arr))) && arr.head == :vect
println("A Vector")
else
throw(ArgumentError("$(arr) should be a vector"))
end
end
如果我写这个就可以了
@doarray([x])
或者
@doarray([:x])
但是下面的代码正确地不起作用,提高了ArgumentError
(ie ArgumentError: alist should be a vector
)。
alist = [:x]
@doarray(alist)
我怎样才能使上述行为类似于 @doarray([x])
动机:我有一个递归宏(比如mymacro
),它接受一个向量,对第一个值进行操作,然后mymacro
用向量的其余部分递归调用(比如rest_vector
)。我可以创建rest_vector
,正确打印值(用于调试),但我不知道如何评估rest_vector
当我再次将它提供给它mymacro
时。
编辑 1:我正在尝试在 Julia 中实现逻辑编程,即 MiniKanren。在我基于此的 Clojure 实现中,代码就是这样。
(defmacro fresh
[var-vec & clauses]
(if (empty? var-vec)
`(lconj+ ~@clauses)
`(call-fresh (fn [~(first var-vec)]
(fresh [~@(rest var-vec)]
~@clauses)))))
基于此的我失败的 Julia 代码如下。如果它没有意义,我深表歉意,因为我试图通过实现它来理解宏。
macro fresh(varvec, clauses...)
if isempty(varvec.args)
:(lconjplus($(esc(clauses))))
else
varvecrest = varvec.args[2:end]
return quote
fn = $(esc(varvec.args[1])) -> @fresh($(varvecvest), $(esc(clauses)))
callfresh(fn)
end
end
end
运行代码时出现的错误@fresh([x, y], ===(x, 42))
(您可以忽略===(x, 42)
此讨论)
ERROR: LoadError: LoadError: UndefVarError: varvecvest not defined
问题线是fn = $(esc(varvec.args[1])) -> @fresh($(varvecvest), $(esc(clauses)))
解决方案
如果我正确理解您的问题,最好在宏内部调用一个函数(不是宏),该函数将对传递给宏的 AST 进行操作。这是一个简单的示例,您可以如何做到这一点:
function recarray(arr)
println("head: ", popfirst!(arr.args))
isempty(arr.args) || recarray(arr)
end
macro doarray(arr)
if in(:head, fieldnames(typeof(arr))) && arr.head == :vect
println("A Vector")
recarray(arr)
else
throw(ArgumentError("$(arr) should be a vector"))
end
end
当然,在这个例子中,我们没有做任何有用的事情。如果您指定了您想要实现的确切目标,那么我可能会提出更具体的建议。
推荐阅读
- php - 类别表单构建器模块 PrestaShop 的问题
- android - 什么更有效:RxTextView.textChanges 或 doOnTextChanged?
- design-patterns - 命令模式是命令的单个实例
- r - RStudio Connect:无法在 R 版本 4.0.0 中部署
- awk - bash中两个连续行的值
- google-cloud-platform - 在重新启动计算引擎时,IP 地址仍然是静态的,尽管它应该是动态分配的
- python - 无法从 oracle pandas datafrime 写入镶木地板
- python - 如何在 Django 中大规模管理视图、URL 和模型?
- algorithm - 什么是更好的递归或迭代星形模式?
- visual-studio - Nuget 还原 - 无法解析远程名称