Is there any straight way or a function to substitute symbols in an expression?

For example:

```
ex = :(x + x^2 + x^3)
substitute(ex, :x => :y) # yields :(y + y^2 + y^3)
substitute(ex, :x => 1.5) # yields :(1.5 + 1.5^2 + 1.5^3)
```

Is there any straight way or a function to substitute symbols in an expression?

For example:

```
ex = :(x + x^2 + x^3)
substitute(ex, :x => :y) # yields :(y + y^2 + y^3)
substitute(ex, :x => 1.5) # yields :(1.5 + 1.5^2 + 1.5^3)
```

```
julia> function rep!(e, old, new)
for (i,a) in enumerate(e.args)
if a==old
e.args[i] = new
elseif a isa Expr
rep!(a, old, new)
end
## otherwise do nothing
end
e
end
rep! (generic function with 1 method)
julia> rep!(:(x + x^2 + x^3), :x, :y)
:(y + y ^ 2 + y ^ 3)
julia> rep!(:(x + x^2 + x^3), :x, 1.5)
:(1.5 + 1.5 ^ 2 + 1.5 ^ 3)
```

1 Like

With the MacroTools package you can do

```
using MacroTools
ex = :(x + x^2 + x^3)
MacroTools.postwalk(ex -> ex == :x ? :y : ex, ex)
MacroTools.postwalk(ex -> ex == :x ? 1.5 : ex, ex)
```

3 Likes

This is how you could do it with my Reduce.jl package

```
julia> using Reduce
Reduce (Free CSL version, revision 4590), 11-May-18 ...
julia> ex = :(x+x^2+x^3)
:(x + x ^ 2 + x ^ 3)
julia> rcall(:(x=y)); rcall(ex)
:((y ^ 2 + y + 1) * y)
julia> rcall(:(x=1.5)); rcall(ex)
:(57 / 8)
```

Alternatively, you can also use the `Reduce.Algebra.sub`

method,

```
julia> using Reduce
Reduce (Free CSL version, revision 4590), 11-May-18 ...
julia> ex = :(x+x^2+x^3)
:(x + x ^ 2 + x ^ 3)
julia> Algebra.sub(:x=>:y,ex)
:((y ^ 2 + y + 1) * y)
julia> Algebra.sub(:x=>1.5,ex)
:(57 / 8)
```

which is closer to your original proposal and is probably better than my original example

2 Likes

Thanks all for the nice suggestions. I also found a native function:

```
Base.Cartesian.lreplace(:(x + x^2 + x^3), :x, 1)
```

but it does not work with float numbers.