When trying to make Lint.jl working in Juno with Julia 1.0.1, I realised that Lint would stumble across any line with using [...].
Digging into the root cause I found that dump(:(using Foo)) has different results in different Julia versions:
julia-0.6.2.2> dump(:(using Foo))
Expr
head: Symbol using
args: Array{Any}((1,))
1: Symbol Foo
typ: Any
julia-1.0.1> dump(:(using Foo))
Expr
head: Symbol using
args: Array{Any}((1,))
1: Expr
head: Symbol .
args: Array{Any}((1,))
1: Symbol Foo
Is this by purpose? It seems a bit odd, as
julia-1.0.1> Expr(:using,:Foo)
:(using Foo)
but
julia-1.0.1> dump(Expr(:using,:Foo))
Expr
head: Symbol using
args: Array{Any}((1,))
1: Symbol Foo
My concern is not so much the stability of AST between Julia versions, it is more that the output of dump(Expr(:using,:Foo)) is not identical to dump(:(using Foo)) although Expr(:using,:Foo) evaluates to :(using Foo).
Funny enough, dump(Expr(:using,:Foo)) == dump(:(using Foo)) evaluates to true …
Yes, this representation is intentional. The idea is that the Expr with head . is a “path expression”, a dot-delimited list of names giving the components of a module path. In general:
julia> dump(:(using A.B.C.D))
Expr
head: Symbol using
args: Array{Any}((1,))
1: Expr
head: Symbol .
args: Array{Any}((4,))
1: Symbol A
2: Symbol B
3: Symbol C
4: Symbol D
So for using A the dot expression has a single argument.
Indeed there are a couple rough edges to fix here:
The printing for Expr(:using, :Foo) should use that input form instead of using Foo, since as you note they don’t match.
This should be added to the AST devdocs.
There should be an error for evaluating Expr(:using, :Foo), or perhaps we should treat it the same as using Foo.
That would be because dump always returns nothing!