# Substitute symbols in expression

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.