Search This Blog

Tech Book Face Off: JavaScript: The Definitive Guide vs. JavaScript & jQuery: The Missing Manual

HTML and CSS are the language of the web, but they are not programming languages. The programming language of the web is JavaScript. Every web browser interprets it, and almost every web page contains some of it. JavaScript is what turns modern web pages into responsive, interactive web apps. Every time you're flipping through a picture slideshow or adding a comment to a friend's posting, there's JavaScript at work behind the scenes.

With JavaScript supported in every browser, it is an incredibly easy language to experiment with. You don't need a compiler or an interpreter or an IDE, because you already have one. Here, try this in the browser of your choice:
  • In Chrome press Ctrl+Shift+J
  • In Firefox press Ctrl+Shift+K
  • In Internet Explorer press F12
  • In Safari press Ctrl+Alt+I
  • In Opera press Ctrl+Shift+I
A web developer console should pop up at the bottom of your browser, and if you browse around the web, you'll see all kinds of HTML requests, errors, and warning messages scrolling past as pages load. This console is not just a running log, though. It's a JavaScript Read, Execute, Print Loop (REPL). At the bottom of the console is a prompt where you can type in JavaScript, and when you hit Enter, it will be interpreted and the output will appear in the console. Try typing in
console.log("Hello world!");
What happened? You just executed JavaScript code in your web browser. Pretty neat, right? Okay, how about something a little more useful. Say you want to figure out how much money you're down today if you invested in 10 shares of Apple (AAPL) a year ago. You would type in
(571.7 - 408.38)*10;
And find out that you're down $1633.20. Not such great news, but at least you can use the console as a calculator. You can do anything in the console that you can do with a normal JavaScript file, but there's one caveat. Entire code blocks have to go on one input line, so declaring functions or large objects is a bit problematic. Firefox has a slick scratchpad to get around this issue. Press Shift+F4 to bring it up, and then you can enter as much JavaScript as you like, nicely formatted, and press Ctrl+R to run it. The output will appear in the console.

That capability is pretty incredible, if you think about it. Every computer comes ready for web development out of the box with no downloads necessary. If you're using Windows, you'd have to download a compiler or interpreter for almost any other language, but not JavaScript. Now that you can write and run your own JavaScript, you just need a good book to learn it. Here are a couple contenders:

JavaScript: The Definitive Guide front cover VS. JavaScript and jQuery: The Missing Manual front cover

JavaScript: The Definitive Guide


Weighing in at 1100 pages, JavaScript: The Definitive Guide is not to be taken lightly. If it is anything, it is aptly named, as it contains everything you could possibly want to know about JavaScript. It's not quite as long as it seems because the last 400 pages are language reference material, but 700 pages is still quite a lot to read through. Yet those pages do not disappoint. They are full of detailed descriptions and examples covering every aspect of the language in a satisfyingly clear, no-nonsense way.

I've found that there are three types of technical books that appeal to me: those that tell great stories or analogies, those that make great use of visuals, and those that present clear and relevant examples. This book doesn't have much in the way of stories or pictures, but it makes up for that with examples in spades. Each example is well thought out, easy to understand, and focused on the topic at hand. Beyond that, they are actually nontrivial and are potentially useful in your own programs.

The examples are really the gravy, though. The meat of the book is the explanations of the language features. Every page is filled with deep, sharp analysis of how to use the language, how the features are implemented, and how to get the best performance out of it.

I started out thinking that I would skim through most of the book, figuring that I could just pick up the syntax and skip a lot of the prose because it would be superfluous. But I found that I was reading almost everything, and spending a decent amount of time on it. Amazingly, despite its length, there was no wasted space, and it never got tiring. On the contrary, the whole book was pleasantly engaging, and I would definitely recommend it for JavaScript programmers of all levels. If what you want to do is possible in JavaScript, then it will be in this book.

JavaScript & jQuery: The Missing Manual


Compared to JavaScript: The Definitive Guide, this book was a letdown. Only about 20% of it actually dealt with the JavaScript language, and it was a pretty cursory treatment at that. There was no explanation of some of the most important concepts in the language, like closures and classes. Even objects were barely mentioned, when one of the most important things to come from JavaScript is JSON (JavaScript Object Notation) and its use in making dynamic web applications with Ajax.

