# Make Julia’s Error Codes Even Better Than Elm’s

**URL:** <https://discourse.julialang.org/t/make-julia-s-error-codes-even-better-than-elm-s/87409>\
**Category:** Internals & Design\
**Created:** [September 17, 2022, 4:26pm UTC](https://discourse.julialang.org/t/make-julia-s-error-codes-even-better-than-elm-s/87409 "2022-09-17T16:26:03Z")\
**Posts on this page:** 1\
**Showing post:** 51

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 12, 2022, 4:33am UTC](https://discourse.julialang.org/t/make-julia-s-error-codes-even-better-than-elm-s/87409/51 "2022-11-12T04:33:59Z")

</div>

> [@StefanKarpinski](#):
>
> Yes, that is a much better error message. Unfortunately it also tends to make functions much slower even when errors aren’t thrown because it creates a complex branch that captures all values that are used in the error message, which forces those values to be materialized and/or heap allocated. Using a static error message, on the other hand, has negligible performance impact, which is why so many error messages are like that. We have some newish technology to improve this, such as LazyString, but while that can help, it doesn’t entirely eliminate the problem. I’m planning on trying to make some better error messages like you suggest to see how bad the impact is and evaluate what kind of compiler magic we need to make it not affect performance unbearably, but it almost certainly will require some compiler work.

Does this really require compiler work? We already have `@noinline` which is sufficient for this as far as I’m aware:

```julia
my_sqrt(x::Real) = x >= 0.0 ? sqrt(x) : my_sqrt_error(x);

@noinline my_sqrt_error(x) = throw(DomainError("my_sqrt requires inputs greater than 0, you gave $x which is less than 0"));

```

```julia
julia> @benchmark my_sqrt(x) setup=(x= 100*rand())
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
 Range (min … max): 2.159 ns … 20.240 ns ┊ GC (min … max): 0.00% … 0.00%
 Time (median): 2.160 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 2.168 ns ± 0.192 ns ┊ GC (mean ± σ): 0.00% ± 0.00%

   █ ▁                                               
  ▂█▁▁▁▁▁▁▁▁▁▂█▁▁▁▁▁▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▂▃ ▂
  2.16 ns Histogram: frequency by time 2.21 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

julia> @benchmark sqrt(x) setup=(x= 100*rand())
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
 Range (min … max): 2.159 ns … 11.370 ns ┊ GC (min … max): 0.00% … 0.00%
 Time (median): 2.160 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 2.167 ns ± 0.107 ns ┊ GC (mean ± σ): 0.00% ± 0.00%

   █ ▆ ▁ ▃ ▁
  ██▁▁▁▁▁▁▁▁▁▆█▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▁▁▁▁▁▁▁▄▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▄█ █
  2.16 ns Histogram: log(frequency) by time 2.21 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

```

In fact, now that I look, it appears that whoever wrote the `sqrt(::Float64)` method in Base already knew and took advantage of this:

```julia
julia> @code_typed sqrt(1.0)
CodeInfo(
1 ─ %1 = Base.lt_float(x, 0.0)::Bool
└── goto #3 if not %1
2 ─ invoke Base.Math.throw_complex_domainerror(:sqrt::Symbol, x::Float64)::Union{}
└── unreachable
3 ─ %5 = Base.Math.sqrt_llvm(x)::Float64
└── return %5
) => Float64

```

---

_[View the full topic](https://discourse.julialang.org/t/make-julia-s-error-codes-even-better-than-elm-s/87409)._
