Confusing julia behavior. @everywhere macro changes the scope of local variables to global

I find this a bit confusing as well. One thing that often adds clarity is to replace macros with the code executed. In this case:

julia> using MacroTools

julia> prettify(@macroexpand(@fetchfrom 2 x))
:(Distributed.remotecall_fetch((()->x), 2))

so @fetchfrom 2 x actually means

remotecall_fetch(() -> x, 2)

i.e. it creates a closure around x, and then executes the result on pid 2. I can see how that ends up returning 1 given the closure is created on pid 1 and therefore likely closes over the local x, but I’m not sure why it changes the value of x on pid 2.

The way to get the value of x from other processes is to directly ask for the symbol defined in Main on those processes, as described in this SO answer:

julia> @fetchfrom 3 getfield(Main, :x)

julia> @everywhere println(x)
      From worker 2:	2
      From worker 3:	3