# Mapping to mixtures of Int64 & Float64

**URL:** <https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 21, 2024, 3:23am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961 "2024-06-21T03:23:20Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [June 21, 2024, 3:23am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/1 "2024-06-21T03:23:20Z")

</div>

I have a function that can produce either `Int64` or `Float64` and I would like to map it to an array to be summed:

```julia
f(s) = parse(rand([Float64, Int64]), s)
a = rand(string.('0':'9'), rand([0,1,5]))
map(f, a) |> sum

```

If `a` is empty this fails because in that case, `map` produces an array of `Any` which cannot be summed.

The shortest solution that I can think of is:

```julia
map(f, a) |> Vector{Real} |> sum

```

but it just feels wrong to typecast everything (My application is not performance sensitive, so performance wise this is okay).

The other solutions that I can think of are:

```julia
map(f, a) |> (x -> isempty(x) ? Int64[] : x) |> sum

```

and

```julia
map(f, a) |> isempty(x) ? 0 : sum(x)

```

I’m just curious to know if someone has a better solution.

---

<div class="post-metadata">

**Author:** ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)\
**Post date:** [June 21, 2024, 3:41am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/2 "2024-06-21T03:41:00Z")

</div>

Not sure if you are focused on the sum, but if so:

```julia
sum(f,a,init=0)

```

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [June 21, 2024, 4:08am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/3 "2024-06-21T04:08:49Z")

</div>

Thank you, the sum is important to me, so this is a better solution.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 21, 2024, 5:15am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/4 "2024-06-21T05:15:10Z")

</div>

How about `sum(float ∘ f, a)`?

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [June 21, 2024, 7:14am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/5 "2024-06-21T07:14:52Z")

</div>

`sum(float ∘ f, String[])` produces a stacktrace. It is important that it can handle the empty array case.

---

<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:** [June 21, 2024, 11:33am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/6 "2024-06-21T11:33:54Z")

</div>

> [@GHTaarn](#):
>
> I have a function that can produce either `Int64` or `Float64`

Note that this will be relatively slow in Julia because it is type unstable. Why not just return a `Float64` in all cases?

(Contrary to popular misconception, integers are represented exactly by `Float64` values, up to \pm 2^{53}, so you don’t generally improve accuracy by using `Int` to store integers.)

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [June 21, 2024, 2:48pm UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/7 "2024-06-21T14:48:20Z")

</div>

Well the stacktrace actually also tells you what went wrong and how to fix it right on the top:

```julia-repl
julia> sum(float∘f, String[])
ERROR: MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Stacktrace:
...

```

so all you need to do is to set `init`:

```julia-repl
julia> sum(float∘f, String[]; init=0.0)
0.0

```

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [June 22, 2024, 3:56am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/8 "2024-06-22T03:56:39Z")

</div>

> [@stevengj](#):
>
> (Contrary to popular misconception, integers are represented exactly by `Float64` values, up to \pm 2^{53}, so you don’t generally improve accuracy by using `Int` to store integers.)

Thank you, I was not aware of this, and according to [this thread](https://stackoverflow.com/questions/53111758/can-i-trust-floats-or-doubles-representing-integers-to-retain-precision) `+`, `-`, `*`, `/` and `sqrt` all preserve this precision. I will certainly consider this in the future, but I do need to work on being comfortable with this after 30 years of having the “misconception”.

> [@stevengj](#):
>
> > [@GHTaarn](#):
> >
> > I have a function that can produce either `Int64` or `Float64`
> 
> Note that this will be relatively slow in Julia because it is type unstable. Why not just return a `Float64` in all cases?

Thanks for challenging my old habits, it is nice to see a well respected programmer confident in using `Float64` to represent integers. I will keep this in mind in the future, but right now I prefer not to change that part of the code.

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [June 22, 2024, 4:04am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/9 "2024-06-22T04:04:29Z")

</div>

> [@abraemer](#):
>
> so all you need to do is to set `init`:
> 
> ```julia-repl
> julia> sum(float∘f, String[]; init=0.0)
> 0.0
> 
> ```

Yes, I did see this, but I don’t see how that would be better than `sum(f, String[], init=0)` as proposed by @laborg .

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 22, 2024, 7:20am UTC](https://discourse.julialang.org/t/mapping-to-mixtures-of-int64-float64/115961/10 "2024-06-22T07:20:40Z")

</div>

> [@GHTaarn](#):
>
> `f(s) = parse(rand([Float64, Int64]), s)`

Not much, on my benchmarks it is even a bit slower. But the underlying idea remains interesting: preserve type-stability wherever possible.  
For example, `init = 0.0` is better than `init = 0` at least on papier, because the sum will end up being a `Float64` and not an `Int`, so it’s better to initialize it that way. See also [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-changing-the-type-of-a-variable)
