# Bools in arithmetic operations

**URL:** <https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504>\
**Category:** New to Julia\
**Tags:** boolean\
**Created:** [December 28, 2020, 12:07pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504 "2020-12-28T12:07:15Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [December 28, 2020, 12:07pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/1 "2020-12-28T12:07:15Z")

</div>

Bools seem to get converted/promoted to numerical zero/one:

```julia
julia> false + 42
42

julia> true + 42
43

julia> false + 3.14
3.14

julia> true + 3.14
4.140000000000001

julia> false + complex(1, 2)
1 + 2im

julia> true + complex(1, 2)
2 + 2im

```

I don’t like it. For example,

```julia
julia> gety(m, index_offset=0) = m[:, index_offset+2]
gety (generic function with 2 methods)

julia> m=[1 3 5 8;2 11 9 6]
2×4 Array{Int64,2}:
 1 3 5 8
 2 11 9 6

```

was accidently called as

```julia
julia> gety(m, true)
2-element Array{Int64,1}:
 5
 9

```

The bug was difficult to hunt down.

Is it possible to optionally suppress such automatic conversions in arithmetic operators?

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [December 28, 2020, 12:24pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/2 "2020-12-28T12:24:07Z")

</div>

For the general question of [“why is `Bool` an `Integer`”](https://discourse.julialang.org/t/why-is-bool-an-integer/17237), see:

[https://github.com/JuliaLang/julia/issues/19168](https://github.com/JuliaLang/julia/issues/19168)

For your particular case, if you don’t want `Bool` to be accepted as input in your function, just make it throw an error in such a case:

```julia
julia> gety(m, ::Bool) = throw(ArgumentError("Bool not allowed"))
gety (generic function with 1 method)

julia> gety(m, true)
ERROR: ArgumentError: Bool not allowed
Stacktrace:
 [1] gety(::Array{Int64,1}, ::Bool) at .\REPL[1]:1
 [2] top-level scope at REPL[2]:1234:1

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [December 28, 2020, 1:15pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/3 "2020-12-28T13:15:31Z")

</div>

> [@stephancb](#):
>
> Bools seem to get converted/promoted to numerical zero/one:

Bools are neither converted nor promoted to numerical zero/one, they **are** numerical zero/one.

```julia
julia> supertype(Bool)
Integer

```

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [December 28, 2020, 1:20pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/4 "2020-12-28T13:20:08Z")

</div>

Thanks for the link. It shows that this is a complicated issue, which I had already suspected.

In reality I have of course many candidate functions which should not work with Bool arguments. For now I restrict them like

```julia
julia> getty(m, index_offset::Int=0) = m[:, index_offset+2]
getty (generic function with 2 methods)

```

which is more restrictive than needed but easier to exclude Bool arguments.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [December 28, 2020, 1:39pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/5 "2020-12-28T13:39:23Z")

</div>

Dispatching on only `Int` is too restrictive. Generic code is normally preferable, so it’s better to define special behavior only for the exceptional cases you want to rule out (`Bool` input, in this case).

But if you don’t want to write the extra methods to manage those exceptions, at least I recommend you to allow any other `Integer` that is not `Bool`. `Bool` happens to be the only subtype of `Integer` which is not either `Signed` or `Unsigned`, so you could write:

```julia
getty(m, index_offset::Union{Signed, Unsigned}=0) = m[:, index_offset+2]

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 28, 2020, 1:52pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/6 "2020-12-28T13:52:31Z")

</div>

> [@stephancb](#):
>
> The bug was difficult to hunt down.

While restricting the input is an option to catch the error at that point, it seems that the bug was probably before the call to your function, somewhere where a `Bool` was generated where an integer was expected to be generated. Perhaps the proper place to add an error message or deal with the Bool was at that point, if for some reason that turns out to be possible and the program is expected to stop if that occurs.

(otherwise, although you can prevent that error from propagating in your own functions, it will propagate in every other functions of other packages or Base that accept Bools as integers, which are probably most of them)

---

<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:** [December 28, 2020, 2:30pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/7 "2020-12-28T14:30:47Z")

</div>

Index inputs are converted to `Int` by the `to_indices` function. One generic way of doing this, in that case is

```julia
gety(m, index_offset::Int=0) = m[:, index_offset+2]
gety(m, index_offset) = gety(m, to_indices(m, (index_offset,))...)

```

This should accept all the same types of indices that other Julia arrays do, staying up-to-date with whatever `to_indices` does. Specifically, `Bool`s will be disallowed, while other integers are accepted.

(Please be aware, I’ve never had reason to use `to_indices` before, so double check that it works as expected.)

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [December 29, 2020, 10:11am UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/8 "2020-12-29T10:11:21Z")

</div>

Thanks for the replies, there are several soulutions to my problem. I add now

```julia
const ExceptBool = Union{Signed, Unsigned}

```

to my relevant modules (or perhaps even to `startup.jl`), and use it in functions like the above mentioned example

```julia
gety(m, index_offset::ExceptBool=0) = m[:, index_offset+2]

```

to enforce that using Bools for arguments in such functions must be explicit:

```julia
julia> gety(m, true)
ERROR: MethodError: no method matching gety(::Matrix{Int64}, ::Bool)
Closest candidates are:
  gety(::Any) at REPL[10]:1
  gety(::Any, ::Union{Signed, Unsigned}) at REPL[10]:1
Stacktrace:
 [1] top-level scope

julia> gety(m, Int(true))
2-element Vector{Int64}:
 5
 9

```

---

<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:** [December 29, 2020, 1:30pm UTC](https://discourse.julialang.org/t/bools-in-arithmetic-operations/52504/9 "2020-12-29T13:30:14Z")

</div>

> [@stephancb](#):
>
> I add now
> 
> ```julia
> const ExceptBool = Union{Signed, Unsigned}
> 
> ```
> 
> to my relevant modules (or perhaps even to `startup.jl` )

Alternatively, you can just do

```julia
@assert !(index_offset isa Bool)

```

inside functions. It will be costless if your types are inferred.
