DEV Community

Cover image for Type System FAQ

Type System FAQ

stereobooster on July 29, 2019

Sit down, we need to talk about types The post is inspired by this thread. People have so much misconception about types, use the wrong terminol...
Collapse
 
codemouse92 profile image
Jason C. McDonald • Edited

Really good insight! This will definitely help a lot of people understand a lot of the debates regarding typing systems.

From a computer point of view, there are no types, there are only bit strings...Types exist for people.

My only pedantic addition is that types aren't merely a high-level abstraction. Of course, once again this one of those "it's complicated" issues you and I tend to get into interesting back-and-forths about, so I'll to try to distill this as far as possible:

Getting this out of the way...objects, classes, and enumerations (etc.), along with their consequential "types," are only abstractions. They really don't "exist" at machine level, only in the higher level language.

But so-called "atomic types" are usually a slightly different scenario. This typically include integers, booleans, and floating-point numbers (either single or double precision). There's a mix of abstraction and underlying logic with these. These atomic types are uniquely delineated, structured, and addressed in memory.

Which types actually constitute an atomic type, and which are just glorified versions of other types. For example, a C char is actually a form of int. A boolean may also be an integer...or it may not. It really depends on the implementation of the language. Once again, this is where it gets "wibbly-wobbly-timey-wimey."

(P.S. Strings aren't ever atomic; they're arrays.)

You are still absolutely correct that all data is just bitstrings. It's possible to interpret the same 32-bit chunk of memory as a single-precision floating point number, or as a 32-bit integer, or as a Unicode character. The trouble is, the data will be effectively "garbage" for one of those interpretations.

For that reason, at the assembly level, type still exists in one sense — it defines how that bitstring is interpreted. We lack most (or all) of the syntactic sugar that makes delineating type so convenient, but the core behavior is still needed.

Type has to be a concept at the machine code level precisely because type doesn't exist as far as memory itself is concerned. There's no label sitting on the bitstring declaring "I'm an integer!" or "I'm a floating-point number!" There's not even typically a sentinel (marker) to declare where one "variable" stops, and another starts.

Knowing how much binary data to read, and how to interpret it, is the responsibility of the code. In fact, a massive percentage of bugs originate from this one responsibility getting botched. The (machine) code's knowledge of how much data to read, and how that data is to be interpreted, is the logic that constitutes "type". It's not pretty or simple this close to the silicon — imagine trying to store all your data in the bit-array data structure your language provides — so higher-level languages abstract that logic out into various typing systems.

All that to say, types (conceptually) don't exist from a memory perspective, but they must exist from a code perspective. Type systems, on the other hand, are abstractions that exist for people.

Collapse
 
stereobooster profile image
stereobooster

The trouble is, the data will be effectively "garbage" for one of those interpretations.

But who will understand that this is a garbage? Does machine care? Do transistors or NAND gates care? This is the human who gives interpretation to the things.

It's possible to interpret the same 32-bit chunk of memory as a single-precision floating point number, or as a 32-bit integer, or as a Unicode character.

Who decides which interpretation to give it? Programmer who wrote the program, in which they put instruction: "go to memory X, take N digits and treat them as number..."

This is tricky philosophical question, if you like this kind of things I recommend to read Real Patterns essay.

Collapse
 
codemouse92 profile image
Jason C. McDonald • Edited

Does machine care? Do transistors or NAND gates care?

Literally true of anything, though. The computer doesn't care about any of this, because it's a non-being. It's just as "happy" being unpowered altogether. Literally anything a computer does only ultimately matters to the human who gives interpretations to the things.

And, like I said, as far as memory is concerned, type isn't a thing.

It is a tricky philosophical question, I agree. Again, my point is, the concept of "type" does exist at machine code level, just in a painfully non-abstracted fashion.

Although, I think we actually agree on that.

Thread Thread
 
stereobooster profile image
stereobooster

My opinion: it exists in the same way as glider exists in the game of life. The structure itself exists on the board, but the meaning exists in the head of observer. From board (game of life) pov: yet another configuration. From human pov: oh look it has interesting properties.

Thread Thread
 
codemouse92 profile image
Jason C. McDonald • Edited

Yeah, I think that's fair. I just don't want anyone to get the idea that "type" (conceptually) isn't an important concept in machine code, which would be fundamentally misleading.

BTW, although I have limited experience writing assembly, I checked all of this with one of my co-workers, who programmed in binary and machine code (with punchcards) as his full time job for many years.

Thread Thread
 
stereobooster profile image
stereobooster • Edited

Fair point. I'm not sure shall we call it Types or Encoding 🤔.

Non scientific chart:

Thread Thread
 
codemouse92 profile image
Jason C. McDonald

Heh, excellent chart. "Machine types" is a bit closer to what I'm talking about, I think, although encoding certainly enters into it some.

Collapse
 
resir014 profile image
Resi Respati

Thank you for this! I was so let down by the many misconceptions of the post you mentioned (I ended up writing a response blog post myself), glad you're here to clear them up.

Just one tiny error that I noticed though. in the makeSureIsNumber example, you throw an error in the isNan() check which says Not a string. I think you're meant to say Not a number?

Also, you might want to take a look at the unknown type. It's like any but with some form of type safety, in the way that you need to check the value of said type before passing it anywhere.

Collapse
 
patricklai profile image
Patrick • Edited

Actually, a great article. JS (and its community) is not the best place to learn about these things, However there is clearly was a need for typing and hence the existence and popular adoption of all these tools (ts/flow, etc).

With the current exploding popularity, I think everyone who use/is thinking about using type script would benefit in some way from reading this.

:thumbsup

Collapse
 
pepesalazar profile image
Pepe Salazar

Nice article, good job explaining the different concepts, I think this can clear many questions to people who are new to typing systems.

I would just add one more thing. I usually hear people talking about strings and numbers, however they don't consider the type checking to an object level. Having a type declaration that is also a structure declaration can help developers to know when they missed a property initialization, operations, or even if and object property should be composed of other object.

Collapse
 
louy2 profile image
Yufan Lou

XD I quivered at the mention of "categories".

I have habitually measured the "strength" of type systems by feeling. My feeling is roughly based on how often I see type verification discussed in the communities.

My ranking is (from weakest to strongest):

Assembly
< C
< Perl = Python = Ruby = JavaScript = Lisp
---- Dynamic above vs. Static below ----
< Java = Go = SQL
< Scala = OCaml = Haskell = C++ = Rust = TypeScript = Elm
< Idris = Lean = Coq = Isabelle

Just as you point out that types are for people, I think most of type system is about culture. After all, one language's compile time is just its compiler's language's runtime, and a Turing complete runtime is capable of any checking. Lean prover is written in C++, but rarely do C++ users put as much care into their types as Lean prover users (who are mathematicians).

That care translates to better ergonomics, and better ergonomics in turn lead to more people caring. I have heard rumors about some C++ programmers writing their templates in Haskell first so that they don't have to suffer the C++ template error messages.

In my opinion, TypeScript really offers a unique window into the intersection of the two cultures. I am really surprised by some complicated type signatures necessary in TypeScript to accommodate dynamic JavaScript code. It is probably the first time that a static type system of a dynamic typed language is adopted widely enough to demonstrate such a direct contrast and provoke such confrontation, which I believe will ultimately lead to more awareness and improved quality.

Collapse
 
shavyg2 profile image
shavyg2

Well done

Collapse
 
xtofl profile image
xtofl

Maybe, in the set of all type systems, we can define a weak ordering "stronger than" with assembly at the weakest level :).

We need more posts about foundational stuff like this! Thanks!