# \`Symbolics.value\` behavior change

**URL:** <https://discourse.julialang.org/t/symbolics-value-behavior-change/134024>\
**Category:** General Usage\
**Tags:** symbolics\
**Created:** [November 21, 2025, 12:10pm UTC](https://discourse.julialang.org/t/symbolics-value-behavior-change/134024 "2025-11-21T12:10:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![AronT](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aront/32/24890_2.png) [@AronT](https://discourse.julialang.org/u/AronT)\
**Post date:** [November 21, 2025, 12:10pm UTC](https://discourse.julialang.org/t/symbolics-value-behavior-change/134024/1 "2025-11-21T12:10:25Z")

</div>

A preface to this question. I use `Symbolics.jl` purely for study purposes and this is not an urgent question that impacts my work. Nor am I in anyway an expert in either mathematics or Julia.

So a few weeks ago as parts of my studies I implemented a Symbolics function to compute the area of an n-gon and used `Symbolics.value` to extract the numeric value after doing a substitution:

```julia-auto
using Symbolics
@variables N, b
area_formula = (1/4) * N * b^2 * cot(π/N)
area_test_simplified = simplify(substitute(area_formula, Dict(N=>3600, b=>1)))
area_numerical_value = Symbolics.value(area_test_simplified)
println("Area: ", round(area_numerical_value, digits = 6))

```

As noted as this code has nothing to do with production, I constantly update the repository as well as my version of Julia. So I am pretty sure that when I last ran this code and it worked it was with version 1.11.x. Recently I wanted to make use of a similar formula and tried the same approach and it failed. And when I reran this code it also failed with the following error:

```julia-auto
RROR: MethodError: no method matching round(::SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}, ::RoundingMode{:Nearest}; digits::Int64)
The function `round` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  round(::BigFloat, ::RoundingMode{:Nearest}) got unsupported keyword argument "digits"
   @ Base mpfr.jl:1123
  round(::Missing, ::RoundingMode; sigdigits, digits, base)
   @ Base missing.jl:144
  round(::Type{T}, ::Any, ::RoundingMode) where T>:Missing got unsupported keyword argument "digits"
   @ Base missing.jl:148
  ...

Stacktrace:
 [1] round(x::SymbolicUtils.BasicSymbolicImpl.var"typeof(BasicSymbolicImpl)"{SymReal}; kws::@Kwargs{digits::Int64})
   @ Base ./rounding.jl:472
 [2] top-level scope
   @ REPL[8]:1

```

Looking at the results it became obvious why it failed. The variable value is `900.0cot(0.0008726646259971648)` i.e. the cotangent isn’t being calculated. I read the documentation carefully and it is not clear to me what changed since I upgraded to Julia 1.12.x and the latest version of Symbolics.

I did find a workaround for my purposes by using `build_function` and evaluating the function (which is fine, since I want to iterate on this function over multiple values). However, I am curious why

1. the `substitute` no longer executes the cotangent and
2. How I can make that happen so that I can extract the final numeric value

---

<div class="post-metadata">

**Author:** ![AronT](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aront/32/24890_2.png) [@AronT](https://discourse.julialang.org/u/AronT)\
**Post date:** [November 21, 2025, 12:31pm UTC](https://discourse.julialang.org/t/symbolics-value-behavior-change/134024/2 "2025-11-21T12:31:01Z")

</div>

Digging deeper into `SymbolicsUtil.jl` documentation I found the answer. I needed to add the flag `fold=Val(true)` to the `substitute` And PS I think the `simplify` is unnecessary:

```julia-auto
area_test_simplified = substitute(area_formula, Dict(N=>3600, b=>1); fold=Val(true))
area_numerical_value = Symbolics.value(area_test_simplified)
println("Area: ", round(area_numerical_value, digits = 6))
Area: 1.031323769436e6

```

The only thing still not clear to me is whether this flag is a recent requirement, and if not, why did it work in the past.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [November 21, 2025, 8:53pm UTC](https://discourse.julialang.org/t/symbolics-value-behavior-change/134024/3 "2025-11-21T20:53:39Z")

</div>

> [@AronT](#):
>
> The only thing still not clear to me is whether this flag is a recent requirement, and if not, why did it work in the past.

There was a recent breaking release, SymbolicUtils v4 and Symbolics v7, which changed the internal representation and this was one of the changes that reflects from that. All operations are type-stable, and thus they return a symbolic value. There is a symbolic Const type in the sumtype now that holds it. Folding is thus not a default because it’s cannot be made type-stable, so the standard simplification does not do numerical evaluation without the user explicitly asking for it. And I kind of think that makes sense because symbolic manipulation and running an interpreter for numerical calculations are kind of two different things, so it was kind of weird that we always merged those together (and then paid an extremely high startup time price because every simplify call was deeply not type-stable).

---

<div class="post-metadata">

**Author:** ![AronT](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aront/32/24890_2.png) [@AronT](https://discourse.julialang.org/u/AronT)\
**Post date:** [November 26, 2025, 11:13am UTC](https://discourse.julialang.org/t/symbolics-value-behavior-change/134024/4 "2025-11-26T11:13:25Z")

</div>

Thanks @ChrisRackauckas for this detailed explanation. This change makes a lot of sense. I’m glad I understand it now and it’s not a mistake I was making!
