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

**URL:** <https://discourse.julialang.org/t/metaprogramming-string-to-symbolics-num-eval-meta-parse/132078>\
**Category:** General Usage\
**Tags:** question, symbolics, sympy\
**Created:** [September 3, 2025, 6:58pm UTC](https://discourse.julialang.org/t/metaprogramming-string-to-symbolics-num-eval-meta-parse/132078 "2025-09-03T18:58:38Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Audrius-St](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/audrius-st/32/24175_2.png) [@Audrius-St](https://discourse.julialang.org/u/Audrius-St)\
**Post date:** [September 3, 2025, 6:58pm UTC](https://discourse.julialang.org/t/metaprogramming-string-to-symbolics-num-eval-meta-parse/132078/1 "2025-09-03T18:58:38Z")

</div>

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?](https://discourse.julialang.org/t/how-to-convert-a-string-to-a-symbolic-expression/104527):
>
> 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: `l`not defined in`Main`

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:

```julia-auto
# 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:

```julia-auto
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

```

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [September 3, 2025, 7:49pm UTC](https://discourse.julialang.org/t/metaprogramming-string-to-symbolics-num-eval-meta-parse/132078/2 "2025-09-03T19:49:08Z")

</div>

I’m not sure if it works, but this unexported feature is supposed to do this for simple cases:

> <https://github.com/jverzani/SymPyCore.jl/blob/main/src/lambdify.jl#L139>

---

<div class="post-metadata">

**Author:** ![Audrius-St](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/audrius-st/32/24175_2.png) [@Audrius-St](https://discourse.julialang.org/u/Audrius-St)\
**Post date:** [September 4, 2025, 4:54pm UTC](https://discourse.julialang.org/t/metaprogramming-string-to-symbolics-num-eval-meta-parse/132078/3 "2025-09-04T16:54:09Z")

</div>

Thank you for the link to the SymPy ↔ Symbolics conversion code. Much appreciated.

The following MWE works

```julia-auto
# test_SymPy_to_Symbolics_v2.jl

using SymPy
using Symbolics
using SymbolicUtils

global const T_smblc = SymbolicUtils.BasicSymbolic

using SymPyCore: exchange, _issymbol, _value, _makesymbol

function parse_String_to_SymPy()

    SymPy.@syms θ, p, g, l, m

    expr_str = "-l*(g*l*m*t*cos(θ) - l**2*m/t)/(g*t**2*sin(θ))"
    expr_smp = SymPy.sympy.parse_expr(expr_str)

    return expr_smp
end

function expr_SymPy_to_Symbolics()

    expr_smp = parse_String_to_SymPy()
    @show typeof(expr_smp), expr_smp
    println("")

    _issymbol(x::T_smblc) = SymbolicUtils.issym(x)
    _value(x::T_smblc) = x
    _makesymbol(::Type{<:T_smblc}, x::Symbol) = SymbolicUtils.Sym{Number}(x)

    expr_smblc_util = exchange(T_smblc, expr_smp)

    @show typeof(expr_smblc_util), expr_smblc_util
    println("")

    expr_smblc = Num(Symbolics.wrap(expr_smblc_util))

    @show typeof(expr_smblc), expr_smblc
    println("")
end

function main()
    expr_SymPy_to_Symbolics()
end

begin
    main()
end

```

returning

```julia-auto
julia> include("test_SymPy_to_Symbolics_v2.jl")
(typeof(expr_smp), expr_smp) = (Sym{PyCall.PyObject}, -l*(g*l*m*t*cos(θ) - l^2*m/t)/(g*t^2*sin(θ)))

(typeof(expr_smblc_util), expr_smblc_util) = (SymbolicUtils.BasicSymbolic{Number}, (-((-(l^2)*m) / t + g*l*m*t*cos(θ))*l) / (g*(t^2)*sin(θ)))

(typeof(expr_smblc), expr_smblc) = (Num, (-((-(l^2)*m) / t + g*l*m*t*cos(θ))*l) / (g*(t^2)*sin(θ)))

```

Given that the Julia Metaprogramming documentation explicitly states that

> `eval` and defining new macros should be typically used as a last resort. It is almost never a good idea to use `Meta.parse` or convert an arbitrary string into Julia code.

your link is the superior solution.

---

<div class="post-metadata">

**Author:** ![Audrius-St](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/audrius-st/32/24175_2.png) [@Audrius-St](https://discourse.julialang.org/u/Audrius-St)\
**Post date:** [September 4, 2025, 7:32pm UTC](https://discourse.julialang.org/t/metaprogramming-string-to-symbolics-num-eval-meta-parse/132078/4 "2025-09-04T19:32:36Z")

</div>

For completeness, a MWE that converts from `Symbolics Num` to `SymPy Sym{PyCall.PyObject}` and back to `Symbolics Num`:

```julia-auto
# test_SymPy_to_Symbolics_v3.jl

# References 
# 1. https://github.com/jverzani/SymPyCore.jl/blob/main/src/lambdify.jl#L139

using Symbolics
using SymbolicUtils
using SymPy

using SymPyCore: exchange, _issymbol, _value, _makesymbol

global const T_smp = SymPy.Sym
global const T_smblc = SymbolicUtils.BasicSymbolic

function expr_Symbolics_to_SymPy_to_Symbolics(expr_num::Num)::Num

    expr_smblc_utls = Symbolics.unwrap(expr_num)

    @show typeof(expr_smblc_utls), expr_smblc_utls
    println("")

    SymPy.@syms θ, p, t, g, l, m
    expr_smp = exchange(T_smp, expr_smblc_utls)

    @show typeof(expr_smp), expr_smp
    println("")

    _issymbol(x::T_smblc) = SymbolicUtils.issym(x)
    _value(x::T_smblc) = x
    _makesymbol(::Type{<:T_smblc}, x::Symbol) = SymbolicUtils.Sym{Number}(x)

    expr_smblc_util = exchange(T_smblc, expr_smp)

    @show typeof(expr_smblc_util), expr_smblc_util
    println("")

    expr_smblc = Num(Symbolics.wrap(expr_smblc_util))

    return expr_smblc
end

function main()

    @variables θ, p, t, g, l, m

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

    @show typeof(expr_num), expr_num
    println("")

    expr_smblc = expr_Symbolics_to_SymPy_to_Symbolics(expr_num)

    @show typeof(expr_smblc), expr_smblc
    println("")
end

begin
    main()
end

```

returning

```julia-auto
julia> include("test_SymPy_to_Symbolics_v3.jl")
(typeof(expr_num), expr_num) = (Num, (-((-(l^2)*m) / t + g*l*m*t*cos(θ))*l) / (g*(t^2)*sin(θ)))

(typeof(expr_smblc_utls), expr_smblc_utls) = (SymbolicUtils.BasicSymbolic{Real}, (-((-(l^2)*m) / t + g*l*m*t*cos(θ))*l) / (g*(t^2)*sin(θ)))

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

(typeof(expr_smblc_util), expr_smblc_util) = (SymbolicUtils.BasicSymbolic{Number}, (-((-(l^2)*m) / t + g*l*m*t*cos(θ))*l) / (g*(t^2)*sin(θ)))

(typeof(expr_smblc), expr_smblc) = (Num, (-((-(l^2)*m) / t + g*l*m*t*cos(θ))*l) / (g*(t^2)*sin(θ)))

```
