Variable interpolation in string within expression

Hi there,

I am experimenting a bit with macros and wanted to know wheter there is a way to interpolate a variable (that is local to the macro) value inside a string within an expression returned by the macro.

a MWE is like the following

macro test1()
    a = "magic"
   :("This is $a")
end

Now I would like @macroexpand @test1 to return :("This is magic"), but instead it returns :("This is $(Main.a)").

I know that for this very simple example I could just create the :string Expression directly but my actual use case is more complicated.

What I am doing is probably convoluted/wrong but basically I have something similar to this;

using HypertextLiteral

macro testt()
    a = "randomstring"
    :(@htl """
         <- HTML things before ->
         <script>
            console.log($a)
            // JS things after
         </script>
     """)
end

Building the resulting @htl expression by hand becomes quite complicated so I wanted to ask if there is a easier way to make the interpolation of variable inside strings inside expression work as I want.

While not directly answering your question … one thing you are missing is called hygene,

macro test1()
  quote begin
    a = "magic"
    b = "This is $a."
    return b
  end; end
end

julia> @test1()
"This is magic."

With macros, It is good practice to use quote ... end or :( ... ) which is shorthand and appropriate for e.g. single line macro definitions. Omitting the quote block may allow unexpected scoping mixups to arise.

typeof( :("this string") ) == String,
:("this") is the same as "this", so it is not clear what you want here.

Yeah, the MWE is not super helpful to understand here.
What I wanted to achieve specifically is a bit convoluted and I don’t think is entirely necessary for the purpose of this question, which is understanding the general behavior of interpolation within strings within macros.

Let me reformulate an example, in my view there could be three possible ways of interpreting the interpolation, and I put them in the example macro below:

macro test2(sym::Symbol)
	a = "Local"
	esc(quote
		s1 = "Case 1: Interpolate the local variable directly in the string: $a" 
		s2 = "Case 2: Leave the string interpolation as it is written: $b" 
		s3 = "Case 3: Use the symbol given to the macro: $sym" 
	end)
end

The output of @macroexpand on that is below, where I removed the LineNums and added as comments what I would like to be able to achieve for these 3 cases

julia> @macroexpand @test2(c)
quote
    # I would this to be 
    # s1 = "Case 1: Interpolate the local variable directly in the string: Local"
    s1 = "Case 1: Interpolate the local variable directly in the string: $(a)"
    # This case is exactly as it should be
    s2 = "Case 2: Leave the string interpolation as it is written: $(b)"
    # I would this to be 
    # s3 = "Case 3: Use the symbol given to the macro: $(c)"
    s3 = "Case 3: Use the symbol given to the macro: $(sym)"
end

Is there some way to get the different behavior when doing interpolation inside string within expressions?
With the synthax as above all the 3 lines are using the interpolation of case 2

Edit:
My impression is that the only way to achieve the behavior of Case 1 and Case 3 is to construct the specific expression by hand using Expr, but I hope there might be something easier I don’t know about :smiley: