←back to thread

Type checking is a symptom, not a solution

(programmingsimplicity.substack.com)
67 points mpweiher | 1 comments | | HN request time: 0.205s | source
Show context
guerrilla ◴[] No.45141819[source]
This is silly. Types are specifications of programs and data. The only reason that isn't obvious is because most of our type systems are rudimentary. It becomes obvious once you pick up anything with a bit more power (Haskell with extensions or any dependently typed programming languages). A type system is not just another ad-hoc solution, it's fundamental and essential to what we're doing. This is obvious if you know the (pre-computer) history of type theory: Types specify sets of objects intensionally. Types describe what our program should do and are also a very clear form of documentation. On top of that, you can't even get rid of types if you wanted. The best you can do is make them implicit. You have to make a decision about how to interpret data in the end, and that's typing. Even assembly language and machine code has types. Even electronics have types, we just don't think of it that way (but look at the 7400-series ICs if you want explicit examples).

This post is written by someone rather naive of computer science. Their description of a "function" betrays that. The failure to recognize UNIX pipelines as function composition also betrays that and so does the whole "black boxes" paragraph.

replies(4): >>45142293 #>>45142585 #>>45142633 #>>45142905 #
tialaramex ◴[] No.45142905[source]
> Even assembly language and machine code has types.

I agree with the overall thrust of your argument, but on this specifically what's noticeable in an assembly language is that data doesn't have types, the operations are typed. That's usually not really a thing in programming languages. It does happen, but it's not common.

For example Rust's Wrapping<i8> is a distinct type from Saturating<i8>, and if we've got variables named foo and bar with the value 100 in them, if foo and bar have the type Wrapping<i8> the addition operation means the answer is -56 but for Saturating<i8> the exact same addition operation gets you 127

In assembly or machine code there's be Wrapping addition, and Saturating addition and they'd both work on integers, which don't themselves inherently care.

replies(1): >>45143235 #
guerrilla ◴[] No.45143235[source]
No, the data is typed; it's just not type checked.
replies(1): >>45144698 #
tialaramex ◴[] No.45144698[source]
I don't buy it. Go look at the Godbolt assembly output when you write software with some floating point constants on a modern CPU. The assembly has no floating point constants, because why would it, the data doesn't have a type, those constants are just emitted as integers, because they're the same thing.

The 32-bit integer 0x3f000000 is literally the same thing as the 32-bit floating point value 0.5

replies(1): >>45148307 #
guerrilla ◴[] No.45148307[source]
Types are not data formats.
replies(1): >>45148710 #
tialaramex ◴[] No.45148710[source]
Sure, but what I'm getting at is that RAX does not have a type

If we write that Quake 3 "fast" inverse square root, the machine code does not have any casting or type changes, but the C does and the Rust does, because in machine code the operations were typed but in these high level languages the values were typed.

replies(1): >>45161686 #
1. guerrilla ◴[] No.45161686[source]
Types are also not type annotations.