On the arbitrariness of truth(iness)

I love the fact that Julia disallows non-Bool types in conditions, it saves a lot of bugs.

38 Likes

That, or remove the braces (but in my case I had a more complicated expression so removing braces wasn’t an option) because

arrow functions do not magically guess what or when you want to “return”

Returning the last expression would be a too reasonable option, I guess.

3 Likes

4 posts were split to a new topic: Assembly: is “jump if not zero” more expressive than “jump if odd”?

Fortranners (at least this one) agree with you. Fortran has a logical type, and if you want to convert an integer to a boolean you write

tf = merge(.true., .false., i /= 0)

All these fancy-schmancy notions of “correctness”, “consistency” and “error resistance” in Julia feel so 20th century to me. Those other languages have apparently embraced postmodern relativism, that truth can be whatever feels right to you depending on your viewpoint and daily mood. That approach is clearly more inline with the Zeitgeist, as evidenced in the news every day. It’s sad to see Julia so out of touch with our times. :wink:

24 Likes

jnz/jz are very useful for pointers.

if p = function_with_optional_result(...)
    # use p, as it is non-null
end

is a common pattern in, for example, the LLVM code base.

I’m not saying this is a better convention than explicit optional types (or returning nothing that’ll throw an error if you try to use it as a pointer), but it’s still fairly convenient.

Ptr types may not be integers, but it’s fairly reasonable to have them behave the same way, and thus have truthiness of integers also be based on comparison to zero.
I don’t know the history, but this also fits the pattern of C vs Lisp having settled on different conventions of truthiness for integers.

1 Like

A post was merged into an existing topic: Assembly: is “jump if not zero” more expressive than “jump if odd”?

In the first example, Julia does the same thing, which is common in logical systems.

julia> all([])
true

all([[]]) is false because the only value is an empty list, which is falsy.

In [4]: x = []

In [5]: bool(x)
Out[5]: False

In [6]: all([x])
Out[6]: False

all([[[]]]) is too complicated to read, but breaking it up we can see the only value is a nonempty list, so it is truthy.

In [1]: x = [[]]

In [2]: bool(x)
Out[2]: True

In [3]: all([x])
Out[3]: True
3 Likes

As much as I agree with the boolean/nonboolean distinction, I often wish Julia had gone one step further and not considered booleans to be integers.

julia> supertypes(Bool)
(Bool, Integer, Real, Number, Any)

julia> true + false
1
10 Likes

I will say that adding booleans is something I’ve done quite a few times before, basically counting the number of times something happened etc. I guess one could cast the bools to int to do that but it’s a bit verbose.

4 Likes

Stick that on a t-shirt and sell it at JuliaCon.

20 Likes

Stephen Colbert is somewhere sarcastically fuming right now

6 Likes

That’s not a step further, it’s a step in an orthogonal direction.

Booleans are integers anyways, at least to same extent as Int64 and Int8 are (modular integer rings). What is gained by pretending otherwise?

3 Likes
julia> all([[]])
ERROR: TypeError: non-boolean (Vector{Any}) used in boolean context
Stacktrace:

what do you mean…

Think the first example was the one referenced, i.e.

julia> all([])
true
1 Like

If they were modular integers like Int64, they would wrap with addition, no?

julia> typemax(Int) + 1
-9223372036854775808

julia> typemax(Bool) + true
2
3 Likes

that’s just Vacuous truth - Wikipedia which is very common. The problem with Python is [] can be interpreted as Boolean, which Julia is very much not able to

2 Likes

Yeah, but I was ju saying the quote on “julia does the same thing” was mentioned only for the first example, and not the one you brought up.

that’s exactly what I don’t understand because the point of @ bkamins is the whole thing, not just all([]) being true or not. I don’t see how “Julia is the same” when it literally is NOT

1 Like

I also don’t think the all([]) example is at all confusing/surprising. That has always been exactly what I wanted it to do; I have always wanted all to mean that there are no exceptions (so all([]) == true), and any to mean that there is an exception (so any([]) == false). Any other behavior I’d find both surprising and annoying, as I’d then be forced to add length checks on all my uses.

The other Python cases I find more surprising.

3 Likes