Hacker News new | ask | show | jobs
by lostcolony 2440 days ago
On that note, I'd include Erlang. It's not gradually typed, per se, but you can have a fully dynamic language (no type specs, no Dialyzer), a completely optimistic static analyzer for inferring types and warning where it's inconsistent (Dialyzer runs), and then you can add specs where needed to tighten up and improve what Dialyzer can catch, to basically be a fully static language.
2 comments

It's relatively easy, but not free, to do this. I find that the erlang (and elixir) guides seem to be a bit scant on best practices to achieve this level of discipline, for example, wrapping all gen_sever calls in module functions and presenting a well-defined API for the genserver module (and possibly, even linting for no naked genserver calls) is not really explained in this light. Similarly guidance is not provided for wrapping enum module calls (since that similarly destroys typing information)
Yeah; it requires some rigor to do. My point was simply that it _can_ be done, and while the effort is high, it does allow you to move from pure dynamic language, to highly defined type checking.
Dialazer is pretty bad and not even close to a static language.
If you fully spec out your code, it's actually quite close. In a project we did that in, the only type errors we encountered were ones that a static system would not have caught either (due to their being caused by incoming data that did not conform to our type expectations; for instance, deserializing JSON to a specific type).

Without specs, it will assume every type is 'any()', unless it has information to infer something more stringent. For instance, if it sees you add 5 to it somewhere, it will instead assume it is a number. Etc. Even if in practice it actually is a list of some kind (and so that addition of 5 will fail). Which, yes, ain't great. Hence why I said it was a gradual transition; it will catch provable errors (i.e., if you call append on that same variable as above, it will note that there is no type that allows both append, and + an integer, and error), but leave plenty of things uncaught that could have been caught had it known the type in question (via a type spec).

That critique is a bit unspecific but I tend to agree.

I have heard good a stuff about "gradulizer" though. It uses a gradual type system instead of dialyzers success typing.

https://github.com/josefs/Gradualizer