def foo(bar)
bar + bar
end
bar1 : Int32
foo(bar1)
bar2 : String
foo(bar1)
bar2 : Int32 | String
foo(bar1)
The above code gives you three methods to generate code for: foo(Int32), foo(String), foo(Int32 | String).This isn't really a problem for small projects, but with large projects (60k+ loc), you end up with some methods such as puts, Array(T)#<<, etc with thousands of instantiations.
We have some edge-case semantics (we don't cast arguments to their restriction types, which we plan to remove before 1.0) which also prevent us from allowing only instantiating foo(Int32 | String) when we change the definition to `def foo(bar : Int32 | String)`. Hopefully in the future, we can allow the compiler to take advantage of method argument type restrictions to reduce the number of instantiated methods and speed up the compiler.
That doesn't mean the compiler will be super slow if you don't annotate your methods, it just means that the stdlib and shards' public API will start annotating it's method arguments more (which gives you better docs and error messages anyway).
For more info: https://github.com/crystal-lang/crystal/issues/4864
I'd be interested why a compiler would even need to do so in the first place --- constructing every possible one instead of every one it encounters as clearly needed right now.
Edit: OK I see it now, you can have stuff like Int32|String. Still though.. TS can "handle" that too?
Here is one of the creators of the language talking about the global type inference of Crystal:
And if it that were the worst part of meta programming, that might be ok, but it's not because the existence of meta programming puts ceiling on just how fast the Ruby runtime can be.
It's true that it shouldn't be abused and it most often is, but it does have its place.
It makes me sad for the reason you said, it’s most often abused.
On the other hand I've read reports that sufficiently large codebases begin to hit machine memory limits for the compiler because they have to scan and construct every possible union type in the codebase. Not sure what there is to do about that other than bisecting the codebase into shared libraries over time.