# \[ANN\] New package: CallableExpressions v1.0.0

**URL:** <https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698>\
**Category:** Package Announcements\
**Tags:** package, announcement, symbolic\
**Created:** [May 24, 2024, 7:04pm UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698 "2024-05-24T19:04:13Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 24, 2024, 7:04pm UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/1 "2024-05-24T19:04:13Z")

</div>

The `CallableExpressions` package is being registered: [New package: CallableExpressions v1.0.0 by JuliaRegistrator · Pull Request #107598 · JuliaRegistries/General · GitHub](https://github.com/JuliaRegistries/General/pull/107598)

> A Julia package for representing, manipulating and evaluating trees of expressions.

The design is quite different from that of DynamicExpressions.jl and SimpleExpressions.jl.

Once the package is registered it’d have a JuliaHub package page at CallableExpressions.jl.

Git repository on Gitlab:

> **[Neven Sajko / CallableExpressions.jl · GitLab](https://gitlab.com/nsajko/CallableExpressions.jl)**
>
> A Julia package for representing, manipulating and evaluating trees of expressions.

### Suggestions are welcome

The package isn’t registered yet, so any kind of suggestion is welcome.

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [May 24, 2024, 9:58pm UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/2 "2024-05-24T21:58:48Z")

</div>

I wonder if you’d be interested in [Home · FixArgs.jl](https://goretkin.github.io/FixArgs.jl/dev/) (it needs some love)

```julia
julia> using FixArgs

julia> f = @xquote (x, y) -> y*sind(x-5)
FixNew(FixArgs.Arity{2, Nothing}(),Some(*),FrankenTuple((arg_pos(2, 0), Call(Some(sind), FrankenTuple((Call(Some(-), FrankenTuple((arg_pos(1, 0), Some(5)), NamedTuple())),), NamedTuple()))), NamedTuple()))

julia> f(17.9, 2)
0.4465002320219027

# instead of storing 5 "dynamically", store it statically

julia> f2 = @xquote (x, y) -> y*sind(x-5::::S)
FixNew(FixArgs.Arity{2, Nothing}(),Some(*),FrankenTuple((arg_pos(2, 0), Call(Some(sind), FrankenTuple((Call(Some(-), FrankenTuple((arg_pos(1, 0), Val{5}()), NamedTuple())),), NamedTuple()))), NamedTuple()))

julia> f2(17.9, 2)
0.4465002320219027

```

---

<div class="post-metadata">

**Author:** ![Julius\_Martensen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/julius_martensen/32/17077_2.png) [@Julius\_Martensen](https://discourse.julialang.org/u/Julius_Martensen)\
**Post date:** [May 25, 2024, 5:04am UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/3 "2024-05-25T05:04:04Z")

</div>

Nice! How does this compare in terms of type stability and performance of evaluation to a normal function? I am just curious because I‘ve cooked up some implementations of this myself and rely heavily on packages like ModelingToolkit.jl and or DynamicExpressions.jl .

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 25, 2024, 9:21am UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/4 "2024-05-25T09:21:07Z")

</div>

> [@Julius\_Martensen](#):
>
> How does this compare in terms of type stability and performance of evaluation to a normal function?

The package is very much designed for enabling maximum performance of evaluation, and for preserving type stability. EDIT: AD (at least with Zygote.jl) is currently not at all performant, and it’s not inferred as type-stable either. Looking into this currently.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 1, 2024, 9:07pm UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/5 "2024-06-01T21:07:31Z")

</div>

> [@nsajko](#):
>
> AD (at least with [Zygote.jl](https://juliahub.com/ui/Packages/General/Zygote)) is currently not at all performant, and it’s not inferred as type-stable either. Looking into this currently.

Preliminary fix released with CallableExpressions.jl v1.1.0 (registered). The AD performance is only good for Julia at least v1.11 (so it’s necessary to use the current beta release of Julia for good AD performance). Currently only reverse mode is well-tested. The AD performance fixes currently only apply to expressions with less than two variables.

@aramend can you test this out, see what’s missing/broken, xref [Performance optimizations with runtime dispatch](https://discourse.julialang.org/t/performance-optimizations-with-runtime-dispatch/110653/)

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/224680_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 2, 2024, 2:28pm UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/6 "2024-06-02T14:28:50Z")

</div>

It seems you’re using DifferentiationInterface.jl for your AD tests? Very nice to see it pop out in the wild! Do reach out if you run into any trouble

---

<div class="post-metadata">

**Author:** ![aramend](https://avatars.discourse-cdn.com/v4/letter/a/a88e57/32.png) [@aramend](https://discourse.julialang.org/u/aramend)\
**Post date:** [June 3, 2024, 10:20am UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/7 "2024-06-03T10:20:25Z")

</div>

The AD performance (using Zyogte again) definitely improved using 1.11.0-beta2, but is still in the 10s of microseconds for even simple expressions.

But to apply this in symbolic AI, we have to be aware that hundreds of thousands or even millions of different expressions will be created and evaluated. The static approach means compile time overhead for every new expression, which more than offsets the improved evaluation speed. Not to mention that since the expressions live in the type level, method tables gradually explode as well.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 3, 2024, 10:39am UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/8 "2024-06-03T10:39:09Z")

</div>

> [@aramend](#):
>
> hundreds of thousands or even millions of different expressions will be created

Yeah, CallableExpressions.jl probably isn’t a good choice in that case.

---

<div class="post-metadata">

**Author:** ![aramend](https://avatars.discourse-cdn.com/v4/letter/a/a88e57/32.png) [@aramend](https://discourse.julialang.org/u/aramend)\
**Post date:** [June 3, 2024, 10:42am UTC](https://discourse.julialang.org/t/ann-new-package-callableexpressions-v1-0-0/114698/9 "2024-06-03T10:42:29Z")

</div>

But if you are expecting to run only a few expressions (that you don’t know before runtime) many many times, this is the way to do it 🙂

The minimal LLVM code is very nice and pretty much human-readable.
