# \_str string interpolation?

**URL:** <https://discourse.julialang.org/t/str-string-interpolation/125766>\
**Category:** General Usage\
**Tags:** macros, string-interpolation\
**Created:** [February 10, 2025, 7:41pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766 "2025-02-10T19:41:03Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 10, 2025, 7:41pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/1 "2025-02-10T19:41:04Z")

</div>

I am not sure what is the issue, but I would like to this to work:

```julia
julia> macro test_str(s)
           :($(esc(s)))
       end
@test_str (macro with 1 method)

julia> test"a 1" # "works"
"a 1"

julia> i = 1
1

julia> test"a $i" # "does not work"
"a \$i"

julia> @test_str "a $i" # works
"a 1"

```

Simlar to this old thread: [String interpolation in the short-hand call of macro @bash1\_str](https://discourse.julialang.org/t/string-interpolation-in-the-short-hand-call-of-macro-bash1-str/51846) Tamas there sais that “you could do it manually”, but I’m unsure what that means and why would it be bad.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 10, 2025, 8:06pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/2 "2025-02-10T20:06:29Z")

</div>

What’s happening here is just that

In

```julia
julia> @test_str "a $i" # works

```

interpolation happened before the string got pass to your macro.

In `test"a $i"`, the raw string is passed to the string macro so that it can process it itself, otherwise, you won’t be able to use `$` in regex `r"^startend$"`, so it’s necessary we pass raw string to `_str` macros

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 10, 2025, 8:11pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/3 "2025-02-10T20:11:39Z")

</div>

Thus, inside the macro, there’s no way for the interpolation to occur, because it cannot know the value?

(without appealing to some extremely unidiomatic and non-local code)

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 10, 2025, 8:14pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/4 "2025-02-10T20:14:58Z")

</div>

you just have to DIY, as the old thread linked by you were suggesting, for example:

[BenchmarkTools.jl/src/execution.jl at cddd794ba336763be6831cfa076d27df96ef893c · JuliaCI/BenchmarkTools.jl · GitHub](https://github.com/JuliaCI/BenchmarkTools.jl/blob/cddd794ba336763be6831cfa076d27df96ef893c/src/execution.jl#L368-L370)

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 10, 2025, 8:16pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/5 "2025-02-10T20:16:17Z")

</div>

actually, check out [Variable interpolation in string within expression](https://discourse.julialang.org/t/variable-interpolation-in-string-within-expression/70258)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 10, 2025, 8:16pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/6 "2025-02-10T20:16:58Z")

</div>

But can I do that from within the `sel"a $i` call? Will **the value** of `i` be visible, if the macro received the raw string?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 10, 2025, 8:17pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/7 "2025-02-10T20:17:17Z")

</div>

yes, that’s what interpolation mean… that was your question right? basically the macro would see `$` and you the macro author have to program the “getting the value” part

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [February 10, 2025, 8:20pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/8 "2025-02-10T20:20:36Z")

</div>

It escapes me at the moment but you can take a raw string and process it with interpolation. It’s just not common because `$` is usually implemented to do something else e.g. interop code string literals convert types between languages, and we can already opt into standard string interpolation prior to a macro call this way.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 10, 2025, 8:29pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/9 "2025-02-10T20:29:23Z")

</div>

I’m admittedly very limited in understanding how macros work, so I cannot solve that even for this trivial example. For instance, if I try:

```julia-repl
julia> module TestStr
           macro test_str(s)
               s = replace(s, "\$i" => "$i")
               :($(esc(s)))
           end
       end
Main.TestStr

julia> using .TestStr

julia> TestStr.test"a $i"
ERROR: LoadError: UndefVarError: `i` not defined in `Main.TestStr`

```

It seems that I need to know the scope from which the call to the macro is happening to interpolate that properly.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [February 10, 2025, 8:38pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/10 "2025-02-10T20:38:45Z")

</div>

That is definitely not how I remember it, I think it had to dig into the parser. `Core.eval( __module__ , :i)` gets you past that error at least, but it’s still not like interpolating a standard string (works with local variables).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 10, 2025, 9:01pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/11 "2025-02-10T21:01:19Z")

</div>

> [@lmiq](#):
>
> Tamas there sais that “you could do it manually”, but I’m unsure what that means and why would it be bad.

The best way to do it manually would be to transform `test"a $i"` into `string("a ", i)` (which is what regular interpolation does). (The key thing to remember is that macros only know how things are “spelled”, not what their _values_ are. By transforming the expression into `string("a ", i)` or similar, you defer the evaluation of `i` until the code actually executes and the value is known.)

An example of how to do this can be found in the [implementation of the `L"..."`](https://github.com/JuliaStrings/LaTeXStrings.jl/blob/d344f9536391ee76fd14b7b62483b6a4bccf1b4d/src/LaTeXStrings.jl#L68-L92) macro from the LaTeXStrings.jl package. In that macro, `$` is treated as the beginning of a LaTeX equation, so it is left as is, but the string `%$` is used for interpolation instead.

The steps are to (1) parse your string to find (unescaped) `$`, (2) call `Meta.parseatom` (or `Meta.parse` with `greedy=false`) to parse the next complete Julia expression after the `$`, and (3) emit the desired expression from the macro, e.g. a call to `string` (or the `latexstring` constructor in the case above).

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 11, 2025, 6:06pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/12 "2025-02-11T18:06:35Z")

</div>

That worked, thanks!

---

<div class="post-metadata">

**Author:** ![algunion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/algunion/32/51630_2.png) [@algunion](https://discourse.julialang.org/u/algunion)\
**Post date:** [February 11, 2025, 7:55pm UTC](https://discourse.julialang.org/t/str-string-interpolation/125766/13 "2025-02-11T19:55:43Z")

</div>

I remember checking the `PromptingTools.jl` package source code a while back and encountering this:

> <https://github.com/svilupp/PromptingTools.jl/blob/4560d973938d073da067bb08e9c718cb7dcabd51/src/macros.jl#L34>

You might fint it useful in the context of your question.
