This course has been updated! We now recommend you take the The Good Parts of JavaScript and the Web course.

Check out a free preview of the full JavaScript the Good Parts course:
The "Avoiding Confusing Code (B)" Lesson is part of the full, JavaScript the Good Parts course featured in this preview video. Here's what you'd learn in this lesson:

Additional pitfalls emerge from the use of global variables and syntax shortcuts. Bad coding styles fall into four classes: Under Educated, Old School, Thrill Seekers, and Exhibitionist Programming is the most complicated thing that humans do. Computer programs must be perfect. Humans are not good at perfection so designing a good programming style demands discipline.

Get Unlimited Access Now

Transcript from the "Avoiding Confusing Code (B)" Lesson

[00:00:00]
>> [MUSIC]

[00:00:04]
>> Douglas Crockford: Global variables are evil in all languages. One of the unfortunate things about JavaScript is that it sometimes requires the use of global variables. Because it doesn't have any other mechanism for binding code units together. So everything gets dumped in common global space, which is terrible for reliability, even worse for security.

[00:00:27] So, you need to avoid global variables as much as possible. So my advice in naming global variables is, write them in uppercase, because I want them to be really rare. And I want them to stand out because there are these dangers that are inherent in globals, I want them to be visible.

[00:00:49] JavaScript has new prefix, which was intended to look like Java in the way that you create instances of objects. But it doesn't work the way you would expect, and there was a bug in the way it was defined. That if you have a function that's intended to be used as a constructor, and someone calls that function without the new prefix.

[00:01:10] Instead of initializing a new object, it's going to clobber global variables instead. Again, no run time warning, no compile time warning, just doing the worst thing, which is bad. So because of that, we have a convention that constructor functions should be named with InitialCaps. And nothing else should be named with InitialCaps.

[00:01:34] Only by having that convention do we have any hope of identifying the cases where new is missing.
>> Douglas Crockford: Let's see, this is another ambiguous statement, var a = b = 0, looks like it creates two variables, a and b, and initializes them. But what it actually does is initialize a global variable, b, and initialize a, which was probably not what you intended.

[00:02:03] That someone was going to some work here to, one of the really bad parts about JavaScript is implicit global variables. So if you have a variable and you do not explicitly declare it, it's assumed to be global. That was done to make the language easier for beginners, it makes the language much harder for professionals.

[00:02:23] I assume you're all professionals, so this turns out to be a bad feature. So you need to figure out which of these, again, you intended, and write the right one. Write it in a way that clearly communicates your intent. Okay, so Thompson created the ++ operator in B in order to increment pointers.

[00:02:49] Since then, we have learned that pointer arithmetic is harmful and it is no longer included in programming languages. The last popular language to have point arithmetic in it was C ++, a language so bad it was named after this operator.
>> Speaker 2: [LAUGH]
>> Douglas Crockford: Now even though we were not incrementing pointers anymore, we still have this operator anyway.

[00:03:17] Which is now used to add one to integers, it's like, why do we need that? This operator was implicated in the buffer over one craze. Remember when Unix and Windows were failing all over the place. And they have to refractor them in order to avoid the buffer overrun attack.

[00:03:37] And it turned out it was this operator was implicated because this operator encourages programmers to write stuff as one liners. Where you can do a whole lot of mutation and modification of stuff, many steps all in one statement. So you can take a big block of code and kind of squish it all down into one line.

[00:03:58] And that turns out to be a horrible trade off, because the benefit of getting everything down to one mind is hugely negative. Because it makes the code much harder to understand and much harder to maintain. And in fact the attackers took great advantage of that. Because nobody knows exactly what that code was except the attackers that spent the time to figure out what it was actually doing.

[00:04:19] I found in my own practice, if I'm using ++, I get this twitch, I can't help it, I start doing, [SOUND]. And it's stupid, and I know it's stupid and I cannot stop myself. So ultimately I had to say, no more, I am not going to write ++ ever again, I'm going to write, + = 1, and suddenly I could relax.

[00:04:43] Food tastes better.
>> Speaker 2: [LAUGH]
>> Douglas Crockford: But I hear from people all the time saying, no, I should be able to write x + + because it means exactly the same thing. And it's so much faster to type because you go, [SOUND], instead of going, [SOUND]. We're not saving time doing that, and if you're actually are losing time on that, there's this wonderful new thing called keyboard macros.

[00:05:12] Where you could do something like Alt+ and boom, it'll do that for you, so the typing speed argument is completely bogus. But there's a bigger problem here because they don't mean exactly the same thing, ++x is a thing that means exactly the same thing. So if I see somebody writing x++ in increment position.

[00:05:34] I have to ask, does this clown know the difference between pre-increment and post-increment? Because there's a really subtle off by one bug there because it's only off by one for a little piece of time. So debugging that kind of stuff is really hard and time consuming. And I have to look at every ++ in this program, and ask, did he get that one right?

[00:05:55] Did he get that one right? I've got to figure we've got at least one of these wrong and so makes these programs a lot harder to read. Recently I was reading some code and I saw this, ++x, ++x, okay, what's the story here, what's going on? It could be a copy and paste error, but more likely a second person came by and saw, there's an off by one error here.

[00:06:19] So I'll fix the off by one by putting another one of these in here. Whereas if the original form had said += 1, the obvious fix would have been to make it += 2. Which I don't think anyone would argue would be the better thing. This doesn't happen all the time, but it happens, and so it's something you need to watch out for.

[00:06:37] And it kinda raises the question, why do we need a completely different syntactic form for adding 1 then adding all other values? I cannot answer that question, I don't know why 1 is so peculiar that we need a completely different syntax for it. It doesn't make any sense to me at all, I'd challenge anybody to defend that.

