# When to return NaN vs throw an Error?

**URL:** https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587
**Category:** General Usage
**Tags:** question
**Created:** [November 1, 2022, 1:42am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587 "2022-11-01T01:42:36Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![Alec\_Loudenback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alec_loudenback/32/278_2.png) [@Alec\_Loudenback](https://discourse.julialang.org/u/Alec_Loudenback)
#### Post date: [November 1, 2022, 1:42am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/1 "2022-11-01T01:42:36Z")

</div>

I have a function with a [suggested PR](https://github.com/JuliaActuary/ActuaryUtilities.jl/pull/92#issuecomment-1297152876) to throw an error if the result would return a `NaN`. I am very much appreciative of someone opening a PR but I was looking for advice on the approach.

I am unsure if it is better package design to through an error, with some helpful pointers, or to let `NaN`s and `Inf`s result?

The function in question is essentially:

```julia
function ratio(v::T) where {T<:AbstractArray}
    positive = sum(x for x in v if x > 0)
    negative = -sum(x for x in v if x < 0)
    return positive / negative
end

```

In the cases where there are not values with opposite signs or all zeros this function will return a variety of `NaN`/`Inf`.

The applied context here is in the [ActuaryUtilities.jl](https://github.com/JuliaActuary/ActuaryUtilities.jl) package and is part of a broader set of risk metrics.

---

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [November 1, 2022, 3:36am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/2 "2022-11-01T03:36:06Z")

</div>

I don’t know that such a question has a singular generalizable answer; I think it depends on context.

There are some occasions where throwing an error on `NaN` values would prematurely terminate a calculation which yields a non-`NaN` result, similar to how imaginary numbers are sometimes needed for intermediate steps in calculations that begin and end in reals.

However, in your context I suspect `NaN` will simply confuse the users with no benefit, so it likely offers more information and has zero usability cost to throw an error. Indeed, `NaN` itself I believe has a confusing name, because it arises from calculations which do result in numbers but just need L’Hôpital’s rule to solve properly (i.e. they’re numbers whose values are unknown to the program), so `NaN` is itself a misnomer.

However, I am not a subject matter expert on what types of calculations will be involved in your package.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [November 1, 2022, 6:57am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/3 "2022-11-01T06:57:16Z")

</div>

> [@Alec\_Loudenback](#):
>
> I am unsure if it is better package design to through an error, with some helpful pointers, or to let `NaN`s and `Inf`s result?

As mentioned above, the context matters here - is there a meaning to a ratio that only has positive entries? If you can’t make that decision in the library, to me at least, this indicates an edge case that users should have to actively think about when using your library, lest they get wrong results.

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [November 1, 2022, 8:45am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/4 "2022-11-01T08:45:29Z")

</div>

As someone doing something vaguely adjacent at the minute I’d say errors are good - I’m reusing an old project at the minute which I wrote years ago to value loan books, and have been stumpted for a couple of days by random `NaN` poisoning my results when using the code with new data. Some of this I’ve worked out (e.g. the data erroneously had some zero interest rates which the code didn’t handle), but it definitely would have been easier if I’d handled this more explicitly.

So yes in the example you give in your OP I’d vote for handling this explicitly. I’m not an actuary so there might be something I’m missing but to me calculating `moic` when there are no contributions and it’s likely that the user is either calling this function in some larger pipeline where they didn’t expect an individual corner case (similar to my zero-interest-rate example above) or are misunderstanding the function.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [November 1, 2022, 12:11pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/5 "2022-11-01T12:11:17Z")

</div>

I would raise an error in this function only if the sum of negative numbers being zero would be considered an error. Otherwise I would return a NaN if either positives and/or negatives are zero, or perhaps better, return both `positive` and `negative` and let the caller the responsibility on what to do with them.

---

<div class="post-metadata">

### Author: ![Alec\_Loudenback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alec_loudenback/32/278_2.png) [@Alec\_Loudenback](https://discourse.julialang.org/u/Alec_Loudenback)
#### Post date: [November 1, 2022, 9:55pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/6 "2022-11-01T21:55:29Z")

</div>

Thanks for the feedback, all. What about the in-between solution of logging an `@warn`? I’m kind of leaning towards _not_ erroring because an input that may be a valid vector for other functions would error in this one and potentially needlessly halt the program.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [November 1, 2022, 10:04pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/7 "2022-11-01T22:04:51Z")

</div>

Another option is returning Some(x)/nothing or using Try.jl and the caller can unwrap the value.

I don’t think warning will be helpful. The user should be forced to handle the empty case.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [November 1, 2022, 10:28pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/8 "2022-11-01T22:28:14Z")

</div>

warnings in backend packages are generally not great.  
Because often one either cares, or does not care.  
If one cares one needs to fix the warning, and it would be easier to fix if it is an error.  
and if one doesn’t care then the warning is an annoyance.  
Often flooding the screen if you call it in a loop, or triggering an alarm if the code is running on a monitored system.  
So either way one often wants to make sure the warning doesn’t happen, so its better if it is an error.

This isn’t always the case, but it is often the case.  
If you know a lot about your end user you can better make the call.  
But for a backend mathematicalk library you often don’t.

It’s rather annoying to silence warnings case by case in julia.  
(Though I think we put code for how to do that, somewhere in the [JuliaLogging website](https://julialogging.github.io/). If not we should)

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [November 1, 2022, 10:32pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/9 "2022-11-01T22:32:24Z")

</div>

> [@joa-quim](#):
>
> Otherwise I would return a NaN if either positives and/or negatives are zero

Unless _both_ are zero, it should simply be `0` or `Inf`, no?

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [November 1, 2022, 10:38pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/10 "2022-11-01T22:38:02Z")

</div>

Why? `NaN` would be used just as a flag _number_. It all depends on how a nonfinite `positive/negative` should be dealt with.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [November 1, 2022, 11:09pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/11 "2022-11-01T23:09:39Z")

</div>

> [@joa-quim](#):
>
> Why?

Because, obviously. The OP also specifies that `Inf` is one of the valid returns. Hiding the clear information in 0 or `Inf` behind `NaN` would be very odd.

If all of `0`, `Inf` _and_ `NaN` are invalid results, then it seems pretty clear that it should be an error, not lumping them all into a `NaN`, which would give a misleading impression of what happened.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [November 1, 2022, 11:24pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/12 "2022-11-01T23:24:24Z")

</div>

If that is the case, so better is to return both the `positive` and `negative` and deal with the combinations at the caller site.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [November 1, 2022, 11:28pm UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/13 "2022-11-01T23:28:22Z")

</div>

Or, alternatively, return the `0`, `Inf` or `NaN`, and let the caller react based on that. Either of those carry the relevant information, I would think.

---

<div class="post-metadata">

### Author: ![blackeneth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blackeneth/32/10353_2.png) [@blackeneth](https://discourse.julialang.org/u/blackeneth)
#### Post date: [November 2, 2022, 1:38am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/14 "2022-11-02T01:38:11Z")

</div>

I’ve looked for general guidelines on this topic in the past and never found any.

There are several values that could be used to signal an invalid function calculation:

NaN  
Inf  
Missing  
nothing

A key question is: should the calculations halt? Or can the program recover from an invalid value?

Does Inf vs NaN provide any information on how to recover? _If it doesn’t,_ you might consolidate to NaN to signal a problem – so outside of the function the user only needs to test the return value with isnan().

Or is it valid/useful to coerce Inf and NaN to 0?

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [November 2, 2022, 1:54am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/15 "2022-11-02T01:54:23Z")

</div>

> [@blackeneth](#):
>
> NaN  
> Inf  
> Missing  
> nothing

These all have well accepted meanings. `NaN` and `Inf` are [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) floating point values.

```julia
julia> NaN isa Float64
true

julia> Inf isa Float64
true

julia> 0/0
NaN

julia> 1/0
Inf

```

`missing` represents missing data. `nothing` represents the absence of a value. `missing` is used for missing data values in a data analysis context; `nothing` is used in a general programming context, like when a function does not return anything, or when `findfirst` fails to find anything.

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [November 2, 2022, 2:53am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/16 "2022-11-02T02:53:04Z")

</div>

> [@Alec\_Loudenback](#):
>
> `positive = sum(x for x in v if x > 0)`

As a side note, this code will throw an error on Julia 1.3 or earlier if `v` does not contain any positive numbers. See this thread:

> [@Inconsistency in \`sum\` of an empty generator](https://discourse.julialang.org/t/inconsistency-in-sum-of-an-empty-generator/89638):
>
> On Julia 1.3, the following two empty generators both throw an error when you apply sum to them: julia\> g1 = (1 for i in Int[]); julia\> g2 = (x for x in [-1] if x \> 0); julia\> eltype(g1) Any julia\> eltype(g2) Any julia\> sum(g1) ERROR: ArgumentError: reducing over an empty collection is not allowed julia\> sum(g2) ERROR: ArgumentError: reducing over an empty collection is not allowed That seems like the correct behavior. On newer versions of Julia, you can avoid the error by setting the ini…

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [November 2, 2022, 6:09am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/17 "2022-11-02T06:09:59Z")

</div>

> [@CameronBieganek](#):
>
> > [@Alec\_Loudenback](#):
> >
> > `positive = sum(x for x in v if x > 0)`
> 
> As a side note, this code will throw an error on Julia 1.3 or earlier if `v` does not contain any positive numbers.

The function also passes over the data twice, and is significantly slower than single loop with

```julia
positive += ifelse(x>0, x, zero(x))
negaitive -= ifelse(x<0, x, zero(x)) 

```

On the overall question, the more I think about it, the more it seems right to return `0, Inf, NaN`, and let the caller sort it out. Each of those are perfectly valid results of a division, and might be of interest to the caller. There is nothing _intrinsically_ wrong about those results, seen from inside a function that simply calculates ratios, and there may or may not be, seen from the outside.

---

<div class="post-metadata">

### Author: ![Alec\_Loudenback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alec_loudenback/32/278_2.png) [@Alec\_Loudenback](https://discourse.julialang.org/u/Alec_Loudenback)
#### Post date: [November 12, 2022, 4:23am UTC](https://discourse.julialang.org/t/when-to-return-nan-vs-throw-an-error/89587/18 "2022-11-12T04:23:12Z")

</div>

Thank you all for the thoughtful feedback. I think I am leaning towards letting floating point math do its thing here and adding color to the docstring to clarify why this may occur. My main motivation is to avoid halting the program for throwing an error, and if I’d ask the user to handle an error… well then they may as well manage the input or decide not to call the function instead of catching the error.
