# Modifying Julia code using macros to substitute variables

**URL:** <https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921>\
**Category:** General Usage\
**Tags:** question, macros, metaprogramming\
**Created:** [November 8, 2023, 2:41am UTC](https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921 "2023-11-08T02:41:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Akhil\_Akkapelli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akhil_akkapelli/32/202792_2.png) [@Akhil\_Akkapelli](https://discourse.julialang.org/u/Akhil_Akkapelli)\
**Post date:** [November 8, 2023, 2:41am UTC](https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921/1 "2023-11-08T02:41:07Z")

</div>

I’m trying to create a Julia macro to substitute specific variables in a Julia program with new ones. I have a working example, but I’m facing a challenge when I need to reassign variables within nested functions.

Here’s a simplified version of my Input code:

```julia
module m1

using sub_vars

function f1()
  @declare_newvar v1 v_1 1
  v2 = 2

  function f2()
    v3 = v1 + v2
    @declare_newvar v1 v^1 4
    v4 = v1 + v3
    v1 = v1 + v4
  end

  f2()
end

f1()
end

```

where

```julia
module sub_vars

?

macro declare_newvar(orig_var :: Symbol, new_var :: Symbol, val :: Any)
  ?
end 

end 

```

The **`@declare_newvar`** macro should replace **`v1`** with **`v_1`** and **`v^1`** in the code as specified.

I would like to get the desired output:

```julia
module m1

using sub_vars

function f1()
  v_1 = 1
  v2 = 2

  function f2()
    v3 = v_1 + v2
    v^1 = 4
    v4 = v^1 + v3
    v^1 = v^1 + v4
  end

  f2()
end

f1()
end

```

Approaches to tackle this issue:

1. Transform the code into an Expr variable and employ a relevant package to identify variable scopes. Subsequently, navigate through the Abstract Syntax Tree (AST) and modify the Expr variable accordingly.
2. Create and maintain a Symbol Table within the sub\_vars module. Utilize macros to capture essential information during passes and employ this data to facilitate variable substitution.

Are there any alternative methods to address this problem?

---

<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:** [November 8, 2023, 3:40am UTC](https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921/2 "2023-11-08T03:40:09Z")

</div>

> [@Akhil\_Akkapelli](#):
>
> I’m trying to create a Julia macro to substitute specific variables in a Julia program with new ones.

Can you give us more context? Why not just use function arguments to substitute in values for variables?

---

<div class="post-metadata">

**Author:** ![Akhil\_Akkapelli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akhil_akkapelli/32/202792_2.png) [@Akhil\_Akkapelli](https://discourse.julialang.org/u/Akhil_Akkapelli)\
**Post date:** [November 8, 2023, 3:54am UTC](https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921/3 "2023-11-08T03:54:05Z")

</div>

> [@stevengj](#):
>
> Can you give us more context? Why not just use function arguments to substitute in values for variables?

Functions are not suitable for altering variable names within an Expr. Therefore, I opted for a macro to achieve this functionality.

---

<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:** [November 8, 2023, 4:04am UTC](https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921/4 "2023-11-08T04:04:02Z")

</div>

It’s definitely possible to traverse an expression and replace a symbol with another, though you would definitely need a different macro call on the entire `f1` function expression that treats `@declare_newvar` as tags that change the symbols’ substitutions. But it’s not clear why you would do this because the expanded code is not visible in the source code, so it’s harder to tell variables apart this way than if you replaced the text in the first place. Probably safest to find-replace in an editor one by one so you don’t accidentally replace the wrong `v1` text.

Also, `v^1` is not a valid variable name, it does `^(v, 1)`. Unicode however does support `v¹`, you just type `v\^1<TAB>` in the REPL or whatever editor supports this tab completion.

---

<div class="post-metadata">

**Author:** ![Akhil\_Akkapelli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akhil_akkapelli/32/202792_2.png) [@Akhil\_Akkapelli](https://discourse.julialang.org/u/Akhil_Akkapelli)\
**Post date:** [November 8, 2023, 4:20am UTC](https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921/5 "2023-11-08T04:20:32Z")

</div>

> [@Benny](#):
>
> It’s definitely possible to traverse an expression and replace a symbol with another, but it’s not clear why you would do this because the expanded code is not visible in the source code, so it seems simpler just to replace the text in the first place. Probably safest to find-replace in an editor one by one so you don’t accidentally replace something else that happens to have `v1` in the text.
> 
> Also, `v^1` is not a valid variable name, it does `^(v, 1)`. Unicode however does support `v¹`, you just type `v\^1<TAB>` in the REPL or whatever editor supports this tab completion.

I prefer using this approach because the variable names I need to use are lengthy and intricate, which can make the code less visually appealing. Shortening the variable names might sacrifice clarity and meaning. By adopting this approach, I discover it more user-friendly for code composition, and I retain the ability to retrieve the original code as required later on.

---

<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:** [November 8, 2023, 4:27am UTC](https://discourse.julialang.org/t/modifying-julia-code-using-macros-to-substitute-variables/105921/6 "2023-11-08T04:27:42Z")

</div>

> [@Akhil\_Akkapelli](#):
>
> I prefer using this approach because the variable names I need to use are lengthy and intricate

I see, so you had made a MWE. Regardless of how long the variable names, it’s definitely a bad idea to have the same text represent different variables depending on where `@declare_newvar` tags are instead of something built in the language like local scopes. You are right to stick to shorter variable names that are easier to read and write, but you can put whatever longer intricate descriptions in comments next to the variable e.g. `v_1 = 3 # voltage at breaker in basement level 1` and `v¹ = 4 # voltage at breaker at ground level`, it’s just as clear. Too much metaprogramming can obscure what an algorithm does, so macros should only be used for more drastic algorithmic changes, not mere variable renaming.
