The WATs of JavaScript

At CodeMash 2012, Gary Bernhardt gave a now infamous lightning talk that has become known simply as The WAT Talk, in which he presents several of the more surprising behaviors of Ruby and JavaScript. I’ve passed the video around quite a few times, and I’ve pointed out some other JavaScript behaviors that seem pretty outlandish at first sight. But I’m feeling a little guilty about poking fun at JavaScript, so I wanted to dive further into these WATs and talk about why they happen.

I’m not here to defend JavaScript — it doesn’t need my defense. It’s not a perfect language, and it’s not my favorite language, but it is the single most popular language on the web right now, and because more and more people are using it for the first time, I think it’s worth the effort to go over some of these unexpected behaviors to help newcomers avoid common pitfalls.

But first, the WATs.

The WATs

WAT?!

Background: Type Coercion

I’m putting the cart before the horse a bit here, but I’m going to go ahead and spoil bits of the rest of this post by telling you up-front that many of these WATs involve type coercion. JavaScript is a dynamically typed language, but it is also a weakly typed language, meaning that variables may be automatically changed from one type to another in fairly wide contexts. Coercion is distinct from casting, in which a variable is changed to another type, but only if you’re changing the interpretation of its contained data or if the new type is higher up in the same type hierarchy. For example, in Java when you cast a long to an int, you’re asking that the top 32 bits be ignored and the remaining bits be treated as a 32-bit signed integer; when you cast a String to an Object, you’re asking the compiler to treat calls to the reference as if they were calls to an instance of Object.

Type coercion, on the other hand, is happy to turn an int into a String for you. In a language like Java, it happens only in a very few places, and is usually pretty obvious and easy to predict. If you’re used to these rules, though, JavaScript’s coercion can be pretty surprising. Not only will it turn a Numeric type into a String for you, but it will go the other direction too.

And now, without further ado, on to the list of WATs.

WAT Number One: Empty Array Not Equal To Empty Array

There’s actually a lot going on here. At first glance, it looks absurd: an empty array does not equal itself?! But that’s not really the question we asked.

So, what question did we ask? Like a Facebook relationship status, it’s complicated. JavaScript’s double-equals equality operator has a fairly extensive set of rules that make it more difficult to use than the double-equals operator in other C-like languages.

What we’re really asking here is, “Is one instance of an empty array equal to another instance of an empty array?” In JavaScript, the answer is no, because when you’re comparing two instances of the same type, double-equals will return true if and only if they are the same instance. We’ve created two instances here, one on the left side of the operator, and one on the right side of the operator. They are not the same instance, so [] == [] evaluates to false.

WAT Number Two: Empty Array Equals Bang Empty Array

OK, now what is this nonsense?

Although I agree it’s pretty confusing, it’s not nonsense if you know the rules and if you apply them in the right order. Here, the bang operator binds more tightly than the double equals, so the first thing we have to do is evaluate ![]. It so happens that in JavaScript, the bang operator coerces whatever it’s applied to into a boolean value. An empty array, in JavaScript, is considered “truthy”, so when it’s coerced into a boolean, it becomes true, not false, and the bang operator converts the true into a false. Now the question looks more like this:

OK, but that still looks bizarre, right? We just said that an empty array was truthy, not falsy, and true certainly does not equal false!

But, like I said, double-equals is complicated. The rules say that when you’re comparing an Object on the left and a boolean on the right, you convert both sides to numbers (the same as applying the Number() function), and re-run the comparison.

In JavaScript, Number([]) => 0, and Number(false) => 0, so now we have a new question:

That’s more like it. Yes, zero is equal to zero.

WAT Number Three: Empty Array plus Empty Array Yields Empty String

This is actually fairly straight-forward once you understand that the addition operator in JavaScript only operates on two types: Strings and Numbers. We’re asking JavaScript to add two Arrays, which it doesn’t know how to do, so it coerces them both into Strings and then concatenates them together. Calling [].toString() yields an empty string, and concatenating two empty strings together yields an empty string.

WAT Number Four: Empty Array minus Empty Array Yields Zero

This case is very similar to the previous case, except we’re using the minus operator instead of plus. Again, JavaScript doesn’t know how to subtract arrays, and while Strings can be concatenated with the plus operator, Strings don’t understand the minus operator at all, so JavaScript coerces both sides into Numbers for us, instead of Strings. If you call Number([]) in JavaScript, you get 0, so what we’re really saying is:

That makes a lot more sense.

WAT Number Five: An Array Of Values Is Equal To A Weird Looking String

Woah, hey now. What’s this all about? It’s all about coercion and that double-equals operator again.

Here, we are using double-equals to compare an Object and a String. The rules say that when you’re comparing an Object on the left side and a String on the right side, you have to perform some operations to the left hand side to figure out how to do the comparison. The end result of this is that the array on the left is coerced into a String (by calling its toString() function, if it has one). And it just so happens that calling [null, undefined, []].toString() yields the String ",," (Why? Because null, undefined, and [] all turn into empty strings, and JavaScript joins those empty strings with commas). So we’re really asking if two strings are equal:

