Why can't I get a symbol to interpolate when using ':(for outer $var ...)'

I am auto-generating Julia code and wish to construct an Expr for a for statement for which the iteration variable will be available in the enclosing scope (that’s the spec of the source language). For some reason

julia > q = :p
julia> :(for $q = 1:2:3 end)
:(for p = 1:2:3

works, but with outer instead I get

julia> :(for outer $q = 1:2:3 end)
:(for outer $ q = 1:2:3

ie $q has not been interpolated.
(This is Julia 1.2)

They’re parsed differently:

julia> Meta.show_sexpr(:(for outer $q = 1:2:3 end))
(:for, (:(=), (:call, :$, :outer, :q), (:call, :(:), 1, 2, 3)), (:block,
    :(#= REPL[1]:1 =#)

julia> Meta.show_sexpr(:(for $q = 1:2:3 end))
(:for, (:(=), :p, (:call, :(:), 1, 2, 3)), (:block,
    :(#= REPL[3]:1 =#)

The first case is surprising, even to me, but it must be due to the fact that outer p is not valid syntax anyway, so outer $ p with $ interpreted as infix operator is the only interpretation that can work:

julia> Meta.show_sexpr(:(a$b))
(:call, :$, :a, :b)

I had now idea this is possible, TBH.

The outer keyword exists in Julia 1.5 but not in Julia 1.2. So if you want to use it, you need to update your Julia version. To be honest I had not idea this keyword exists but it is in the manual: https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Loops-and-Comprehensions

1 Like

Uh. That’s new to me, never heard of it. My examples were done in 1.3. Time to update!

The manual for 1.2 includes outer in the section on Loop scoping. It is however missing from the list of keywords in the manual for both 1.2 and 1.5. Anyway, I’ll give 1.5 a try.

Good point – maybe the issue is that you are running this code the REPL? Especially around variable scope the REPL has special rules

I initially encountered this problem inside a function so I don’t think REPL scope is the issue.

Just checked with Julia 1.5.1, the behaviour is the same as Julia 1.2.

So, it seems like the parser does not recognize the outer keyword properly. I think that justifies filing an issue.

I’ve raised an issue.

A fix for this issue has now been committed to master.

1 Like