# Fast way to evaluate arithmetic and logical expressions at run time

**URL:** <https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102>\
**Category:** General Usage\
**Created:** [April 13, 2019, 12:58am UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102 "2019-04-13T00:58:10Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)\
**Post date:** [April 13, 2019, 12:58am UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/1 "2019-04-13T00:58:10Z")

</div>

I have some expressions generated at run time, for example, `:(3.4 - 1.0 > 1.2 - 1.4^2)` and `:(2.3^4 - 3.4^3 + 1.2^3)`. They do not involve any symbols, they just deal with numbers. Is there any efficient way to evaluate them at run time? (`eval` is not an option). I tried `JuliaInterpreter.@interpret` with no success because I would need some sort of `interpret` function and not a macro.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 13, 2019, 1:36am UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/2 "2019-04-13T01:36:53Z")

</div>

> [@RaulDurand](#):
>
> I have some expressions generated at run time

How are they being generated at runtime? You need to provide more context.

You mentioned something about “user input” in another thread. What is the UI? Why can’t the user just pass a function directly?

---

<div class="post-metadata">

**Author:** ![Adrien](https://avatars.discourse-cdn.com/v4/letter/a/ea666f/32.png) [@Adrien](https://discourse.julialang.org/u/Adrien)\
**Post date:** [April 13, 2019, 9:46am UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/3 "2019-04-13T09:46:10Z")

</div>

Why isn’t eval an option ? That’s kind of what it’s for. Alternatively you might want to use a package like [this one](https://github.com/chakravala/Reduce.jl) which is designed to manipulate formal mathematical expressions.

---

<div class="post-metadata">

**Author:** ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)\
**Post date:** [April 13, 2019, 1:36pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/4 "2019-04-13T13:36:19Z")

</div>

> [@stevengj](#):
>
> How are they being generated at runtime? You need to provide more context.

The user provides conditionals to specify a set of points in a 3d space, something like: `select(points, :(x>1))` or `select(points, :(y+x==4))`. Due to numerical errors the expressions are modified at run time to include a tolerance. Thus they become: `:(x>1+tol)` and `:(abs(y+x-4)<tol)`. Later for each conditional a function is defined (using eval) and finally invoked for all point coordinates.  
An input function would be ideal instead of expressions, however it would be cumbersome for the user to think about tolerances each time a selection is made.

I know that eval provides performance issues and defining a function at run time triggers recompilation. That is why I am looking for an alternative approach.

---

<div class="post-metadata">

**Author:** ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)\
**Post date:** [April 13, 2019, 1:51pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/5 "2019-04-13T13:51:36Z")

</div>

I found that `Base.Cartesian.exprresolve_conditional()` almost does what I want and it seems to be very fast. It can evaluate expressions like `:(3.0 < 4.0)` but not `:(3.0 + 1.0 < 5.0)`

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 13, 2019, 2:07pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/6 "2019-04-13T14:07:14Z")

</div>

I would do something like this: the user specifies a closure (you can make this easier with a macro that transforms

```julia
@something x > 1

```

to

```julia
x -> x > 1

```

etc), your implementation defines a wrapper type

```julia
struct Tolerant{T}
    x::T
end

Base.(<)(x::Tolerant, y) = x < y + tol

```

and wraps all the inputs before calling that closure.

---

<div class="post-metadata">

**Author:** ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)\
**Post date:** [April 13, 2019, 2:24pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/7 "2019-04-13T14:24:59Z")

</div>

That’s interesting. Thus may be I can do something like

```julia
select(points, @makefun(x==1 && y>1) )

```

that is transformed to

```julia
select(points, (x,y,tol) -> (abs(x-1)<tol && y>1+tol) )

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 13, 2019, 2:42pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/8 "2019-04-13T14:42:14Z")

</div>

Close, but as I said, don’t add `tol` at the expression level, let dispatch take care of it. It is much easier to implement, debug, and maintain.

---

<div class="post-metadata">

**Author:** ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)\
**Post date:** [April 13, 2019, 2:54pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/9 "2019-04-13T14:54:04Z")

</div>

> [@Tamas\_Papp](#):
>
> don’t add `tol` at the expression level, let dispatch take care of it. It is much easier to implement, debug, and maintain.

Great!, then I think I have to define a set of arithmetic operators:

```julia
Base.(+)(x::Tolerant, y) = x.x + y
Base.(-)(x::Tolerant, y) = x.x - y
Base.(*)(x::Tolerant, y) = x.x * y
Base.(<)(x::Tolerant, y) = x.x < y + tol
Base.(>)(x::Tolerant, y) = x.x > y - tol
and so on...

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 13, 2019, 2:55pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/10 "2019-04-13T14:55:36Z")

</div>

Precisely. This has the advantage that the user cannot “escape” your mini-DSL, for methods that you did not define.

You can also simplify the generation of the above with a macro.

---

<div class="post-metadata">

**Author:** ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)\
**Post date:** [April 13, 2019, 2:56pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/11 "2019-04-13T14:56:29Z")

</div>

Thanks a lot @Tamas_Papp and thanks all for the advice!

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 13, 2019, 3:45pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/12 "2019-04-13T15:45:58Z")

</div>

> [@RaulDurand](#):
>
> Due to numerical errors the expressions are modified at run time to include a tolerance.

Why not just have the user specify inequality constraints of the form `f(x)<=0` and/or equality constraints of the form `h(x)==0` — that is, the user supplies the functions `f` and/or `h` as ordinary functions (not expressions). Then you can internally check `f(x) <= tol` and `abs(h(x))<= tol` as desired.

This way, the user can define arbitrary Julia functions as complicated as they want, not restricted to symbolic expressions that you know how to analyze.

Furthermore, instead of using a heuristic tolerance, you could alternatively use [interval arithmetic](https://github.com/JuliaIntervals/IntervalArithmetic.jl): pass an instance of an interval type for `x`, and then you can check rigorously whether the output may possibly satisfy the constraints up to roundoff errors.

---

<div class="post-metadata">

**Author:** ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)\
**Post date:** [April 13, 2019, 9:27pm UTC](https://discourse.julialang.org/t/fast-way-to-evaluate-arithmetic-and-logical-expressions-at-run-time/23102/13 "2019-04-13T21:27:54Z")

</div>

That’s a nice solution also. Thanks a lot 😉