Yes, they are, so it evaluates to true.

WAT Number Six: Array Plus Object Yields The String “[object Object]”

This is still more type coercion. We’ve already discussed how the addition operator only operates on Numbers and Strings, and what’s happening here is JavaScript converting both sides of the operator into Strings. An empty array, as we’ve already seen, gets converted into an empty string. But what about {}?

In JavaScript, {} is (usually!) an Object literal. It’s really saying, “Make an instance of Object for me, please.” So now we’re concatenating an empty string, and the result of coercing an Object instance into a String.

Well, the default toString() for Object returns the string “[object Object]”. The code now becomes:

WAT Number Seven: Object Plus Array Yields Zero

BUH!

Wait wait wait. We just got finished explaining how JavaScript coerces both sides into a String, right? So shouldn’t this be exactly the same as the previous example?

Well, not quite.

We’ve actually been bitten by a bizarre edge case here. JavaScript has misunderstood our intentions completely. As it scanned the line, it interpreted the initial {} not as an object literal, but rather as an empty code block. Yes, really. In essence, it has just decided to ignore it completely, and treat the line as if it were written this way:

That in itself would seem nonsensical, except that JavaScript also allows unary addition operator. Unary addition + x is equivalent to calling Number(x), so what you end up with is an empty Array instance being converted to a number, which yields 0.

WAT Number Eight: Math.min() is greater than Math.max()

Before we explore this, let’s look at how these functions are defined, and what they return.

Math.min() and Math.max() are being used deceptively in this WAT. Most languages define global min and max values, and JavaScript does too — but not with Math.min() and Math.max(). Instead, JavaScript gives us Number.MIN_VALUE and Number.MAX_VALUE, and these behave exactly as you would expect:

Math.min() and Math.max(), on the other hand, are functions used to find the min and max values of a sequence of numbers. If you use them correctly, they make sense:

And if you call them without arguments?

Why? It’s how they’re implemented. Math.min() initializes its return value to Infinity and then looks for the smallest number in the sequence. There isn’t one, so it returns Infinity. Similarly, Math.max() initializes its return value to -Infinity, and looks for the largest value. There isn’t one, so it returns -Infinity.

The final form of this makes a lot more sense:

WAT Number Nine: Floating Point Madness

This is probably the sanest WTF on the page. If you’ve ever worked with floating point numbers in any language, this kind of thing is probably already familiar to you. It’s just a run of the mill floating point accuracy issue.

But 100 is an integer, isn’t it? Well, no. Not in JavaScript. JavaScript numbers come in only one flavor: IEEE-754 floating point. There are no integers in JavaScript. This may in fact be the single most important thing to know about JavaScript, especially if you’re doing any kind of math.

This problem would present itself in C, too. Example:

If you run this code, what do you get? Not 0.108! On my computer, you get 0.1080000028014183, because of inherent limitations in floating point accuracy.

JavaScript isn’t alone here, it’s just more likely to bite you because you have to use floating point, while you’re free to use other numeric types in other languages.

Conclusion

I’ll be frank: JavaScript is weird, but it’s here to stay, and if you find yourself working in it, it’s good to immerse yourself in the weirdness and try to get a feel for what’s going on under the hood. I hope this post has helped to clear up a handful of the stranger seeming cases, especially if you’re new to it and coming from the background of another language.

Do You Want To Build an FPGA? Part Two

In my last post, I showed you how to download Altera’s Quartus II software and get a new, empty project started for the BeMicro CV platform.

This time, we’ll learn how to build a Verilog module and compile it.

The Blank Slate

We left off looking at a blank slate, an empty project.

Empty Project

This is always the most intimidating part of any project. What do we want to do?

The next step is to define a top-level design file. From the menu. select FileNew…, and you will be presented with a list of components. Select Block Diagram/Schematic File from the list.

New Block Diagram

Next, click FileSave As… from the menu, and save the new top level design file as flashy.bdf.

We won’t get very far with just a blank design file. We need a Verilog Module to define the behavior we want from our counter, so next, choose FileNew… from the menu, and select Verilog HDL File. This will open up a blank Verilog file, ready for your input.

New Verilog

The Verilog “counter.v” Module

Verilog is a language that defines how our FPGA is to behave. It’s tempting to think of it as a programming language, but it’s dangerous to fall into this trap. It’s not a programming language, it’s a hardware definition language.

What’s the difference? A programming language describes linear process that implements an algorithm step-by-step. A hardware definition language, on the other hand, describes how a digital circuit should behave using words. It is not implementing an algorithm, it’s implementing a circuit!

The distinction can seem very subtle. When you’re describing how hardware behaves, it can certainly look very much like a program or an algorithm. But it’s not, and it’s always very important to keep that in mind. So, we want to design a circuit that will take a 50 MHz clock signal as input, and count down on the 8 LED outputs forever.

