> I remember when I first learned about type inference, one of my first thoughts was, why can’t we just create a statically typed language that does type inference for everything. The compiler would still have to figure out the types at compile time anyway, and I’d save myself a few keystrokes.
> Turns out this is what Crystal does. It does aggressive type inferencing, and only asks you to declare types when it can’t figure it out.
> Crystal does not have a global type inference engine
As the sibling comment points out, this has been a feature of many functional programming languages for a long time. If you infer everything, though, it becomes a little unfriendly in use.
When you make a change in one location and accidentally use the wrong type for something, it can affect global type inference and you get error messages in other locations. In essence, if you use only type inference, a change anywhere in the program can turn up as an error due to a type mismatch anywhere else in the program.
Most languages with powerful type inference aim for a middle ground where important types are declared and mostly-local types are inferred.
The underlying principle in Crystal is that data structures usually require explicit declaration while types of values passed around on the stack usually don't need to be declared. I find it makes it easy to reason about the result while still being very stream lined.
> Turns out this is what Crystal does. It does aggressive type inferencing, and only asks you to declare types when it can’t figure it out.
> Crystal does not have a global type inference engine