# Bug/unexpected behavior when extending Base.any with new type

**URL:** <https://discourse.julialang.org/t/bug-unexpected-behavior-when-extending-base-any-with-new-type/94359>\
**Category:** General Usage\
**Created:** [February 9, 2023, 4:41pm UTC](https://discourse.julialang.org/t/bug-unexpected-behavior-when-extending-base-any-with-new-type/94359 "2023-02-09T16:41:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![brunbjerg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brunbjerg/32/53205_2.png) [@brunbjerg](https://discourse.julialang.org/u/brunbjerg)\
**Post date:** [February 9, 2023, 4:41pm UTC](https://discourse.julialang.org/t/bug-unexpected-behavior-when-extending-base-any-with-new-type/94359/1 "2023-02-09T16:41:58Z")

</div>

I have extended the any function as shown in the example below:

```julia
function Base.any(array::Matrix{Real})
    checker = zeros(Bool, size(array)[1])

    for i in axes(array, 1)
        for j in axes(array, 2)
            if array[i, j] == 1
                checker[i] = true
                break
            end
        end
    end
    return checker
end

```

The `any` function should now take in a `Matrix` that contains elements of the type `Number`, but when given the following matrix:

```julia
A = any([0 0 0 1;
         0 0 0 0;
         0 0 0 1])

```

We get:

```julia
ERROR: TypeError: non-boolean (Int64) used in boolean context
Stacktrace:
 [1] _any
   @ .\reduce.jl:1207 [inlined]
 [2] _any
   @ .\reducedim.jl:1005 [inlined]
 [3] #any#792
   @ .\reducedim.jl:1003 [inlined]
 [4] any(a::Matrix{Int64})
   @ Base .\reducedim.jl:1003
 [5] top-level scope
   @ REPL[149]:1

```

But when given

```julia
A = any([0 0.0 0 1;
         0 0 0 0;
         0 0 0 1])

```

We get the correct output which is:

```julia
3-element Vector{Bool}:
 1
 0
 1

```

Is this a bug? If I am reporting this in the wrong place, please let me know where to post it.

---

<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:** [February 9, 2023, 4:51pm UTC](https://discourse.julialang.org/t/bug-unexpected-behavior-when-extending-base-any-with-new-type/94359/2 "2023-02-09T16:51:16Z")

</div>

This is because in your first case you are imputing a `Matrix{Int}`, which is not a `Matrix{Real}`, then another `any` method is being called. You have to change your function to accept `Matrix{<:Real}`, which are the matrices for which the elements are any subtypes of `Real`.

With `Matrix{Real}` you are asking the function to only accept the matrices that are specifically of type `Matrix{Real}`, which are matrices that accept, on its elements, any type of real number.

Search for the “covariance” of types in Julia, or for example: [Vector{Int} \<: Vector{Real} is false??? · JuliaNotes.jl](https://m3g.github.io/JuliaNotes.jl/stable/typevariance/), or [Why [1, 2, 3] is not a Vector{Number}?](https://discourse.julialang.org/t/why-1-2-3-is-not-a-vector-number/52645)

By the way, you can use:

```julia
julia> A = [0 0.0 0 1;
            0 0 0 0;
            0 0 0 1];

julia> any.(==(1), eachrow(A))
3-element BitVector:
 1
 0
 1

```

(ps: calling your function with the second type of matrix doesn’t work here either, because it is a `Matrix{Float64}` which is not either a subtype of `Matrix{Real}`. Your method works, as is, if you explicitly set `Real[0 0 1; 0 1 0 ; 0 0 1]`, such to get `Matrix{Real}`).

Finally, the error message (which is not great), is saying it is trying to test if a integer number is true or false, that is, using a integer where it expects a boolean. This occurs because the `any` function supports not providing the first argument (the function to be mapped to every element of the collection), and in that case it tests for true/false the array itself:

```julia
julia> any([true false])
true

julia> any(==(1),[1 0])
true

julia> any([1 0])
ERROR: TypeError: non-boolean (Int64) used in boolean context

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 9, 2023, 5:34pm UTC](https://discourse.julialang.org/t/bug-unexpected-behavior-when-extending-base-any-with-new-type/94359/3 "2023-02-09T17:34:16Z")

</div>

Even better, use `any(x; dims=2)`:

```julia-repl
julia> x = [0 0 0 1;
            0 0 0 0;
            0 0 0 1];

julia> any(x; dims=2)
3×1 Matrix{Bool}:
 1
 0
 1

```

I never extend basic functionality like this until I’m sure it’s (a) working as I hoped and (b) is operating in a sense consistent with the other methods. Start with your own function names first.

---

<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:** [February 9, 2023, 5:52pm UTC](https://discourse.julialang.org/t/bug-unexpected-behavior-when-extending-base-any-with-new-type/94359/4 "2023-02-09T17:52:44Z")

</div>

Or `any(==(1), x; dims=2)` if the matrix is not of integer zeros and ones. By the way, seems slightly inconsistent that this works:

```julia
julia> x = [1 0];

julia> any(x; dims=1)
1×2 Matrix{Bool}:
 1 0

```

while this does not:

```julia
julia> any(x)
ERROR: TypeError: non-boolean (Int64) used in boolean context

```

Why in one case integers are considered “as booleans”, and in the other case don’t? (for the fun I created a [PR that fixes this inconsistency](https://github.com/JuliaLang/julia/pull/48607), but that seem to be a deliberate choice, so probably that is not going to change).

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [February 9, 2023, 7:40pm UTC](https://discourse.julialang.org/t/bug-unexpected-behavior-when-extending-base-any-with-new-type/94359/5 "2023-02-09T19:40:26Z")

</div>

Both your original version or the suggestion to implement `Base.any(array::Matrix{<:Real})` are cases of [type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy) (see [examples](https://discourse.julialang.org/t/minimal-working-example-that-demonstrates-the-danger-of-type-piracy/66922/1)). You have modified a function you do not “own” (is not originally defined in the code you’re working on) for a type that you also do not own.

Piracy risks breaking your entire Julia session (and anyone’s who uses your code) in subtle and insidious ways and is _strongly_ discouraged. I recommend using the suggested call to `any(==(1), A; dims=2)`, which is exactly equal to your version but more flexible and not a case of piracy.
