An integer is a whole number. A string contains text. A Boolean is true or false. A floating-point number represents numbers with fractional components.
Then you learn another programming language and discover that apparently none of this was quite as simple as advertised.
An integer in Python is not the same thing as an integer in C. JavaScript's number covers values other languages separate. Rust would rather make absence explicit than let null wander through a program. R has several different ways for something to be missing.
The definitions are not wrong. They are incomplete. A data type does more than tell a computer how to store a value. It expresses what a language assumes you should be able to represent, which distinctions matter, and which mistakes should be caught before the program runs.
So instead of memorizing another list of types, let's give several languages the same small collection of facts and see what happens.
Alex is about to have a complicated afternoon, mostly because of one missing middle name.
Nothing exotic. Text, an integer, a decimal value, an absent value, a collection, and a status chosen from a known set.
If data types were merely different spellings for the same concepts, moving this model between languages would be syntax conversion.
At runtime those values have types such as str, int, float, NoneType, and list. We did not declare them before assigning because Python is dynamically typed.
That makes Alex easy to get into the system. It also means constraints exist only if we deliberately add them.
Nothing about status = "ACTIVE" prevents a later status = "ACTVE". Python does not know our domain recognizes ACTIVE, SUSPENDED, and DELETED and has never heard of ACTVE. We can model that with an Enum, type hints, validation, or classes, but the bare string does not carry the rule.
Python's integers hold another surprise for anyone arriving from C or Java. A normal Python int is not limited to a fixed 32-bit range.
| Spelling | What it means | Who makes you deal with it | | --- | --- | --- | | None | The only nothing available | Nobody |
Already, "integer" has stopped meaning one universal thing. And None is a single, undifferentiated way of saying nothing is here, which will turn out to be a choice rather than an inevitability.
Yes, typeof null returns "object", a famous historical artifact that cannot be fixed without breaking existing code.
More important for our comparison, 42 and 0.15 share the ordinary type number, based on IEEE 754 double-precision floating point. JavaScript also has BigInt for integers beyond the safe range of number.
Absence is where it gets interesting. An uninitialized variable is undefined. A variable deliberately set to nothing is null. The language provides two spellings for emptiness and then declines to tell you which one means what. In practice one tends to mean "nobody has assigned this yet" and the other "somebody decided this is empty," except when a codebase uses them the other way around, or interchangeably.
Loose equality shows what the language really thinks. Zero, the empty string, false, and an empty array all agree they are the same thing. The two values that actually mean nothing is here do not join in:
