Metaprogramming | String to Symbolics Num; eval(Meta.parse(. . .))

Audrius-St
Wed, 03 Sep 2025 18:58:38 +0000
General Usage

Hello,

Context. I am using SymPy.solveset(. . .) within a function to solve an equation. I first convert the Symbolics Num equation to a string, pass it to the function, and within the function use
SymPy.sympy.parse_expr(eqtn_str) to convert it a SymPy expression and finally solve it.

The test solution is retuned as
sltn = Set(Sym[-l*(g*l*m*t*cos(θ) - l^2*m/t)/(g*t^2*sin(θ))])

Extracted from the Set using first(sltn) the result is

(typeof(sltn_pyobject), sltn_pyobject) = (Sym{PyCall.PyObject}, -l*(g*l*m*t*cos(θ) - l^2*m/t)/(g*t^2*sin(θ)))

which is then converted to a string

(typeof(sltn_str), sltn_str) = (String, "-l*(g*l*m*t*cos(θ) - l^2*m/t)/(g*t^2*sin(θ))")

and returned from the function.

Issue. I would like to convert the returned string back to a Symbolics expression. Based on the discussion in

How to convert a string to a symbolic expression? General Usage

How can I convert a string to a symbolic expression? The following code fails: using Symbolics @variables R a A Γ ρ U Q Q1 Q = 0.5A*R*a*Γ*ρ*(U^2) Q_string::String = repr(Q) # how to convert Q_string back into a symbolic expression of type Num? # this is not doing what I want to Q1=Num(Q_string) tree = Symbolics.unwrap(Q) tree1 = Symbolics.unwrap(Q1) @assert istree(tree) # this assertion fails @assert istree(tree1)

I attempted use eval(Meta.parse(sltn_str)), but encounter a metaprogramming error that I don’t understand.

ERROR: LoadError: UndefVarError: lnot defined inMain`

I suspect that it have something to do with scope, but not having used metaprogramming before, I’m at a bit of a loss on how to fix the issue.

Alternatively, if there is a better method to convert a SymPy PyObject expression to a Symbolics Num expression, I’d appreciate learning how to do so.

Below is a MNWE that reproduces the issue:

# test_eval_Meta_parse.jl

using Symbolics

function eval_String_to_Num(
            θ::Num,
            p::Num,
            t::Num,
            g::Num,
            l::Num,
            m::Num
        )
    # Specifying the variable here also does not work.
    # @variables θ, p, t
    # @variables g, l, m

    expr_str = "-l*(g*l*m*t*cos(θ) - l^2*m/t)/(g*t^2*sin(θ))"

    # Ref. https://discourse.julialang.org/t/how-to-convert-a-string-to-a-symbolic-expression/104527

    expr_parsed = Meta.parse(expr_str)
    @show expr_parsed
    println("")

    expr = eval(expr_parsed)

    @show expr
    println("")
end

function main()
    @variables θ, p, t
    @variables g, l, m

    eval_String_to_Num(
        θ,
        p,
        t,
        g,
        l,
        m
    )
end

begin
    main()
end

The full error message is as follows:

ERROR: LoadError: UndefVarError: `l` not defined in `Main`
Suggestion: check for spelling errors or missing imports.
Stacktrace:
 [1] top-level scope
   @ none:1
 [2] eval
   @ ./boot.jl:430 [inlined]
 [3] eval
   @ ./sysimg.jl:48 [inlined]
 [4] eval_String_to_Num()
   @ Main ~/projects/Hamiltonian/test/test_eval_Meta_parse.jl:26
 [5] main()
   @ Main ~/projects/Hamiltonian/test/test_eval_Meta_parse.jl:36
 [6] top-level scope
   @ ~/projects/Hamiltonian/test/test_eval_Meta_parse.jl:49
 [7] include(fname::String)
   @ Main ./sysimg.jl:38
 [8] top-level scope
   @ REPL[1]:1
in expression starting at /home/audrius/projects/Hamiltonian/test/test_eval_Meta_parse.jl:48

4 posts - 2 participants