如果我有一个方法
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(即ArgumentError: alist should be a vector)。
alist = [:x]
@doarray(alist)我怎样才能使上面的代码类似于@doarray(x)
动机:我有一个递归宏(比方说mymacro),它接受一个向量,对第一个值进行操作,然后用向量的其余部分递归调用mymacro (比方说rest_vector)。我可以创建rest_vector,正确地打印值(用于调试),但是当我再次将rest_vector提供给mymacro时,我不知道如何计算它。
编辑1:我正在尝试在Julia中实现logic programming,即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)))
发布于 2018-11-23 15:36:33
如果我正确理解了您的问题,最好在宏内调用一个函数(而不是宏),该函数将在传递给宏的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当然,在这个例子中,我们没有做任何有用的事情。如果你具体说明了你想要实现的目标,那么我可能会提出更具体的建议。
https://stackoverflow.com/questions/53440146
复制相似问题