Hacker News new | ask | show | jobs
by BoppreH 836 days ago
I've always wondered if global type inference wouldn't be a game changer. Maybe it could be fast enough with caching and careful language semantics?

You could still have your IDE showing you type hints as documentation, but have inferred types to be more fine grained than humans have patience for. Track units, container emptiness, numeric ranges, side effects and idempotency, tainted values for security, maybe even estimated complexity.

Then you can tap into this type system to reject bad programs ("can't get max element of potentially empty array") and add optimizations (can use brute force algorithm because n is known to be small).

Such a language could cover more of the script-systems spectrum.

3 comments

Type inference is powerful but probably too powerful for module-level (e.g. global) declarations.

Despite type systems being powerful enough to figure out what types should be via unification, I don't think asking programmers to write the types of module declarations is too much. This is one area where forcing work on the programmer is really useful to ensure that they are tracking boundary interface changes correctly.

People accept manually entering types only at a relatively high level. It'd be different if types were "function that takes a non-empty list of even numbers between 2 and 100, and a possibly tainted non-negative non-NaN float in meters/second, returning a length-4 alphanumeric string without side effects in O(n)".
one of the other reasons global inference isn't used is because it causes weird spooky action at a distance - changing how something is used in one place will break other code.
I've heard that, but never seen an example*. If the type system complains of an issue in other code after a local change, doesn't that mean that the other code indeed needs updating (modulo false positives, which should be rarer with granular types).

Or is this about libraries and API compatibility?

* I have seen examples of spooky-action-at-a-distance where usage of a function changes its inferred type, but that goes away if functions are allowed to have union types, which is complicated but not impossible. See: https://github.com/microsoft/TypeScript/issues/15114

Try writing a larger OCaml program and not using interface files. It definitely happens.
I've never used OCaml, so I'm curious to what exactly happens, and if language design can prevent that.

If I download a random project and delete the interface files, will that be enough to see issues, or is it something that happens when writing new code?

If you delete your interface files and then change the type used when calling a function it can cascade through your program and change the type of the function parameter. For this reason, I generally feel function level explicit types are a fair compromise. However, making that convention instead of required (so as to allow fast prototyping) is probably fine.
Just require it for public functions. Your own code can be as messy as you want unser the hood
> If the type system complains of an issue in other code after a local change, doesn't that mean that the other code indeed needs updating

The problem is when it doesn't complain but instead infers some different type that happens to match.

I dabbled a bit with ReasonML which has global type inference, and the error messages from the compiler became very confusing. I assume that's a big reason for not gaining more adoption.