Julia: Base.any() does not work as expected with arrays - POLA violation

Created on 2 Oct 2019  Â·  7Comments  Â·  Source: JuliaLang/julia

In other languages, you can call any([0 0 0.0]), and it will return false or 0. Similarly, any([1 2 3]) will return true or 1

In Python 3.7.4:

>>> any([1, 2, 3])
True
>>> any([0, 0, 0])
False

In MATLAB:

>> any([1 2 3])
ans =
  logical
   1
>> any([0 0 0])
ans =
  logical
   0

In R, it _works as expected_, but also gives a warning:

> any(c(1,2,3))
[1] TRUE
Warning message:
In any(c(1, 2, 3)) : coercing argument of type 'double' to logical
> any(c(0, 0, 0))
[1] FALSE
Warning message:
In any(c(0, 0, 0)) : coercing argument of type 'double' to logical

With Julia, I get:

julia> any([1, 2, 3])
ERROR: TypeError: non-boolean (Int64) used in boolean context
Stacktrace:
 [1] _any at .\reduce.jl:693 [inlined]
 [2] _any at .\reducedim.jl:663 [inlined]
 [3] #any#566 at .\reducedim.jl:661 [inlined]
 [4] any(::Array{Int64,1}) at .\reducedim.jl:661
 [5] top-level scope at REPL[1]:1

julia> any([0, 0, 0])
ERROR: TypeError: non-boolean (Int64) used in boolean context
Stacktrace:
 [1] _any at .\reduce.jl:693 [inlined]
 [2] _any at .\reducedim.jl:663 [inlined]
 [3] #any#566 at .\reducedim.jl:661 [inlined]
 [4] any(::Array{Int64,1}) at .\reducedim.jl:661
 [5] top-level scope at REPL[2]:1

Should there be a definition for any(a::Array) that works as expected?
Example:

function Base.any(a::Array)
       return any(a .!= 0)
end
any([1, 2, 3])
any([0, 0, 0])

Most helpful comment

Just for Python, consider the following:

https://itnext.io/you-shouldnt-use-truthy-tests-753b39ef8893
https://mail.python.org/pipermail/python-ideas/2014-March/026446.html
https://andreasbergstrom.com/posts/python-gotchas-and-tips-4/
https://www.reddit.com/r/learnpython/comments/64v9gg/help_with_understanding_truthy_and_falsey_values/
https://vegaskid.net/2018/02/truth-about-boolean-values-python/

Now, consider that all other languages with “truthiness” have a different definition of it and have just as many—but slightly different!—equally bad issues with it. How much text must be spilled over this inherently ill-defined concept? This can only be considered a reasonable situation by someone who has neither pushed the boundaries of what truthiness can mean nor used more than one or two of these languages with different arbitrary definitions of truthiness.

In Julia this is all you have to write about truthiness: true is true and false is false; anything else is invalid in a Boolean context.

The only confusion that we ever have about this is people who occasionally demand that miscellaneous obviously true/false arbitrary instance of some complex data structure should be consider false/true when is pass it to an if block.

All 7 comments

I would find an any(::Array{T}) (for T != Bool) method to be a "POLA violation"; it introduces a sense of truthiness which is otherwise not present in Julia.

I don't know about R but in both MATLAB and Python, 0 and 1, are converted implicitly to boolean. Julia just doesn't have that. In another word, any([0]) should work iff if 0 works.

Now if you want to make 0/1 treated as boolean in general, then that's a decision made a long time ago with reasons behind it. Please ask on discourse.julialang.org if you have question about that.

You can do this:

julia> any(!iszero, [1, 2, 3])
true

Julia rejects the implicit and essentially arbitrary notion of "truthiness" that many language have.

You can do this:

julia> any(!iszero, [1, 2, 3])
true

Julia rejects the implicit and essentially arbitrary notion of "truthiness" that many language have.

Not going to lie, as a beginner and not a professional programmer, this kind of thing feels like it gets in the way of getting things done.

You will be happy when it saves you from a hard to find bug (actually you probably won't because you won't notice it but anyway) where you accidentally put a 1 or a string or whatever else people dream up to mean as true in a boolean expression when you, in reality, wanted something to put something else there.

This is the classic "simple vs. easy" distinction. If you're used to 0 being false, then it's easier for us to follow that. But it's less simple, since there are more hidden rules in play. Is just 0 false, or also all-zero arrays, etc? BTW, in scheme only #f is false, and everything else including 0 is true. So we feel it's better in the long run to keep things explicit and orthogonal.

Just for Python, consider the following:

https://itnext.io/you-shouldnt-use-truthy-tests-753b39ef8893
https://mail.python.org/pipermail/python-ideas/2014-March/026446.html
https://andreasbergstrom.com/posts/python-gotchas-and-tips-4/
https://www.reddit.com/r/learnpython/comments/64v9gg/help_with_understanding_truthy_and_falsey_values/
https://vegaskid.net/2018/02/truth-about-boolean-values-python/

Now, consider that all other languages with “truthiness” have a different definition of it and have just as many—but slightly different!—equally bad issues with it. How much text must be spilled over this inherently ill-defined concept? This can only be considered a reasonable situation by someone who has neither pushed the boundaries of what truthiness can mean nor used more than one or two of these languages with different arbitrary definitions of truthiness.

In Julia this is all you have to write about truthiness: true is true and false is false; anything else is invalid in a Boolean context.

The only confusion that we ever have about this is people who occasionally demand that miscellaneous obviously true/false arbitrary instance of some complex data structure should be consider false/true when is pass it to an if block.

Was this page helpful?
0 / 5 - 0 ratings