When I teach a Ruby or Python class, I always begin by going through the various data types. My students are typically experienced programmers in Java, C++, or C#, and so it no longer surprises me when I begin to describe numbers, and someone asks, “How many bits is an integer?”
My answer used to be, “Who cares?” I would then follow this with a demonstration of the fact that in these languages, numbers can be pretty darned big before you have to worry about such things.
But over the last few months, I’ve begun to understand the reason for this question, and others. Indeed, I have begun to understand one of the reasons why dynamic languages can be so difficult for people to learn after they have worked with a static language.
Let’s take a simple example. In a typical, C-style statically typed language, you don’t just assign a variable. You must first declare it with a type. You can thus say something like this:
int x; x = 5;
In both Ruby and Python, you can do something similar:
x = 5 # no type declaration needed
On the face of it, these seem to be doing similar things. But they aren’t.
In a static language, a variable is an alias to a place in memory. Thus, when I say “int x”, I’m telling the compiler to set aside an integer-sized piece of memory, and to give it an alias of “x”. When I say “x = 5”, the compiler will stick the number 5 inside of that int-sized memory location. This is why static languages force you to declare types — so that they can allocate the right amount of space for the data you want to store, and so that they can double-check that the type you’re trying to store won’t overflow that allocated area.
Dynamic languages don’t do this at all. Whereas assignment in a static language means, “Put the value on the right in the address on the left,” assignment in a dynamic language means, “As of now, the name on the left points to the object on the right.”
In other words, assignment in a dynamic language isn’t really assignment in the traditional sense. There’s no fixed memory location associated with a variable. Rather, a variable is just a name in the current scope, pointing to an object. Given that everything in both Python and Ruby is an object, you never have to worry about assignment not “fitting” into memory.
This is also why you can say “x = 5” and then “x = [1,2,3]” in a dynamic language: Types sit on the data, not on the variable. As long as a variable is pointing to an object, you’re just fine, because all object pointers are the same size.
The bottom line, then, is that = in static languages and = in dynamic languages would seem, on the surface, to be doing similar things. But they’re definitely not. Once you understand what they are doing — putting data in memory, or telling a name to point to a value — many other mysteries of the language suddenly make more sense.