Here’s our Verilog module to describe that behavior. Save this file as “counter.v”:

Verilog Module

It’s short and sweet. The top-level module definition has two arguments, clk_50, which we will map to our 50 MHz clock signal, and leds, which we will map to our LED outputs.

Internally, there are two registers: an 8-bit register named leds, and a 21-bit register named counter. These are used to latch state in the circuit. Because we’ve named one of the registers the same as one of the outputs, they will be automatically connected for us.

The critical part of the circuit description is the always @(posedge clk_50) block. This describes what happens at the positive edge of a clock trigger on the clk_50 input. It says that we decrement our counter register, and if the counter happens to be all 0’s, we latch the state of the LEDs plus one into the leds register. We’re using the internal counter register as a delay to slow down the rate at which we update the LEDs.

You may be confused at this point, because I said our circuit was going to count down, but clearly we’re incrementing the leds register. What’s that about? Well, it turns out the BeMicro CV uses LEDs that are active low, meaning that they light up when the corresponding output is grounded. The end effect is that if you want all the outputs lit, you write 00000000 to the output. In other words, when we count up with our leds register, it looks like the LEDs are counting down. If you wanted the LEDs to count up, you could just invert the output. I’ll leave that as an exercise to the reader.

Adding the Verilog Module to the Project

We’ve described a simple circuit here. Now we need to tell Quartus how to connect the inputs and outputs of our circuit. To do that, we’ll first need to make a circuit diagram symbol for our module.

Right-click on the “counter.v” file in our project, and select Create Symbol Files for Current File

Symbol File

Quartus should compile your file. If you get any errors, double-check to make sure there are no typos! After it’s compiled, you can close the Compilation Report tab, and then return to the flashy.bdf tab.

Right-click anywhere inside the flashy.bdf tab, and select InsertSymbol… from the context menu.

Insert Symbol

You should be presented with a dialog like this. Select the counter symbol from the Project folder, click OK, and then drop the symbol anywhere into the flashy.bdf tab.

Counter Symbol

Now we have a symbol placed into our project, but we still need to map its inputs and outputs. Right-click on the symbol you’ve just placed, and select Generate Pins for Symbol Ports from the menu.

Generate Pins

There, now things look a little more complete. We can see that we have some pins named clk_50 and leds[7..0].

Pins

Connecting The Pins

Although our symbol now has inputs and outputs, those inputs and outputs are not yet connected to the real physical BeMicro hardware! To do that, we’ll need Quartus’s help.

From the menu, select ProcessingStartStart Analysis & Elaboration. This step will analyze our top-level schematic and figure out how many inputs and outputs we’ll actually be using on our FPGA chip.

Start Analysis

The module will compile, and Quartus will analyze it. Depending on your hardware, this may take a minute or two. You should eventually see a compilation report letting you know the analysis was successful. You can close the compilation report once you’re done reviewing it.

Analysis Report

Now comes the critical part: We can map our circuit’s inputs and outputs to real FPGA pins!

From the Assignments menu, select Pin Planner

Pin Planner Menu

You should be presented with the Pin Planner. This dialog allows you to map the flashy inputs and outputs to the FPGA’s pins. You’re actually looking at a real map of all 484 pins on the FPGA, but don’t worry — we’re only going to be using nine of them!

This is where we have to turn to the BeMicro’s documentation for help. We want to figure out what input the 50 MHz clock is on, and what outputs the LEDs are on. I’ll save you some time and pain by just putting the information here, because it turns out that the BeMicro CV documentation is wrong. Their mapping of LED pins is out of order. Oops!

Here’s how the BeMicro CV actually maps its pins:

FPGA Pin Voltage BeMicro Mapping
H13 1.8V 50 MHz Clock
Y3 3.3V LVCMOS LED 7
AA2 3.3V LVCMOS LED 6
AA1 3.3V LVCMOS LED 5
W2 3.3V LVCMOS LED 4
U2 3.3V LVCMOS LED 3
U1 3.3V LVCMOS LED 2
N2 3.3V LVCMOS LED 1
N1 3.3V LVCMOS LED 0

We need to map these using the Pin Planner. In the end, your Pin Planner should look like this:

Pin Planner Mapped

It’s safe to close the Pin Planner window now, and you’ll notice that the symbol has changed somewhat, to show that the inputs and outputs have been mapped.

After Mapping

Now you’re ready to compile the whole project. From the Processing menu, select Start Compilation. Compiling should take a minute or two, depending on your hardware.

Once it’s all done, congratulations! You’ve built your first FPGA module! Now all you need to do is actually load it onto the FPGA and start it running. We’ll cover that in our next and final blog installment.

Composite Video

Sweet, I just found this YouTube video about adding composite input to a television. It looks much simpler than I anticipated.

I also just got the schematics for my set, so I’m in business.