如何解决 julia 表达式中变量的范围?

Mas*_*son 11 julia

有没有办法在不运行任意表达式的情况下运行名称解析?例如,我想采用诸如

quote
    x = 1
    y = 2*x + 1
    z = x^2 - 1
    f(x) = 2*x + 1
end
Run Code Online (Sandbox Code Playgroud)

并被告知在此块的范围内定义的名称是x, y, z, f,并且名称*, +, ^, -是从此块的范围之外拉入的。如果它可以告诉我在其主体中定义了一个子作用域,f它会创建自己的名称x+从封闭的作用域中拉入,则加分。

这个问题出现在Julia Zulip 社区

Mas*_*son 9

由于孝文用于显示我如何解决这个上Zulip

我们可以在 julia 表达式的最外层范围内获取本地定义的名称列表,如下所示:

ex = quote
    x = 1
    y = 2*x + 1
    z = x^2 - 1
    f(x) = 2*x + 1
end
Run Code Online (Sandbox Code Playgroud)
using JuliaVariables, MLStyle

function get_locals(ex::Expr)
    vars = (solve_from_local ? simplify_ex)(ex).args[1].bounds
    map(x -> x.name, vars)
end

julia> get_locals(ex)
 4-element Array{Symbol,1}:
  :f
  :y
  :z
  :x
Run Code Online (Sandbox Code Playgroud)

我们可以像这样从范围拉入符号:

_get_outers(_) = Symbol[]
_get_outers(x::Var) = x.is_global ? [x.name] : Symbol[]
function _get_outers(ex::Expr)
    @match ex begin
        Expr(:(=), _, rhs) => _get_outers(rhs)
        Expr(:tuple, _..., Expr(:(=), _, rhs)) => _get_outers(rhs)
        Expr(_, args...) => mapreduce(_get_outers, vcat, args)
    end
end

get_outers(ex) = (unique! ? _get_outers ? solve_from_local ? simplify_ex)(ex)

julia> get_outers(ex)
 6-element Array{Symbol,1}:
  :+
  :*
  :-
  :^
Run Code Online (Sandbox Code Playgroud)