Hacker News new | ask | show | jobs
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.

1 comments

I'm not sure that's really a practical distinction between Typescript and Python. Most of the practical bundling setups I've seen use a tool like Babel or Esbuild, which doesn't do any type checking - instead the type checking is done as a linting/testing check beforehand, the same as with Python. And as you point out, even if you compile directly with Typescript, it will quite happily compile code that doesn't pass the type checks, as a configuration option.

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.

> Most of the practical bundling setups I've seen use a tool like Babel or Esbuild, which doesn't do any type checking - instead the type checking is done as a linting/testing check beforehand, the same as with Python.

I think the difference is really one of UX (or DX I guess) and availability: Yes, if you already work with a toolchain, there won't be a difference. However, lots of people don't. If you just use the language runtime on its own and want to get your program running with the minimum possible effort, then for typescript, you'll run the transpiler and feed the resulting JS to a browser or nodejs vm; for python, you'll just run your program with the python interpreter directly.

The thing is that for the "minimum" typescript workflow, type checking is per default performed, while for the minimum python workflow it isn't. That you could also disable type checking for typescript or use a linter to get it done in python is besides the point - those are additional options and tools that you have to spend additional effort to activate - and you have to know about them in the first place. Someone who just has some basic skills in the language is unlikely to do so, so effectively, type checking for them is performed in typescript but not in python.

Ah, I see what you mean. I guess it's a matter of framing - to me, choosing to install and run Typescript is the equivalent of choosing to install and run mypy - in both cases, you've added an additional tool above and beyond the default (Javascript and Python, respectively). I guess I don't really see Typescript as a separate language from Javascript in the sense, it's just Javascript with knobs on.

So there isn't really a "minimum" Typescript workflow because by using Typescript, you're already choosing to install additional tools and set up a more complicated workflow (compile then run, as opposed to just running Javascript). And if you'd do that with Javascript, you'd do that with Typescript as well.

(I think it's no coincidence that the long-term plan from the Typescript team is to have type annotations become part of regular Javascript syntax, in the same way that Python includes type annotations out of the box. In both cases, they'd be ignored by the parser and only used as metadata for the purposes of a separate type checking tool. The Typescript team do not see themselves as developing a separate language to Javascript, but rather just a dialect that includes types.)