# Code templates, quoting, and variable substitution

**URL:** <https://discourse.julialang.org/t/code-templates-quoting-and-variable-substitution/61306>\
**Category:** General Usage\
**Created:** [May 17, 2021, 3:03pm UTC](https://discourse.julialang.org/t/code-templates-quoting-and-variable-substitution/61306 "2021-05-17T15:03:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mark\_Nahabedian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mark_nahabedian/32/16562_2.png) [@Mark\_Nahabedian](https://discourse.julialang.org/u/Mark_Nahabedian)\
**Post date:** [May 17, 2021, 3:03pm UTC](https://discourse.julialang.org/t/code-templates-quoting-and-variable-substitution/61306/1 "2021-05-17T15:03:50Z")

</div>

I’m having trouble with code templates, quoting, and variables.

I’m using the NativeSVG package. Some of its SVG element definitions don’t allow content even though they should. In particular, I’d like to add a `title` child to `rect` so that my `rect`s can have tooltips.

I made a local branch of NativeSVG to work in. It’s easy enough to change the flag associated with `:rect` in the definition of `PRIMITIVES` to enable child content.

The code in NativeSVG that defines a function for each SVG element that can have children is

```julia
for primitive in keys(filter(d -> last(d), PRIMITIVES))
    eval(quote
        function $primitive(f::Function, io::IOBuffer = BUFFER; kwargs...)
            print(io, "<", $primitive)
            for (arg, val) in kwargs
                print(io, " ", replacenotallowed(arg), "=\"", val, "\"")
            end
            println(io, ">")
            f()
            println(io, "</", $primitive, ">")
        end
    end)
end

```

I’m also trying to abstract out the code that writes the SVG into a single function that can be called by those element definitions and is available to users if they require some element not considered by NativeSVG:

```julia
function element(f::Function, tagname::Symbol, io::IOBuffer = BUFFER; kwargs...)
    print(io, "<", tagname)
    for (arg, val) in kwargs
        print(io, " ", replacenotallowed(arg), "=\"", val, "\"")
    end
    println(io, ">")
    f()
    println(io, "</", tagname, ">")
end

for primitive in keys(filter(d -> last(d), PRIMITIVES))
    eval(quote
        function $primitive(f::Function, io::IOBuffer = BUFFER; kwargs...)
          element(f, $primitive, io; kwargs...)
        end
    end)
end

```

When I run my NativeSVG’s unit tests though, I get the error

```julia
     Testing Running tests...
ERROR: LoadError: MethodError: no method matching element(::NativeSVG.var"#6#7"{var"#1#3"}, ::typeof(svg), ::IOBuffer; xmlns="http://www.w3.org/2000/svg", width="300", height="200")
Closest candidates are:
  element(::Function, ::Symbol, ::IOBuffer; kwargs...) at c:\Users\Mark Nahabedian\.julia\dev\NativeSVG.jl\src\svg.jl:82
  element(::Function, ::Symbol) at c:\Users\Mark Nahabedian\.julia\dev\NativeSVG.jl\src\svg.jl:82 got unsupported keyword arguments "xmlns", "width", "height"
Stacktrace:
 [1] svg(f::Function, io::IOBuffer; kwargs::Base.Iterators.Pairs{Symbol, String, Tuple{Symbol, Symbol, Symbol}, NamedTuple{(:xmlns, :width, :height), Tuple{String, String, String}}})
   @ NativeSVG ~\.julia\dev\NativeSVG.jl\src\svg.jl:105

```

The top stack trame `svg` is a function defined by this code.

I don’t understand why `svg` is calling `element` without ‘f’ and with a `var`. Presumably the 2nd argument `::typeof(svg)` is the `:svg` that was substituted for `$primitive`. Why did it not recognize that as `Symbol`?

Can someone explain what I’m doing wrong?

Thanks.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 17, 2021, 5:56pm UTC](https://discourse.julialang.org/t/code-templates-quoting-and-variable-substitution/61306/2 "2021-05-17T17:56:00Z")

</div>

When you write:

```julia
        quote
        function $primitive(f::Function, io::IOBuffer = BUFFER; kwargs...)
          element(f, $primitive, io; kwargs...)
        end

```

you’re producing code that looks something like:

```julia
function svg(f...)
  element(f, svg, ...)
end

```

where `svg` is a symbol in the resulting code (just like `element`, and `f` are), but not actually a quoted symbol itself.

Or, in simpler form, you’re doing this:

```julia
julia> name = :a
:a

julia> quote
         $name
       end
quote
    #= REPL[7]:2 =#
    a
end

```

when what you want is this:

```julia
julia> quote
         $(QuoteNode(name))
       end
quote
    #= REPL[8]:2 =#
    :a
end

```

I think `element(f, $(QuoteNode(primitive)), io; kwargs...)` should resolve the issue.

---

<div class="post-metadata">

**Author:** ![Mark\_Nahabedian](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mark_nahabedian/32/16562_2.png) [@Mark\_Nahabedian](https://discourse.julialang.org/u/Mark_Nahabedian)\
**Post date:** [May 17, 2021, 8:00pm UTC](https://discourse.julialang.org/t/code-templates-quoting-and-variable-substitution/61306/3 "2021-05-17T20:00:29Z")

</div>

Thanks Robin. That did the trick.

I don’t understand why the call to `print` in the original code did’t have the same problem though. Would it be because `print` presumably accepts`Any` and it could find a string representation for what ot got?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [May 17, 2021, 8:21pm UTC](https://discourse.julialang.org/t/code-templates-quoting-and-variable-substitution/61306/4 "2021-05-17T20:21:12Z")

</div>

Right, you can print just about anything, and if you `print` a function, it just prints the name of that function:

```julia
julia> function foo()
         println("<", foo, ">")
       end
foo (generic function with 1 method)

julia> foo()
<foo>

```

but that’s not a particularly relaible way to do things. After all, some future version of Julia might “improve” function printing to something like `Function: "foo"` or whatever, which would have completely broken the old code.
