|
|
|
|
|
by saghm
877 days ago
|
|
To be fair, TypeScript is a bit different because you can use it to compile to JavaScript rather than merely annotating in JavaScript files, which is crucial because it means that compilation can _fail_ to produce JavaScript. If I recall correctly, you can still have it produce JavaScript even if the type checking fails, but the fact that you can't just directly run the TypeScript makes a difference. With the Python type annotations, you can still just run the code directly without _ever_ compiling, let alone if type checking fails. > If you really want a hard type system, just move to GO or Rust or C or something with a real type system enforced. For what it's worth, Rust also has no types at runtime, which is why Rust doesn't have reflection and relies heavily on compile-time magic with macros. The difference is that there's no way to get a binary to run if the code doesn't typecheck. The most underrated feature of a compiler is that it can say "no"; in the case of Rust, the killer feature of the language isn't what you're allowed to do, but what you're _not_ allowed to do, even accidentally. |
|
And this isn't just a side effect of the build tools, but a genuinely useful feature. While I'm working on a change, I can run half-finished code and get some feedback before fixing the rest. This is particularly useful for tests - I can test a module, even if I've not yet updated all of that module's usages, to sanity check whether what I'm doing makes sense.
There can definitely be downsides to this separation of type system and runtime behaviour, but it's also very useful, and it works the same in Typescript and Python.
I think the biggest issue that Python's type checking has in comparison to Typescript is just sheer power: Typescript can very explicitly and correctly type real-world Javascript code, whereas typed Python, in my experience, ends up feeling a lot more like old-school Java than idiomatic Python. And it's difficult to sell old-school Java to Python developers.