We are dealing with literals, which are special in the metaprogramming space since quoting a literal is the literal itself.
julia> :(5)
5
julia> :("hello")
"hello"
julia> eval(:(:("hi")))
"hi"
Consider an alternative construction of the macros:
julia> macro foo_str(ex)
ex2 = unescape_string(ex)
quote
StaticString($ex2)
end
end
@foo_str (macro with 1 method)
julia> foo() = foo"hello"
foo (generic function with 1 method)
julia> @code_llvm foo()
; @ REPL[71]:1 within `foo`
define [1 x [5 x i8]] @julia_foo_798() #0 {
top:
%gcframe6 = alloca [3 x {}*], align 16
%gcframe6.sub = getelementptr inbounds [3 x {}*], [3 x {}*]* %gcframe6, i64 0, i64 0
%0 = bitcast [3 x {}*]* %gcframe6 to i8*
...
This still results in quite complicated code.
The notable thing about the string literal in StaticStrings.jl is that we receive an expression, a literal, manipulate that in the meta macro space, recieve a value, and then inject that value into a quoted expression as a literal.
Metaprogramming by itself would be turning the literal into an expression surrounding that literal. This is a meta-meta programming because I have done some actual computation in the meta space rather than just building a new expression to be evaluated, and then interpolated the result of that computation into a new expression as if it were a literal.
Thus, the result of the macro and subsequent compilation is not the dynamic allocation of a String and subsequent call to a constructor. Rather, it looks as if I had just returned a 64-bit number literal.
julia> g() = static"Accurate"
g (generic function with 1 method)
julia> @code_native g()
...
movq %rdi, %rax
movabsq $7310575239352771393, %rcx # imm = 0x6574617275636341
movq %rcx, (%rdi)
retq
In the above example, “Accurate” got converted into the number 7310575239352771393
or 0x6574617275636341
in hexadecimal.
julia> n = Int(0x6574617275636341)
7310575239352771393
julia> reinterpret(UInt8, [n]) .|> Char
8-element Vector{Char}:
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'u': ASCII/Unicode U+0075 (category Ll: Letter, lowercase)
'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
't': ASCII/Unicode U+0074 (category Ll: Letter, lowercase)
'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
That number happens to encode the eight ASCII bytes to spell “Accurate”.