Every A is a B, but not every B is an A, C?

Every A is a B, but not every B is an A, C?

The title of this blog references a common pattern in learning, from a programming perspective. For example, when you learned basic geometry, you were probably taught some variation of this statement:

Every square is a rectangle, but not every rectangle is a square.

At first it might seem to be a deliberate brain teaser, the kind of thing a person only says to sound smart (they might also throw out words like “antimetabole”.) Geometrically, of course, it’s completely true: if a rectangle is a four-sided figure with four right angles, then a square is just a special type of rectangle. What makes a square special is that all its sides have the same length. And the way the above statement is constructed places the focus squarely on that specialness.

Taking a step back, we can see that this kind of statement is important to the way we learn. At least as far back as Aristotle, people recognized that categorization was a crucial way of understanding the world. We examine each new fact and try to fit it in with the experiences and frameworks we have already built up in our minds. In a search for order and meaning, we try to categorize and classify everything. And often we come across important relationships between things that are similar but different. Or, as in the example above, we find subcategory relationships.

In software development, the idea of a subcategory relationship is extremely useful, and comes up in many different areas: Inheritance in object-oriented development, data normalization in schema design, even simple bug hunting. What got me thinking about this recently was a JavaScript code review. In the code under review, an Array was being used where an Object would have sufficed. Now, for developers who have come to JavaScript from other languages it might seem that, following the principle of doing the simplest thing that could possibly work, an array, being a simpler data type than on object, would be a better first choice. But JavaScript is different.

In JavaScript, almost everything is an object. JavaScript objects are extremely flexible because they allow you to dynamically add keys (also known as properties or fields) and values at runtime. With the help of the [] getter/setter, the hasOwnProperty() method, and the delete operator, objects in JavaScript behave much like dictionaries or hash-maps in other languages.

In the code under review, the developer needed to maintain a list of string values, and then later determine whether a particular value was in the list.  Items would be added and removed from the list, as well. Although an Array worked, it required more complicated code (and probably performed slower) than a simple Object map. It’s difficult to work with a standard Array in this scenario without resorting to multiple for loops and splice() calls. See this JSFiddle for a simplified example of what I mean. Of course, there’s more to it than that, and there are definitely times when an Array would be better suited than an Object – for example, when you need to easily know the size of a list or map. (Yes, I’m ignoring the new ES5/6 goodies.) Still, knowing what a plain Object can do in JavaScript gives you a powerful tool when striving for the simplest code.

How can you easily remember the distinction between an Array and an Object in JavaScript? It helps to describe them using the same square/rectangle statement we considered above:

In JavaScript, every Array is an Object, but not every Object is an Array.

I’ve found that statements of this form continually recur in computer programming. More examples:

  • In C, every string is a pointer, but not every pointer is a string.
  • In databases, every clustered key is an index, but not every index is a clustered key.
  • In networking, every TCP packet is an IP packet, but not every IP packet is a TCP packet.

These are somewhat contrived and obvious, but they illustrate the point: subcategory relationships between similar but different concepts can be a powerful tool to help you learn.

What other subcategory relationships have you found helpful to understand in programming? Can you think of some other antimetabole statements that make them easier to remember?

Share this:

Posted in:

Developer's Corner