Quoting numbers vs quoting names

julia> Meta.parse(":1")
:($(QuoteNode(1)))

julia> Meta.parse(":a")
:(:a)

Quoting the name a gives me what I expect: The symbol :a. Quoting the number 1, however, resolves to $(QuoteNode(1)), which is not what I expect. I expect :1 to resolve to the symbol :1, and not to a QuoteNode that gets immediately interpolated.

There surely is a reason for this behavior, but I cannot find anything in the Metaprogramming docs.

It’s just printed more compactly.

julia> dump(Meta.parse(":a"))
QuoteNode
  value: Symbol a

julia> dump(Meta.parse(":1"))
QuoteNode
  value: Int64 1
1 Like
julia> dump(Meta.parse(":a"))
QuoteNode
  value: Symbol a

julia> dump(Meta.parse(":1"))
QuoteNode
  value: Int64 1

For this output, my question would be why dump(Meta.parse(":1")) gives value: Int64 1 instead of value: Symbol 1

Perhaps these examples are useful:

julia> foo = 3
3

julia> @eval $(:foo)
3

julia> @eval $(:1)
1

julia> @eval $(Symbol("1")) = 2
2

julia> @eval $(:1)
1

julia> @eval $(Symbol("1"))
2

julia> varinfo()
name                    size summary           
–––––––––––––––– ––––––––––– ––––––––––––––––––
1                    8 bytes Int64               
foo                  8 bytes Int64      
3 Likes

Whoa - did you just make a global variable called 1 and assign it a value 2? Kinky. :slight_smile:

Does this mean that the rules for variable naming are only enforced on the parser level? I assume that @eval trick only works in the global namespace, so is there another tricky way of defining local variables with relaxed naming rules?

macro withone(body)
    o = esc(Symbol("1"))
    quote
        let $(o) = 2
            $(esc(body)) + $(o)
        end
    end
end

@withone sin(1) # == sin(1) + 2
3 Likes