function main()
v = Function[]
for i = 10:10:20
for j = i+3:i+4
push!(v, () -> println("I'm ", j))
v[end]()
j = (i)j # modify!
v[end]()
end
end
println("---see what we got---")
map(x -> x(), v)
end
main();
function main()
v = Function[]
for i = 10:10:20
for outer j = i+3:i+4
push!(v, () -> println("I'm ", j))
v[end]()
end
local j = 6i
end
j = -9 # irrelevant
println("---see what we got---")
map(x -> x(), v)
end
main();
Using interpolation, i.e. $, in various macros is literally a rewriting to compute the interpolated expression before whatever the macro does. That is,
@spawn something($expr)
is literally rewritten to something like
...
let uniquename=expr
t = Task(() -> something(uniquename)
end
...
This is done by Base._lift_one_interp!(...), which works on the syntax tree produced by the parser.
Likewise, a for loop is literally rewritten to a while loop using iterate(...), as described above, and in the docs. Though with unique variable names which your program can’t touch, so it can’t be inadvertently mutated. (Except in an outer for). The result of these rewriting operations can be observed e.g. with the @code_lowered macro, and for the interpolation with a @macroexpand:
julia> @macroexpand Threads.@spawn foo($i)
quote
#= threadingconstructs.jl:511 =#
let var"##277" = i
#= threadingconstructs.jl:512 =#
local var"#70#task" = Base.Threads.Task((()->begin
#= REPL[47]:1 =#
foo(var"##277")
end))
...