# Replace symbols within an expression

**URL:** <https://discourse.julialang.org/t/replace-symbols-within-an-expression/96966>\
**Category:** General Usage\
**Tags:** metaprogramming\
**Created:** [April 2, 2023, 10:58am UTC](https://discourse.julialang.org/t/replace-symbols-within-an-expression/96966 "2023-04-02T10:58:40Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [April 2, 2023, 10:58am UTC](https://discourse.julialang.org/t/replace-symbols-within-an-expression/96966/1 "2023-04-02T10:58:41Z")

</div>

I want to take an expression like

```julia
:(structOne.a[I] = tanh(structTwo.b[I]))

```

and replace all the composite values with other variables so I can make a function like

```julia
function f(I,a_new,b_new) # can't use composite values here
   a_new[I] = tanh(b_new[I]) # original expression with new symbols inserted
end
f(I,structOne.a,structTwo.b) # call

```

I know how to recursively find all the symbols in an expression, and I can look for the `:(.)` to isolate composite values, and I can use `@gensym` to make replacement symbol names.

But how can I make the expression `a_new[I] = tanh(b_new[I])` which has the same form as the original expression but replaces the composites values with the new symbols?

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [April 2, 2023, 11:15am UTC](https://discourse.julialang.org/t/replace-symbols-within-an-expression/96966/2 "2023-04-02T11:15:55Z")

</div>

Do you mean, something like this?

```julia
julia> ex = :(structOne.a[I] = tanh(structTwo.b[I]))
:(structOne.a[I] = tanh(structTwo.b[I]))

julia> rep(ex) = ex
       rep(ex::Expr) = ex.head == :. ? Symbol(ex.args[2].value, "_new") : ex
       rep!(ex) = ex
       rep!(ex::Expr) = (ex.args = map(rep, ex.args); foreach(rep!, ex.args); ex)
rep! (generic function with 2 methods)

julia> rep!(ex)
:(a_new[I] = tanh(b_new[I]))

```

---

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [April 2, 2023, 11:48am UTC](https://discourse.julialang.org/t/replace-symbols-within-an-expression/96966/3 "2023-04-02T11:48:40Z")

</div>

Perfect example. Thanks!

---

<div class="post-metadata">

**Author:** ![eliascarv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eliascarv/32/22152_2.png) [@eliascarv](https://discourse.julialang.org/u/eliascarv)\
**Post date:** [April 2, 2023, 9:48pm UTC](https://discourse.julialang.org/t/replace-symbols-within-an-expression/96966/4 "2023-04-02T21:48:53Z")

</div>

This is my solution, inspired by @uniment’s solution but using “for loop”:

```julia-repl
julia> makesym(expr::Expr) = Symbol(expr.args[2].value, "_new")
makesym (generic function with 1 method)

julia> function preprocess!(expr::Expr)
           for (i, arg) in enumerate(expr.args)
               if arg isa Expr
                   if arg.head === :(.)
                       expr.args[i] = makesym(arg)
                   else
                       preprocess!(arg)
                   end
               end
           end
           expr
       end
preprocess! (generic function with 1 method)

julia> expr = :(obj1.a[i] = tanh(obj2.b[i]))
:(obj1.a[i] = tanh(obj2.b[i]))

julia> preprocess!(expr)
:(a_new[i] = tanh(b_new[i]))

```
