Comment by duped
9 months ago
> Type checkers shouldn't get in the way of your code compiling.
I don't get it, what's the point of type checking if not to reject invalid programs? The point of a type system isn't simply to add annotations to a programmer (and some type systems can omit them entirely) but to define the subset of programs that are correct within the set of all the programs that can be expressed.
I understand (and have used in production) optionally/gradually typed languages, and without fail codebases will opt for using types up front and not ignoring type check failure because they are always incorrect.
A type error is the compiler/run time telling you "I don't understand what you told me" so why do you want to ignore that?
And if the point is that you want to be able to change the type signature of something without having to refactor giant chunks of code, then that suggests your code is structured poorly to begin with. It should be easy to pull in what you need and play with it without affecting everything else if you haven't done a bad job of architecting the codebase.
Because often, and especially with heavily interactive programs like games or UIs (any web page), you don't know if something will be good or not until you build some working version of it. The more barriers there are (type checkers, compiler errors, etc), the longer it will take you to prototype something usable to check if what you're building is good.
Sometimes, it's useful to bypass these things for a prototype and you don't care if it crashes on any edge case. This is why typescript is so popular on the web - you can quickly prototype something with JS, then once you find the right solution, add types and productionize the code
I agree with this, but I don't think dynamic types is the only solution. Something like Roc[0] strikes a better balance: it gives you a flag for development, and when enabled, all compilation errors become warnings. The compiler substitutes every function it couldn't compile with one that panics at runtime.
[0] https://www.roc-lang.org/
But a type error isn't an edge case! It means you've written something the compiler can't understand.
> This is why typescript is so popular on the web - you can quickly prototype something with JS, then once you find the right solution, add types and productionize the code
I think you've got it backwards - TS is popular because people want to use types up front, but it has to work with JS, which is so dynamic that it's impossible to write a sound type system that can even touch it.
I don't want to reply "git gud" but I really am struggling to understand how people are writing code that where it is so difficult to use type information or where changing it is so cumbersome that you think it's a barrier. And I don't see many games or performant GUIs written in dynamically typed languages, particularly outside the web. Even in very dynamic languages like Objective C, things are still well typed.
> But a type error isn't an edge case! It means you've written something the compiler can't understand.
I get it! But the compiler here is getting in the way, so Rust is the wrong tool choice here, or for anything that requires quick prototyping (like the OP said)
> writing code that where it is so difficult to use type information
It's not difficult, it just takes longer. Typing up front works well when you know exactly what you're building. When you don't, or are doing experimental design, they just get in the way until you've settled on a direction. This direction is not due to technical constraints or language choice, it's simply that designing complex user interactions is hard and you don't know it's correct until you have users use it
> dynamically typed languages
Because the cost of prototyping in a dynamic lang and then fully rewriting in a performant language is higher than having slower iteration speeds in typed languages. But also, this is why a large number of new non-web GUIs use electron (or are mac exclusive, which offers other benefits for GUI development)
> I think you've got it backwards - TS is popular because people want to use types up front,
Personally, I mix it up. There are things I know what their types will be no matter what so i add them up front. Then there are other things which I do not know, and I add those types at the end once i'm performing the final cleanup before code review
The nicest part is, TS runs regardless. I often refactor my types frequently since I get them wrong a lot (especially the up front ones) and have TS in a failing state while developing, but the TS compiler doesn't get in my way, and still works for the types that I expect to have working
A type error means a type error, and nothing more. Type errors do not mean "incorrectness." Here is an example of something you can't do in rust, but can do in other statically typed languages.
```rust
struct Type1 { id: u32 }
struct Type2 { id: u32 }
fn main() {
}
```
This code works perfectly fine. These two structs have the same signature. The only thing that doesn't work is the names. There are dozens of things like this where your code works but the compiler is too strict. This is terrible for rapid iteration. It's good for other things like modeling your domain with types.
2 replies →
Exactly this. Typing in the final version is great. Typing up front is almost always getting in the way.
Most interesting programs involve a lot of figuring things out as you go, and so any "tax" on that process is one you hope to avoid. The last thing you want is for the language itself to be the source of that tax any more than it has to be.
>I don't get it, what's the point of type checking if not to reject invalid programs
It can take longer to think about how to properly type instead of just writing some code, testing it out, and immediately seeing if something is wrong. You also often get into a situation where linters who like to act like type-systems give you arcane errors (looking at you TypeScript).
In the moment I just want to move some data around and quickly try out an idea, I don't need it to be resilient or perfect.
>I don't get it, what's the point of type checking if not to reject invalid programs?
Because not every program that doesn't compile is necessarily invalid.
> Because not every program that doesn't compile is necessarily invalid.
I think that more programmers should be aware of this point. Rust doesn't reject code that will crash, it rejects code that it cannot prove won't crash.
The code being rejected might be just fine (as numerous examples in the article showed).
>And if the point is that you want to be able to change the type signature of something without having to refactor giant chunks of code, then that suggests your code is structured poorly to begin with.
The article addresses this, multiple times. In brief, the "poor structure" isn't the problem.