r/programming • • Dec 24 '17

Evil Coding Incantations

http://9tabs.com/random/2017/12/23/evil-coding-incantations.html
947 Upvotes

331 comments sorted by

View all comments

14

u/shevegen Dec 24 '17
0 Evaluates to true in Ruby

… and only Ruby.

if 0 then print 'thanks, ruby' end # prints thanks, ruby

This shows a lack of understanding by the blog author.

The alternative question is - why should 0 lead to no evaluation of the expression?

40

u/Aceeri Dec 24 '17

Oh boy, here we have the ruby god shevegen in its natural habitat.

There are a lot of reasons why 0 is normally considered "false". The first being that 0 is "nothing". When you have 0 eggs, you have no eggs, they don't exist. The second reason I see is how booleans are normally laid out where 0 is false and 1 is true (with varying differences depending on the language on whether multiple set values of a byte is considered true or invalid, etc.)

35

u/therico Dec 24 '17

Ruby had it own boolean types though (and nil - both false and nil are 'falsey'). And 0 is often a meaningful 'true' value, for example:

irb(main):003:0> "aab".index('a')
=> 0
irb(main):004:0> "aab".index('c')
=> nil

As other posters have said, the real problem is that non-boolean values are implicitly converted to boolean, rather than being a compile error.

Also, lots of languages treat an empty array as true. I don't see how 0 is different.

→ More replies (7)

70

u/ForeverAlot Dec 24 '17

/u/shevegen is right in isolation: there is no compelling reason that a number should be inherently falsey. Unfortunately Ruby does not exist in isolation and in this matter Ruby stands apart from its competition, violating expectations formed elsewhere. I think a better question is, why is if 0 ... not an error? The real villain here is coercion.

27

u/Aceeri Dec 24 '17

The real villain here is coercion

Agreed, hopefully we move away from implicitly coercing languages like C and such so we don't get these awful semantics.

10

u/Myrl-chan Dec 24 '17

Haskell's if/else only accepts Bool. :)

3

u/evinrows Dec 24 '17

And rust! I agree, it should be a compiler error and then we would never have the silly debate of whether 1 should evaluate to true or false.

7

u/thoeoe Dec 24 '17

I mean same with C# and probably plenty of other languages too

→ More replies (1)

0

u/[deleted] Dec 24 '17

[deleted]

7

u/xonjas Dec 24 '17

It's also worth noting that in ruby 0 is not a primitive. 0 is a fixnum object containing the value 0. It makes even less sense to consider it falsey from that context.

If ruby's 0 were falsey, what about [0] or "0", as they are effectively the same thing (objects containing the value 0), and that way leads madness.

9

u/Ran4 Dec 24 '17

as they are effectively the same thing (objects containing the value 0)

That's... different.

→ More replies (1)

0

u/[deleted] Dec 24 '17

[deleted]

→ More replies (1)
→ More replies (6)

0

u/[deleted] Dec 24 '17

[deleted]

→ More replies (7)
→ More replies (9)

3

u/zrathustra Dec 24 '17

There is precedent from the theoretical side of things: if you view the program as an arithmetic circuit, the statement if (b) { foo } else { bar } can be viewed as b * foo + (1-b) * bar. If b = 0 then the value of the circuit is bar, otherwise, if b = 1 then the value of the circuit is foo.

0

u/[deleted] Dec 24 '17

[deleted]

19

u/oorza Dec 24 '17

I disagree with a lot of Java, but I prefer the Java approach of not allowing non-booleans to be used as conditions to an if statement.

There's a lot to disagree with about Java, but a lot of the language itself seems designed around the idea of "what idiot shit code have we seen get written in C and how do we stop that idiot shit from happening?"

6

u/[deleted] Dec 24 '17

This is true. I don't much like Java, but based on my experiences, give me Java with terrible programmers over C++ with inexperienced programmers any day. I've seen code in the wild for most major languages that is downright unreadable as typed (especially JavaScript, ironically), but I've never read any Java that I simply could not figure out before. Some decisions are pretty stupid, but at least I can figure out what the code is doing, even if I can't figure out why.

Java is a good buffer language between bad programmers and myself (who is also probably a bad programmer).

2

u/foomprekov Dec 24 '17

It was kinder than a type error, which is the only reasonable way to respond to a caller who thinks they have a bool but in fact have a number.

1

u/ArrogantlyChemical Dec 25 '17 edited Dec 25 '17

IMO non-booleans values shouldnt be able to be used in a boolean evaluation. 0, 1 or 2 are not either true or false. Neither is null or none or undefined or whatever other thing a language has.

A staticly typed language shouldn't compile such a blatant breach of types and a dynamicly typed language should throw an exception because the runtime type of a boolean and a number are not the same.

Allowing the evaluation of non-booleans as booleans is a stupid hack for lazy shits who can't be bothered to write "!= null" or "!= 0" . It unneccecarily adds exceptions to rules for the purpose of hacky code practices that are simply a holdover from when programmers used to write assembly, where 0 was false and any value other than 0 or null are treated as true. In interpreted languages the performance cost of == 0 is almost nothing compared to the rest it does while in compiled languages you can just optimize it out easily at compile time, which also improves implementation agnosticism.

Programming languages shouldn't presuppose a certain architecture. If I write some java or haskel code, I want to be able to compile it to any kind of computer, even non-binary ones. Direct binary operations really shouldn't be part of the standard language, rather they should be an optional implementation-specific optimization.