The other 80% of the book was about jQuery, and David McFarland did a more than adequate job of covering that. The chapters were full of examples that were presented in a tutorial format so that you could type the code into a text editor, see the working examples, and experiment on your own. I liked that aspect of the book, so as a manual for jQuery, it hit the mark.

For a beginning web programmer who wants to learn just enough JavaScript to use jQuery and make dynamic, interactive web applications, this book would probably be perfect. That was not what I was looking for, though. I find that learning frameworks like jQuery is best done within the context of a project, and online resources are much more useable because they are searchable and have less risk of being out-of-date.

What I wanted was a book that went into plenty of detail and analysis with the JavaScript language and pointed me in the right direction with the jQuery framework. This book certainly fell short of those expectations. After trying out two books from The Missing Manual series with unfulfilled high hopes, I think I'm ready to pass on any more of these books. If you're looking for a book that will just tell you what you need to know to get a job done, this series will probably work for you. But if you're like me, and you want to get deep into the language, they're not going to be enough.

JavaScript: The Language


After spending a decade and a half with static compiled languages, JavaScript is my first dynamic interpreted language, and the difference is striking. I'd like to spend a little time here exploring the differences between JavaScript and C++ to show how pleasant JavaScript is to program in by comparison. Let's start with variable declarations. In C++ you have to think carefully about what type every variable is that you declare. Now in certain domains that's important because the variable types will have a big impact on performance, but let's assume that we're programming in a domain where that won't matter. You still have to declare your variable types in C++:
int samples[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = 0;
double mean = 0.0;
double stdev = 0.0;
You should always initialize your variables, so I did that. Now look at what's going on there. It's a little redundant to declare the variable type and then assign it to a value that makes it obvious what the variable type should be. JavaScript is much easier:
var samples = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var sum = 0;
var mean = 0;
var stdev = 0;
Nice! By the way, in most cases in JavaScript there are no integers, only reals, so it doesn't matter if you use '0' or '0.0'. You're going to get a real-valued variable. Declaring variables like this will spoil you. I've caught myself trying to do it in C++ now out of habit, so you've been warned.

Alright, let's say you want to create a quick object to hold some data on your pets. In C++ you'd have to at least create a struct and instantiate it. That would look something like this:
struct Pet {
  string name;
  string type;
  string breed;
  int age;
  double weight;
}

Pet myPet = {"Twitch", "cat", "Siamese", 10, 8.4};
And then there's JavaScript:
var myPet = {
  name: "Twitch", 
  type: "cat", 
  breed: "Siamese", 
  age: 10, 
  weight: 8.4
};
We can just create the object on the fly without having to declare an object type as a struct or a class. But now let's say we wanted to make the pet more permanent as a class. In C++ you might do this:
class Pet {
private:
  string _name;
  string _type;
  string _breed;
  int _age;
  double _weight;
public:
  Pet(string name, string type, string breed, 
      int age, double weight) {
    _name = name;
    _type = type;
    _breed = breed;
    _age = age;
    _weight = weight;
  }
}

Pet myPet = new Pet("Twitch", "cat", "Siamese", 10, 8.4);
You might want to include setter and getter methods for any of the members (class variables) that you'd want to change later, but I'll omit those for brevity's sake. I'm also not including any error checking code that would be required, like making sure the age and weight are within reasonable bounds. Now here's the equivalent JavaScript:
function Pet(name, type, breed, age, weight) {
  this.name = name;
  this.type = type;
  this.breed = breed;
  this.age = age;
  this.weight = weight;
}

var myPet = new Pet("Twitch", "cat", "Siamese", 10, 8.4);
Once again JavaScript is more compact and far less redundant. What a pleasant change of pace. It's not readily apparent that 'Pet' is actually a class, but once you get used to JavaScript, it becomes easily recognizable as one. I was amazed at how quickly I picked up most of the language, and it is, dare I say, quite fun to program in it.

The comparisons I went through here only scratch the surface of JavaScript's efficiency. Things that took lines and lines of tedious code in C++ or Java can be done with much less code in JavaScript. It's much easier to put your thoughts directly into code. You don't have to muck around with variable types and tedious class declarations. It feels like you can express the problem more directly in JavaScript without all of the cruft. If you haven't learned a dynamic language yet, I highly recommend this one. It will expand your mind and make you a better programmer.

Back to the Books


So which book is the one for you? If you want to know all about the JavaScript language and just enough about jQuery to get started programming dynamic web pages, go with JavaScript: The Definitive Guide. I would especially recommend getting it in an electronic version for two reasons: you don't want to break your back lugging the dead tree(s) version around, and as a reference it is infinitely more searchable on your computer or Kindle. Of course, if you do get the print version, you can also use it as a combination foot stool and bug/rodent smasher.

If you want to start programming dynamic web pages right away and don't care much about advanced features of JavaScript, go with JavaScript & jQuery: The Missing Manual. If you learn better from tutorial style examples, this book will be even better for you. You should be writing flashy interactive web pages in days.

As for JavaScript itself, enjoy it. If it's your first programming language, I envy the experience you're about to have. I can't imagine what it would be like learning JavaScript as a first language, but I'm sure it would be much easier than C++. Don't shy away from C, though. Once you know JavaScript, learning C will show you a whole other realm of programming that will serve you well. If you're coming to JavaScript from a static language, enjoy the freedom that JavaScript gives you. You'll probably wonder why you waited so long to learn a dynamic language. I know I do.

Exploring the World of Programming Languages

I first learned to program way back in seventh or eight grade with the Logo programming language. I found it fascinating to be able to move the turtle, a little triangle, around on the screen and make simple drawings with only a basic set of text commands typed into a console. I could tell that this experience of programming was fundamentally different than any other programs I had used on a computer, from games to graphics editing to word processing. To my young mind, the possibilities seemed endless and a little overwhelming, but I was inextricably drawn to that most basic of interactions with the computer. Figuring out how to make that turtle do what I wanted it to and build up a functioning program from basic elements appealed to my problem-solving nature. I was hooked.

A Beginner's Perspective


Today I can hardly remember the Logo syntax and commands. I recall that it had all of the basic elements of a programming language: variables, loops, conditionals, procedures, etc. But having only barely become a teenager and considering that this was my first programming language, I didn't have a clue what programming was really about, or how Logo fit in to the world of programming languages. I didn't even know that world existed. I was fumbling around in the dark with an underpowered flashlight, finding interesting little trinkets to play with, but having no concept of the enormous playhouse I was wandering around in. It's as if the programming world was like this:

Diagram of novice programming perspective with Logo

Fast forward a couple years. Now I'm a sophomore in high school, and I'm learning a new programming language called Pascal. That's a big change from Logo because Pascal is a compiled language instead of an interpreted language. I had no idea of this difference at the time. In fact, I didn't even realize that Logo and Pascal were related in any way. I thought of Logo as a toy program and Pascal as my first programming language. I didn't even consider the possibility that Logo and Pascal shared many programming constructs, but with different syntax. You see, my addled teenage brain couldn't conceptualize the overlap between these two languages. I was too concerned with learning the Pascal constructs to be bothered with relating it to another language that I thought was irrelevant, even though that comparison probably would have helped me understand Pascal and Logo much better. So my view of the world expanded a bit:

Diagram of programming perspective with Logo and Pascal

Now this picture is in need of a little explanation. I'm not claiming here that Pascal is a proper super-set of Logo, only that I relearned in Pascal all of the programming constructs that I had learned in Logo, plus some additional ones like variable types, arrays, and recursion. That is not to say that those constructs don't exist in Logo. I honestly don't know, because I wasn't exposed to those concepts until I learned Pascal. So this is a picture of what I learned in these languages and how I should have organized that knowledge, but didn't. As for the black background, that shows what I don't even know I don't know at this point.

Even from this severely restricted view of programming, I was enthralled with the possibilities that programming presented. I was solving math puzzles, experimenting with the limits of the computer's memory and processor, and creating games to play around with. Basically, I was having a great time messing around with computers and seeing what they could do, and my flashlight was getting stronger. I could see more of this language playhouse and interact with it in new and interesting ways. I still didn't have any real concept of how large the programming world was, but my view of that world was about to get a lot bigger.

Macros and Templates and Pointers, Oh My!


During my senior year of high school, I took a course on object-oriented programming in C++. In order to get to C++, the course went through C programming first. Both languages were mind-bending compared to Pascal. Learning C introduced pointers and dynamic memory allocation, both of which I struggled through but didn't fully understand until much later. It also introduced macros, a powerful feature for extending the language that can easily be abused if you're not careful.

C++ not only added object-oriented programming, an entirely new paradigm compared to the structural programming I had been doing before, but it also threw in operator-overloading, function overloading, and template meta-programming. The shift to object-oriented programming was a game-changer. It helps you think about program organization in an entirely new way that permanently affects how you do software design, even during the times when you fall back to structural programming. That is one of the great advantages of learning new programming languages. Every language is different in some way, either by having different features or implementing features differently than other languages, and learning those differences expands your mind and makes you a better programmer.

At this point, my view of the world looked more like this:

Diagram of programming perspective with Logo, Pascal, C, and C++

So in senior year of high school, I was pretty comfortable with the basic programming constructs of variables, conditionals, and control structures after being exposed to them multiple times in different languages, but the newer constructs of object-oriented programming and dynamic memory were much more muddled in my mind. That's okay because college would introduce another language to help me in this exploration of the world of programming - Java.

A Memory is an Awful Thing to Waste


As I entered the Electrical and Computer Engineering program at UW-Madison, Java was on its meteoric rise as The Next Programming Language so naturally, most of the computer science courses I took used it. Learning Java was easy, and since it was a completely object-oriented language, I couldn't help but solidify my understanding of that concept. As for dynamic memory, Java used garbage collection to manage dynamically allocated objects for you, whereas in C/C++ you have to keep track of all of that memory yourself.

When comparing dynamic memory management between these languages, C is the worst because you have to manage the raw memory all by yourself. C++ is better since you just have to keep track of the objects, and the runtime remembers the size of those objects for you. But Java's garbage collector keeps track of everything for you. There are some edge cases that you need to be careful of, but for the most part you can create new objects and let the garbage collector delete them when they're not being used anymore. Thinking about that difference in memory models between C, C++, and Java was what finally made dynamic memory fall into place for me.

Notice the contrast between these two concepts. On the one hand, object-oriented programming is fairly similar between C++ and Java. On the other hand, the memory models are drastically different between C, C++, and Java. In both cases, knowing more than one language was instrumental in my understanding of these complex concepts.

Java is also missing a number of language features that C++ has. Macros, templates, operator overloading, and bit manipulation operators are all gone. But, Java does have much better string support than C/C++ and a great concurrency model for multi-threaded programming. The more I learned about Java, the more I appreciated the similarities and differences between it and C/C++, and that was making me a better programmer with a bigger view of the world. Here's what it looked like to me now:

Diagram of programming perspective with Logo, Pascal, C, C++, and Java

One curious thing I've noticed through this whole learning process is that at every step of the way, I was totally oblivious to the fact that there were other programming languages out there that had dramatically different features and concepts than the ones I already knew. Each new language was a surprise and an unexpected learning experience. That wasn't going to change for quite a long time, and it's fascinating looking back and seeing how naive I was, especially in light of all of the languages and concepts I learned between this picture of the world of programming and my realization that the black void was actually filled with an incredibly diverse ecosystem of languages.

What Goes on Under the Hood


Before I was aware of that language diversity, I learned a few very important things about the workings of microprocessors and languages that deepened my understanding of programming. The first was assembly language, the language on which all other programming languages are based. Assembly is actually a family of languages, with each one being unique to a particular microprocessor architecture. The assembly code can be translated directly into the machine code that runs on that particular microprocessor, and compared to most programming languages, it is obscure. All higher level language constructs are built up from these low-level instructions, like the way the same Lego blocks can be assembled into a multitude of different space vehicles.

Knowing how language constructs are built up from basic instructions greatly increases your understanding of how they work, what their best uses are, and what their performance impact is. Even more so, learning assembly teaches you about pointers because they are fundamental to assembly coding. You can't do anything effectively in assembly until you understand pointers backwards and forwards. I thought I had them pretty much figured out before learning assembly, but I was dead wrong. After going through the mental machinations of assembly coding with near constant pointer arithmetic puzzles to solve, pointers in C/C++ made a whole lot more sense, and my programming reached a new level.

Most programmers don't code in assembly these days, though. How do we get from C or Java to assembly? Why, compilers and interpreters, of course. Knowing how to write high-level language constructs in assembly code by hand is one thing; knowing how to parse a high-level language and generate the assembly code automatically is even better. The course I took on compilers opened my eyes to the real inner workings of high-level languages in a way that learning more languages never could. It gave me an incredible appreciation for how much work high-level languages do for you, and how micro-optimizing your code can not only be useless, but detrimental to performance. The compiler is performing all kinds of optimizations that you can't possibly keep in your head as you write code, so the best thing you can do is make your code as human understandable as possible. Then let go and let the compiler do its job.

On the other side of assembly language lives the actual hardware, but the hardware was most likely designed using a language as well - a hardware description language. The two most common HDLs are VHDL and Verilog, and I learned the latter while taking multiple courses in computer architecture during college. Understanding both Verilog and computer architecture also deepened my understanding of programming. Like compilers, the hardware in modern superscalar out-of-order processors is doing all kinds of optimizations on the code it's running. So even if you turn off all optimizations in the compiler, the hardware optimizations are still going to change the way your code runs. Micro-optimizing your code really is a fool's errand.

As for programming in Verilog, it is unlike any other programming language I know of because everything happens at once. Every line of code, every assignment, every operation gets evaluated every clock cycle, and for statements not controlled by a clock, they are evaluated every time their inputs change. Now that's parallel programming. Understanding how that all works, and how to manage that kind of complexity, definitely improves your programming skills in other languages.

Unveiling Reality


Learning all of those things took most of my college career, along with a slew of other CS, EE, and math courses. But nothing I learned in college really expanded my view of the programming language world beyond C/C++ and Java. It wasn't until fairly recently that the lights finally came on, and that was due to two things: reading lots of programming blogs, and learning JavaScript. The blog reading made me much more aware of the shear number of other languages and other kinds of languages out there, and JavaScript is one of those other kinds of languages.

Whereas the languages that I knew best (C/C++ and Java) were static languages, JavaScript is a dynamic language. That difference alone is huge compared to the differences between C, C++, and Java. On top of that, JavaScript is interpreted instead of compiled and it has a host of other features that were new to me, like object literal notation, property attributes, sparse arrays, closures, functional programming, and class prototypes.

After these two key experiences, my view of the world really changed:

Diagram of programming perspective with Logo, Pascal, C, C++, Java, and JavaScript

Programming in JavaScript is so different than the other languages I know, it's refreshing and downright exciting. I still have a lot to learn to become proficient in it, but I can already see that it's going to open up whole new ways of thinking about and designing software for me. And now I realize how small my view of the world was. The single most important thing I can do to improve as a programmer is learn another language. It doesn't matter how many I know, the next language I learn is going to teach me things I don't yet know about programming and improve my understanding about things I thought I already knew. I still have a lot to learn.

Tech Book Face Off: HTML & CSS: Design and Build Websites vs. HTML5: The Missing Manual

HTML and CSS are the language of the web. Every time you visit a website in your browser, the browser sends a request to the website server to retrieve an HTML file. The server responds with the file, which is in human-readable plain text. That HTML file likely contains links to CSS and JavaScript files, and those are downloaded and interpreted along with the HTML to give the webpage the final look that you see in your browser. The entirety of the web that you see is based on these languages, and if you want to be an participant in the web, you would benefit greatly by learning them. On the one hand, I waited far too long to learn HTML and CSS myself. For how easy they are, I should have picked them up years ago. On the other hand, the benefit of waiting is that I didn't have to endure the raft of changes that those languages have gone through in the last decade, culminating in HTML5 and CSS3. Since the time was long overdue to learn them, I grabbed a couple of books and got to work.

HTML and CSS: Design and Build Websites front cover VS. HTML5: The Missing Manual front cover

HTML & CSS: Design and Build Websites


This book is another reason it was beneficial to wait to learn HTML and CSS, not that I should have waited. I have never experienced a technical book like this before. Jon Duckett did an incredibly masterful job presenting these languages in a way that the reader can absorb quickly and easily. It's a full-color layout with beautifully structured pages that detail all of the important HTML tags and CSS attributes, giving clear examples of each tag or attribute throughout the chapter and then a longer, fully working example at the end of each chapter.

After seeing a book done like this, it now seems painfully obvious that this is the way a book on HTML and CSS should be done. Why wouldn't a book on the languages of the web be in full color with an engaging layout and clear, no-nonsense coverage of the topics? Why wouldn't it be visual? The only way it could have been better is if it was interactive, essentially an impossibility for a printed book. It was an absolute pleasure to read, and it was as if the content was being absorbed directly into my brain through my eyeballs. I ended up finishing the whole book in a matter of hours. When I was finished, I couldn't believe I had waited this long to learn HTML and CSS. These languages were so straightforward, and this book made them ridiculously easy to learn.

Of course, because the book is full of such visually rich content, it's really impossible to give it justice with words. Here are a couple pictures to give you an idea of how well done it is. Mentally compare them with every other technical book you've read.

HTML and CSS a closer look at the paragraph tag

HTML and CSS background position example pages

The content is so well presented and engaging that the reader can't help but quickly absorb everything. Really, this is the way it should be done! Go out and get your own. Highly recommended.

HTML5: The Missing Manual


I actually had read this book before HTML & CSS: Design and Build Websites, which could be good or bad, depending on how you look at it. It was good for this post because I can do an actual face-off between two HTML books. It wasn't so good for my leisure time because I wasted some of it reading a book I never would have finished, had I read the other one first.

I went on a bit of a rant last week about a comment that was made in this book about recursion. That was definitely not the defining weakness of this book, only a minor infraction as this book is not about programming techniques. However, it is a fairly characteristic example of the larger issues I have with this book.

Matthew MacDonald does start out rather well. His initial narrative about HTML5 is quite interesting, and it kept me engaged for a couple chapters. He is a decent writer. After the first couple chapters, though, I started to wonder who this book was really written for. He specifically made the point of telling the reader that he expected you to already know HTML and CSS prior to HTML5 so he would only be covering the new features. Okay, fine, I could deal with that, but by chapter 4 he had pretty much covered the new tags in HTML5 so he moved on to validating web forms and embedding audio and video in websites.

This is where things started getting weird. You see, these things take a fair amount of JavaScript to get working in a clean, user-friendly way, and that's fine. Matthew does a fine job of going through all of the idiosyncrasies of the different browsers and how to handle all of those issues while making nice, dynamic webpages using JavaScript. However, he assumes you already know JavaScript. He warned about that in the introduction, too. That isn't quite so bad. The JavaScript is actually pretty simple, and even if you have a passing familiarity with it, you should be able to understand it just fine. But then he keeps making comments like, and I'm paraphrasing here, if you're head's spinning from all the JavaScript code, don't worry. After a few instances of this apologizing or pandering or whatever it was, it started getting seriously annoying, even distracting. If he's going to give the reader a bunch of JavaScript because it's the best way to work around missing browser support for new features, he could do it without being patronizing.

As the book went on, it basically became a book about how to write JavaScript for HTML5 features. If your JavaScript skills are weak, then there pretty much wasn't anything there for you. If they are strong, you're going to wish he would just get on with the code and dispense with the disclaimers. Overall, I would say the book was light on HTML5 and heavy on JavaScript. I honestly wonder if it should have been titled HTML5 and JavaScript: The Missing Link. I can't imagine the type of web designer that could pick it up and use it as an HTML5 manual.

One last problem with this book is how quickly it will be hopelessly out-of-date, if it isn't already. The various browser manufacturers are implementing HTML5 features as fast as they can, and most features are already done in Firefox, Chrome, and Opera. Most of the book's content was about how to handle features that were not yet available in one or more browsers, but that time is quickly coming to an end. That will leave a lot of content largely irrelevant. Basically this is a book that no one needs.

Internet Explorer: The Missing Features


If you noticed, I didn't include Internet Explorer in the list of browsers that implement most of HTML5's new features. That wasn't an oversight. If you're using Internet Explorer 10 on Windows 8, you're in better shape, but that's not a lot of users. One thing these two books both make quite clear is that Internet Explorer is different than other browsers, and not in a good way. Microsoft does so many thing differently with the way Internet Explorer handles HTML and CSS that if it wasn't included with Windows, it's obvious that no one would use it. If the chronic incompatibilities are not intentional, then they're at least embarrassing. Though I suspect the former.

Beyond the slow and distorted feature adoption, Internet Explorer is also living in the dark ages of browser revisions. Firefox and Chrome long ago moved to the continuous model of browser updates, so every time you restart your browser, it could be updated to the newest released version (not sure about Opera, since I don't use it). This is great for both users and developers. Users don't have to think about updating their software anymore, and developers can assume that users are always on the latest version. Especially for a piece of software that needs to be connected to the internet to work, that makes a whole lot of sense. With Internet Explorer's antiquated update model, it could take more than a year for users to transition to a new version, longer with IE 10 because it needs Windows 8. That's an eternity on the web!

You Should Learn HTML and CSS


Yes, you should. It's easy. All you need is a text editor, like Notepad, and a web browser. I can't believe I waited this long to learn it. As for how to learn it, isn't it obvious? Read HTML and CSS: Design and Build Websites. It accomplishes everything it should with beauty and grace, and it stays focused on all of the HTML and CSS that matters. It is such a great book, there really is no comparison with any others. It raises the bar for a good technical book way beyond any other offering. I only wish I had held off on learning JavaScript a bit longer. Jon Duckett's next book, JavaScript & jQuery: Interactive Front-End Web Development is coming out in July. I enjoyed HTML and CSS so much that I'll probably get it anyway. As for HTML5: The Missing Manual, leave it alone. I'm pretty sure it's not for you.

The Misuse of Recursion

Recursion is an important and powerful concept in computer science. It's something that every programmer should have in their toolbox because the right application of recursion can produce elegant solutions to difficult problems. That's why I'm astounded that authors of programming books occasionally make some pretty blatant errors about recursion that only serve to confuse the reader and mislead the novice programmer. One case that I came across recently in HTML5: The Missing Manual was actually addressed to the advanced user in a "Power User's Clinic" sidebar:
This technique is useful for complex computational tasks that require recursion, like calculating the Fibonacci sequence.
There are two things wrong with this statement. Do you see them?  If you already know recursion, then you probably do. If not, let's take a little crash course in recursion to get you up to speed, first.

What is Recursion?


Recursion is actually quite a simple concept. It is merely a function that calls itself. That's it. If you don't want infinite recursion, you need some way to stop the function from calling itself every time it runs. To do that, you would pass a slightly different value as a parameter to the function each time it was called, and when that parameter reaches a certain value, the function stops calling itself.

By way of example, let's implement addition using recursion. You would never do this in a real program because it's ridiculously inefficient, but it works as an easy example since everyone knows how addition works. Let's start with a function that takes two parameters 'a' and 'b', defined as Add(a,b). This function should return a result equal to a+b, but we're going to do it by calling the Add function again within itself.
Add(a, b) {
    return Add(a, b-1) + 1
}
Do you see what's going on there? The Add function calls itself with a new 'b' parameter that's one less than before, and adds one to the result before returning it. Unfortunately, this is not enough because the recursive calls will never end. If you want it to end, you have to check for a stop condition:
Add(a, b) {
    if (b == 0) return (a)
    otherwise return (Add(a, b-1) + 1)
}
In this case, we can use the identity a+0=a, so if 'b' is zero, return 'a'. This is all pseudo-code, but real code wouldn't look that much different. Now that we have a working recursive function, we can think about what happens with some real inputs. If you call Add(3, 3), what actually happens is Add gets called repeatedly as shown in the following sequence of operations to produce the result:
Add(3, 3)
= Add(3, 2) + 1
= (Add(3, 1) + 1) + 1
= ((Add(3, 0) + 1) + 1) + 1
= ((3 + 1) + 1) + 1
= (4 + 1) + 1
= 5 + 1
= 6
All we did was implement addition by counting up from 'a' the number of times specified by 'b'. The same principle could be used to implement multiplication with addition or exponents with multiplication. Now that we all know what recursion is, we can look at why that quote is so wrong.

What Computational Tasks Require Recursion?


It seems to be a common misconception in the software industry that there are certain complex problems that need to be solved with recursion. This is simply not true! Any problem that can be solved with recursion can be solved with iteration instead, and usually with better performance. Iteration is another programming concept where a task is repeatedly done in a loop. For any programming problem, recursion and iteration are interchangeable.

Now there are certain problems that are solved more easily or elegantly with recursion. Sorting is one example of such a problem. Conceptually, sorting a list of numbers using recursion is quite straightforward. First you split the list of numbers in half and sort each half of the list. You keep splitting the lists until you get to the point where each list is only one number. Then you merge each pair of lists by selecting whichever number is smaller at the beginning of the two lists and moving it to the merged list until both original lists are empty. Once you have merged all of the split lists, you have a sorted list. This algorithm is fittingly called mergesort.

Another type of problem that can easily be solved using recursion is any kind of graph traversal. A graph is made up of nodes and links connecting those nodes. To search a graph for something, you start at a node in the graph. Often times there is a root node where you start, and then the graph is called a tree. If the node you're at contains what you're looking for, then you're done. Otherwise, follow each link from your current node and search that sub-graph. Pretty simple, right? If the graph can have cycles, then things get more complicated, but the basic idea is really easy to understand.

Both sorting and graph searching can be solved using iteration, but the algorithms are much uglier and harder to understand. Iteration does provide one benefit, though - performance. An iterative version of an algorithm is almost always faster than a recursive version because the recursive function calls incur some time and memory overhead, unless you can get the recursive version into a form that uses tail-recursion and the language supports tail-call optimization. If that's not an option, and the problem size is too large, you could quickly run out of memory and crash your program.

I'm not saying you should never use recursion. There are, in fact, many real situations where recursion is clearly better than iteration. The point is that you definitely need to understand the trade-offs when using it, and there is no problem that absolutely requires recursion.

Is Recursion Suitable For The Fibonacci Sequence?


If we revise the original questionable statement to say:
This technique is useful for complex computational tasks that lend themselves to recursion, like calculating the Fibonacci sequence.
Is it any better? Would you actually use recursion to calculate the Fibonacci sequence? It is defined recursively where given a number 'n',
Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)
Fibonacci(0) = 0
Fibonacci(1) = 1
But implementing this definition in code as a recursive function is expensive! For every Fibonacci number, you're calculating almost the entire Fibonacci sequence twice. That takes a lot of time and memory. A much faster and smaller algorithm would just start with two variables set to 0 and 1 and then add one to the other, back and forth, 'n' times. Here's the pseudo-code:
Fibonacci(n) {
   f0 = 0
   f1 = 1
   for (i from 2 to n) {
      if (i is even) f0 = f0 + f1
      otherwise f1 = f0 + f1
   }
   if (n is even) return f0
   otherwise return f1
}
This iterative form is almost as easy to understand, it takes a constant amount of memory, and it's way faster than the recursive form. I would never calculate a Fibonacci sequence using recursion when iteration is so much better.

We Can Do Better


If calculating the Fibonacci sequence is a bad example of when to use recursion, what's a good example? It should be something obvious, something that immediately makes sense to most people that you would actually use recursion to solve it. I already brought up two problems that are better - sorting and searching, and both of them are pervasive in software development. Think about it. Most of what Google, Amazon, Facebook, and Twitter do can be boiled down to sorting and searching. Why not use those key problems as the examples of when to use recursion:
This technique is useful for complex computational tasks that lend themselves to recursion, like sorting or searching massive data sets.
I'm not sure that any of these large companies use recursion in their algorithms, although it's pretty likely. Even though it is true that recursion runs into memory problems as the problem size grows, and iteration is generally faster when running on a single processor, everything changes when the problem size gets so large that you need to split it up and run the program on multiple processors. You see, most recursive sorting and searching algorithms use a divide-and-conquer approach. They automatically divide up the data set while processing it. That makes it quite easy to spin off chunks of data to be crunched on separate processors while keeping the basic algorithm simple.

It isn't that difficult to come up with much more compelling examples of why to use recursion. Using the Fibonacci sequence is lazy and misguided. It doesn't make sense to use recursion for it, and you're rarely going to need to calculate the Fibonacci sequence anyway. But everyone who uses software is exposed to sorting and searching, so those are the prime examples that need to be used when talking about recursion. Maybe recursion would be more widely understood if those who talked about it used real-world examples that mattered.