[00:07:04]
>> Speaker 2: I'll give an answer. I think it was the one liner where it was so common with copying an array or a portion of array.
>> Douglas Crockford: Yeah.
>> Speaker 2: And so the arrays are the abstraction level, and understandably we saw the ++. Typically it was used in the sort of block tool?

[00:07:24]
>> Douglas Crockford: Yeah, which we've since determined is a really bad idea, there's no reason to do it anymore.
>> Speaker 2: We don't do it as often, I think.
>> Douglas Crockford: We shouldn't do it at all, there is no justification for it. So for no cost, by adopting a more rigorous style, many classes of errors can be automatically avoided.

[00:07:47] Here's another one, this is another of Thompson's, this is Thompson's fault, bcpl had an if statement with a block. And in bcpl, the parents around the condition were optional, but the braces around the consequence were required. And that turned out to be right, Thompson had been working in Fortran and PL1, and they did it the other way.

[00:08:13] So he decided to make the pairings around the condition required. And the braces optional, which turns out be wrong because it encourages stuff like this, this looks like this one. If a is true, we'll call b and c, but it's not, it's going to call c unconditionally. This causes errors all the time, this is a really common source of errors.

[00:08:39] So, my advice is, figure out which of these you mean, and write that instead. So always put the curly braces in every time, even if there's only one little thing behind it, put the curly braces on. It makes it much more likely that the next person who has to fix your code is going to be able to fix it without breaking it.

[00:08:58] And that turns out to be a really good thing, the counterargument is, I don't have time, because you have to go, [SOUND], so hard. This is a great trade off for two characters, you can make your code so much more robust in the face of agile development. I mean, this should be an easy trade off, always put the curly braces in, it makes your program so much more reliable.

[00:09:25] So as our processes become more agile, our coding must be more resilient. So I would characterize bad stylists in one of four classes, first, there are the under educated. We see a lot of these in the web, people who had no formal training in programming. Learned most of what they know from doing view source on really bad code.

[00:09:53] Often going through many layers of imitation and crappification leading all the way back to DreamLeader and other things. And I feel sad for those people, they just never had a chance.
>> Speaker 2: [COUGH]
>> Douglas Crockford: And then there are the old school guys. Guys who are coming to say JavaScript from C++, or Java because that's where the jobs are.

[00:10:18] And they're resentful, they'd rather be working in a man's language. But okay, I 'll write in your JavaScript, but there's no way I'm going to know what I'm doing, that's principle, which is crazy. I mean, JavaScript is the only language that people feel good about not knowing what they're doing.

[00:10:37]
>> Speaker 2: [LAUGH]
>> Douglas Crockford: And that's inexcusable, we're professionals, programming language isn't complicated. And our principle tool, you have to know what you're doing, even if it's JavaScript. So then there are the thrill seekers who want to show off their mad skills by writing code that they know is flimsy.

[00:11:00] Just to show that they can do it, and guys like that I think they should have to wear helmets when they are coding.
>> Speaker 2: [LAUGH]
>> Douglas Crockford: And then most dangerous are the exhibitionists, who will study the standards and understand exactly what the languages are doing. And exhaustively test them across all implementations and find weird crazy stuff that no one would ever expect you could do and do it.

[00:11:27] Just to show off that they figured this out and can do it. So they write programs that make no obvious sense just to show off what they can do and I think that's mad. And they will say, that was intentional, I know what I'm doing.
>> Speaker 2: [COUGH]
>> Douglas Crockford: And I say, no, if you knew what you were doing, you would not be doing that.

[00:11:49]
>> Douglas Crockford: So, programs are the most complicated things that humans make. And they have to be perfect and we are far from perfect, I am a deeply flawed human being. And so I require a lot of discipline in order to do this work, because it so hard, so designing a programming style demands discipline.

[00:12:11] It should not be about selecting features because they're liked or pretty familiar, or because they reduce your keyboarding. It should be because they help reduce your error rate, ultimately that's the only thing that matters. The consequence is you are going to be spending more time in the abyss.

[00:12:29] The abyss is this cold dark deep place where you go after your tower of operators has collapsed into a puddle of confusion. You just look into the darkness and say, my god, what have I done? I used to think that everybody should learn programming. I remember when I first learned it, and suddenly the world looked really different to me.

[00:12:50] And I had these tools for analyzing everything, and I thought, wow, this is great, everybody should learn to do this. I don't think that anymore, I think I am able to do what I do because there is something deeply wrong with me. Now so if a normal person tries to do programming, they can usually write the statements and all that, but then they have to debug.

[00:13:13] And they have to go down into the abyss, and if they come back, they say, I'm changing majors, I don't know how you guys do this. I can do this because there's this defect in me, which, a couple of defects. One is, I am unreasonably optimistic, I believe that I can go down into the abyss and I will find it and I will come back.

[00:13:41] There's no reason to think that I should be able to do that, but I think so and I can, normal people can't do that. Now, it turns out that optimism is why I can't schedule worth a crap, right? Because yeah, I should be able to do that, I can't, but why do I think I can because I'm an optimist.

[00:13:58] You have to be an optimist to do this work, but the other thing is the blackout, which comes after the euphoria. That you go down there and it's terrible and painful, and then you come back and you feel good. And you forget about it, and we do that all the time, and that's why we don't learn from our mistakes.

[00:14:22] And normal people don't have that blackout and they remember their time in the abyss and go, I'm not doing that again. So having discovered and started accounting for my time and figuring out, how much lost time do I have in my day? And how much of that was spent keyboarding, no, most of it was spent down there.

[00:14:42] And so if I want to be a more effective developer, I've got to spend less time there. That's the thing I should be optimizing, optimizing anything else doesn't make sense.