How to convert a symbol to a string of variable it represent

julia> expr = :a + 3 * :b
:a + 3:b

julia> string(expr)
":a + 3:b"

How do I convert an expression with symbols in it to a string representing the variables that the symbol represent?

I want “a + 3 b” instead of “:a + 3 :b”

Oh yeah, my use case. I am trying to do symbolic differentiation

julia> using Symata

julia> answer = @sym D(3x^4,x)
12
:x^3

julia> answer = replace(string(answer), “:” => “”)

julia> eval(Meta.parse("func = x -> $answer”))
#3 (generic function with 1 method)

julia> func(5)
1500

This is not valid Julia code apparently:

julia> expr = :a + 3 * :b
ERROR: MethodError: no method matching *(::Int64, ::Symbol)
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:538
  *(::T, ::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:87
  *(::Union{Int16, Int32, Int64, Int8}, ::BigInt) at gmp.jl:538
  ...
Stacktrace:
 [1] top-level scope at REPL[32]:100:
2 Likes

If you have

julia> ex = :(a + 3*b)
:(a + 3b)

julia> string(ex)
"a + 3b"

then it works.

You might want to look into ModelingToolkit for symbolics:

julia> using ModelingToolkit

julia> @variables a, b
(a, b)

julia> ex = a + 3b
a + 3b

julia> string(ex)
"a + 3b"
1 Like

It worked in Symata

julia> using Symata

julia> answer = @sym D(3x^4,x)
12*:x^3

julia> answer
12*:x^3

julia> expr = :a + 3 * :b
:a + 3:b

It is valid julia code as much a error() is valid julia code. (edit: and by valid julia code I mean :a + 3 * :b is a valid expression)

While you should not use string to do anything serious, this is basically the same issue as Printing of multiplication and vs. UInt16 etc. · Issue #36108 · JuliaLang/julia · GitHub which is fixed on master now by fix #36108, printing invalid numeric juxtapositions by JeffBezanson · Pull Request #36122 · JuliaLang/julia · GitHub.

This won’t happen since they aren’t the same expression.

1 Like

Can you explain what you are trying to do at a higher level? I mean can you explain the problem you are trying to solve, rather than talking about the method you are trying to solve it. It could be a good approach, but there may be other, better approaches.

2 Likes

You might want

julia> @sym answer = D(3x^4, x)
12*:x^3

julia> func = @sym Compile([x], Evaluate(answer))
#3 (generic function with 1 method)

julia> func(5)
1500

or

julia> @sym expr = 3a + b
3:a + :b

julia> func1 = @sym Compile([a, b], Evaluate(expr))
#5 (generic function with 1 method)

julia> func1(1, 2)
5

This is a bug in Symata. Defining a method that allows 3 * :b is type piracy. This method was meant to be opt in, rather than on by default.

1 Like

This is what I was trying to achieve
Given some Julia code (of the body of a simple function)
Find the symbolic differentiation of the code
Then turn it into a function
To use in Newton-Raphson method
https://en.wikipedia.org/wiki/Newton%27s_method

julia> using Symata

julia> expr = :( 3 * x^4)
:(3 * x ^ 4)

julia> eval(Meta.parse("@sym answer = D($expr,x)"))
12*:x^3

julia> func = @sym Compile([x], Evaluate(answer))
#3 (generic function with 1 method)

julia> func(5)
1500

You don’t need symbolic differentiation for this – you can use automatic differentiation using e.g. https://github.com/JuliaDiff/ForwardDiff.jl

But ModelingToolkit can find and use the symbolic derivative.

2 Likes