Hacker News new | past | comments | ask | show | jobs | submit login

My background is php and then javascript. My first experience with 'types' was learning that apparently javascript's implicit type conversion was not normal and actually pretty bad. That made sense to me.

Then I learned about explicit types via TypeScript, and that made sense to me too, although I could imagine how this could explicit typing could get in the way of my prototyping, small projects, or REPL-driven development.

Now, a few years later, and having learned a bunch of new languages, both explicitly and implicitly typed, I'm mostly wondering why I'd go for anything that isn't gradually typed as an ideal approach.

I get the impression that the core discussion is explicit vs implicit (correct me if I'm wrong), and I can see how in some cases enforcing explicit typing is worthwhile, but for most of the work I actually do, it seems like the best solution is something gradual and flexible. Typescript, or perhaps some (improved) version of Elixir/Erlang's Dialyzer, or Clojure's spec: flexible enough to allow for said prototyping, small projects, and REPL-driven development, but gradually rigid enough to be useful when things grow larger and more solidified.




> I'm mostly wondering why I'd go for anything that isn't gradually typed as an ideal approach.

In some ways, gradual or optional types give you the best of both worlds. You aren't obligated to submit to the whims of the type checker when you don't want to, but you can elect to get the safety of types where it matters. You can get the brevity of dynamic typing and the safety of static types.

But, in other ways, they give you the worst of both worlds. If you have any sufficient fraction of typed code in your program, then you will feel pressure to structure even the untyped parts of your program in ways that play nice with static typing. Some API design choices are more "typable" than others, and having static types at all discourages you from some interesting API choices.

In order to play nice with untyped code, most gradual and optionally typed languages are deliberately unsound. There are holes in the type system that can't be closed. That means compilers cannot rely on types for optimization purposes.

You end up with the rigidity of static types and the performance of dynamic types.


I wonder if coming from the other way would be acceptable for fans of dynamic typing.

Instead of adding types gradually to a dynamic language (like Typescript sorta does with Javascript), we could add type-checking features that enable a kind of "statically-checked duck typing". Complete inference (like Elm, Crystal or Haskell) gets you halfway there – most of the time you don't have to write method/function signatures.

Then add structural typing like Extensible Rows [1] or Elm Records [2], or something that type-checks based on the structure instead of classes, and it allows you to have the compile-time type-checking of Interfaces or Generics/Templates without the extra typing. Then you can add explicit generics/templates later if you want.

Both Crystal and Elm get very close to that for me, but not 100%. I honestly think that this is a safer bet than gradual typing that could lead to very similar results, but I don't know how feasible or acceptable to mainstream programmers this is.

[1] https://github.com/tomprimozic/type-systems/tree/master/exte...

[2] https://elm-lang.org/docs/records


If you haven't already, you should see this paper from 2017 about sound gradual typing: https://www.cs.cornell.edu/~ross/publications/nomalive/nomal... The performance and rigidity issues you mention are solvable. Although the research is pretty cutting-edge and not implemented in many programming languages yet.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: