Transcript from the "Implicit Coercion: Booleans" Lesson
>> Kyle Simpson: What about Booleans? Anybody ever done an if statement before where you just passed in something that wasn't already a Boolean? Anybody ever done that before? You might not have thought, I'm doing an implicit coercion. You might have done so well writing a blog post saying, implicit coercion is bad.
[00:00:31] You know why, cuz that's not an important detail on that line of code.
>> Kyle Simpson: What I'm communicating here, is that if it is truthy, make this thing happen. I don't need to clutter up that code by explicitly coercing it to a boolean so that I can do an if check.
[00:00:48] The implicit system here is helpful because it hides the unnecessary noise. I'm a big fan of line 2, but I don't see how you can be consistent in your world viewpoint. To talk bad about implicit coercion, and then write code like that. So, string 123, it's truthy, right, cause it's not on the falsey list, so we passed the if statement.
[00:01:13] The 0 on line six, is that truthy or falsey?
>> Speaker 2: Falsey.
>> Kyle Simpson: So on the falsely list was false. So we're gonna print the, right. Now, what about line 10? Line 10 is where things start to get a little bit strange here. Cuz it works, we compare 0 to false with that dreaded double equals.
[00:01:35] Which we gonna get lots into I promise. We compare 0 to false. And it turns out that the check passes. So what's going on? Here's why I said earlier, I made you write down in your notes, that the rules for Boolean coercion only happen if the rules for Boolean coercion are actually happening.
[00:01:56] Remember that whole no op that I said? Sounded like a Buddhist monk saying something weird or whatever like, it only works when it works, right? Okay, gee, thanks. Here's what's happening. When you look at foo == false, 0 == false, I'm willing to bet that most, if not all of you, think to yourselves, well, 0 is falsie, so it's gonna become false and then I compare to false to false, and of course, they're the same, so we pass the check.
[00:02:26] But, that's not what happens at all. As a matter of fact, line 10 only works because of a happy accident. I don't like relying upon happy accidents in my code, I don't know about you.
>> Kyle Simpson: Line 10 only works because of a happy accident. Here's what actually happens.
[00:02:43] We're gonna get into double equals in a minute, but I'll just tell you right now that what actually happens is that the double equals prefers to compare numbers. So what it's actually gonna do instead of making 0 into false and comparing the two falses, it's gonna make false into 0 and compare the two 0s.
>> Kyle Simpson: Why? I don't know, probably cuz number comparison is a lot more efficient in the internals of the CPU.
>> Kyle Simpson: But that's the way the algorithm was written, it prefers to compare numbers.
>> Kyle Simpson: I bet that's another one of those that you could trip people up on in an interview question.
[00:03:23] Because most people never stop to think, how does that work? You just assume that is a Boolean coercion. Nope, it's not. And here it works. Your assumption works out okay for you, but it's a happy accident. On the next screen, I'm gonna show you something where that does not work so well, okay?
[00:03:39] Line 14.
>> Kyle Simpson: That or operator, that double pipe that we have there, everybody recognizes that as the or operator. The double ampersand being the and operator. What do those things do? Well, those things are often called logical operators. That's how they're labeled. That's how they're labeled in the official spec in the documentation.
[00:04:26] The difference is subtle but actually pretty important. The or operator here is not producing a true or a false, baz is not going to be true or false baz is gonna be quote foo. And whoa, whoa, wait a minute. The end result is not a logical result, the end result is that we actually just picked one of the two operands.
[00:04:49] The or operator and the and operator, these so-called logical operators actually, are more like selection operators. They take two operands, they do a Boolean coercion test against the first one. And based upon that end result, pick one of the two. They select one of the two operands, that's what they do.
[00:05:12] That's why we have this default value idiom that we've all probably seen. Where I can say make baz equal to either foo or back up to quote foo as a default if the variable foo wasn't already set. Cuz we're gonna do Boolean check against foo and if it passes, we're gonna use foo.
[00:05:57] Which is a short hand way of saying, if the call back has been set, then invoke the callback, why? Because we're checking the value of the cb and it only goes to the second operand if it passes as true.If it fails as false, we short circuit out and don't try to execute it.
[00:06:18] So we're showing off our skills, relying upon not only this implicit coercion happening, but also, we're relying upon short circuiting of these operators. I'm not negative on that, I think those are great features, but we have to be honest that they're implicit features. How many have you ever written something like if a or b?
[00:06:39] Or if a and b. And in all of those cases where those things already Booleans?
>> Kyle Simpson: See you're already relying upon implicit coercion. Does that create an identity crisis for you that you should go back and fix all your code and put in all those double negates all over the place?
[00:07:02] I would argue this is a place where the implicit coercion is helping the readability of your code. Everybody following that reasoning?
>> Kyle Simpson: Here's where the double equal stuff starts to get crazy for us, because here we have the string 123. Now, the string 123, we've already established that it's truthy, right?
[00:07:23] So when I double equal it to true and that fails, my whole world starts to fall apart. How can something be truthy but not double equal to true?
>> Kyle Simpson: Well, it's cuz the double equal isn't doing a Boolean coercion at all, just like I said before. The double equals prefers to compare numbers.
[00:07:45] So, if I give it a string and a Boolean, guess what's gonna happen? Both of them are gonna get coerced to numbers. The string is gonna coerce to the number 1,2,3, the true is gonna coerce to the number 1. And the number 1,2,3 and number 1 are most definitely not equal to each other.
>> Kyle Simpson: Now you may be thinking at this point, I promise we're getting to double equals in a minute, but you may be thinking at this point, well, geez this double equals just seems hopelessly complicated. I'm never gonna be able to fully understand this double equals thing. Not true, it's actually a very simple algorithm.
[00:08:19] Here's the one key takeaway, we'll come back to this. If you just know that double equals prefers to compare numbers, most of the behavior simplifies itself. That's just something nobody's taught me before. Double equals to prefers to compare numbers. Just that one fact eliminates most of the confusion of the double equals, okay?
[00:08:43] We'll get into more of that. So here it's not doing a Boolean coercion. So let me give you a takeaway. You're looking for, I don't wanna talk about abstract, give me practical stuff. Here's a takeaway, don't ever under any circumstances, and I don't very often use absolutes, but this is one of them.
[00:09:00] Don't ever under any circumstances, compare with double equals true or double equals false, just never, ever, ever, ever, ever do it. Because, most likely, it's only gonna work as a happy accident. And in the worst case, it's gonna confuse people and create bugs. Just don't do it. We’ve already talked about multiple other ways, for you to either let it do the implicit coercion for you, or be explicit about it, but don’t rely upon double equals to true, or double equals to false, cuz they aren’t gonna do what you’re expecting them to do.
[00:09:39] And more importantly, they’re not gonna do it, what the future reader of your code is expecting it do do.
>> Kyle Simpson: Same thing down on line 7. We've got an array. We know the array, even though it's an empty array, it's truthy. Why is it truthy? It's not on the falsey list, right?
[00:10:01] Even though an empty array seems like it ought to be. It's not on the falsy list so it's gotta be truthy. So we do an if test for it and sure enough it passes as true. So we've established that it's truthy but on line 10 we double equal it to false, and that also passes.
[00:10:15] How can something be both truthy and double equal to false? Or maybe it's cuz the double equals doesn't do a Boolean coersion. Maybe it's cuz that double equals is gonna try to do a numeric coersion. So we're gonna take the empty array, remember primitives need to be, I mean non-primitives need to become primitives.
[00:10:34] So what is the two primitive of an empty array gonna produce?
>> Speaker 3: String 0.
>> Kyle Simpson: An empty string. First, we're get there right? You're right, we're gonna produce an empty string. So now what we really have is empty string double equal to false. Now we still prefer numbers, right?
[00:10:54] So we're gonna turn the empty string into a number, which one does that become?
>> Speaker 3: 0.
>> Kyle Simpson: 0, we're gonna turn false into a number which one does that become?
>> Speaker 3: 0.
>> Kyle Simpson: So now we have these zeros. There's our root, root of all evil again, all right?
[00:11:09] I told you we'd be coming back to that over and over. The gateway drug here is the double equals comparison with a Boolean. Just don't do it.