I'm not sure if this is even possible, depending on how the compiler works internally, but... Not all code needs the performance of static typing. It would be nice to be able to declare an "any type" variable, that basically works like Ruby variables, and uses dynamic dispatch.
Static typing is more like a requirement for the language to work than a performance enhancing feature. A any type doesn't really make sense and I fail to see an use case for it. I closest way I can think to implement it would be a union type of all possible types. Not very useful nor performatic. Also this brings all kinds of problems, like calling an instance method on it. Currently the method call is resolved at compile time and the runtime doesn't really have the means of resolving it.
If the performance isn't needed and you want to fully avoid static types, well... Ruby is there for that.
You fail to see a use case? How about "every program ever created"?
Think about it. Many programs need high-performance compiled code for intensive computation. Very few programs, however, need this _everywhere_. Usually you just have a couple of critical performance bottlenecks, and the rest of the program doesn't need the speed.
Statically typed languages like Crystal and C++ are harder to program in. A good 50% of the errors I get, in any compiled language, are type-related compilation errors. Ruby, on the other hand, is a dream to code in. Until you need the speed.
So, the best solution is to write 90% of your program dynamically, and the occasional high-performance bit statically.
As to implementation... I reckon it might be possible. Just off the top of my head, store the address of each static function in a lookup table, and use assembly language to jump there based on some condition.
Possibly you could annotate certain methods as "dynamic", and they wouldn't be statically-callable. That'd make the implementation easier, possibly.
This is a duplicate of #27
I agree with @lbguilherme here. In Crystal, for now, we are trying to build a language where dynamic aspects are disallowed. We are trying to see how far we can go this way, without having to fallback to an "any" type and trying to move some logic from runtime to compile-time with macros.
Ruby is a dream to code, I agree with that too. But it's until you need the speed, and while you are getting "undefined method 'x' for nil:NilClass" on production code. So speed isn't the only reason to disallow dynamic aspects, it's also type safety and ensuring code will work, and giving you confidence that refactors won't break existing stuff.
In the future we will probably support having a variable be of type Object, and it will be similar to a void*: you won't be able to do anything with it unless you cast it to the type you want. That would be similar to Go's interface{}, I guess.
Also, having an "Any" type means that classes and methods must be available at runtime and must be interpreted. That bloats the executable and makes us implement an interpreter, so it's basically a parallel language.
Finally, there are many programs out there that are built with static languages, not dynamic ones, so "every program ever created" is definitely not true.
If Ruby is a dream to code in and you need better perf use Rubinius or jRuby. I prefer to see errors during compilation than 2 weeks later on production which is 50% of the errors we get on a large Ruby codebase it's far from "a dream to code in"), errors that could have been caught if we were using a compiled lang like Crystal.
Type checking is a very useful thing to have and its benefit is not just speed but also programmer sanity evident in large codebases. Please don't add Any type to the language and please don't try to make Crystal more Ruby like (there are other issues about adding more dynamism to the language which I don't think is a good direction tbh).
The reason we're looking at Crystal is because it does things differently/better than Ruby and because it is type checked/compiled. Any type would encourage sloppy design, you start using it here because thinking about types seems too hard and quickly it spills into other areas, after a while anything can go anywhere and you start getting no method exceptions on production.
Remember, if it walks like a duck and quacks like a duck it'll throw exceptions at runtime :)
Most helpful comment
If Ruby is a dream to code in and you need better perf use Rubinius or jRuby. I prefer to see errors during compilation than 2 weeks later on production which is 50% of the errors we get on a large Ruby codebase it's far from "a dream to code in"), errors that could have been caught if we were using a compiled lang like Crystal.
Type checking is a very useful thing to have and its benefit is not just speed but also programmer sanity evident in large codebases. Please don't add Any type to the language and please don't try to make Crystal more Ruby like (there are other issues about adding more dynamism to the language which I don't think is a good direction tbh).
The reason we're looking at Crystal is because it does things differently/better than Ruby and because it is type checked/compiled. Any type would encourage sloppy design, you start using it here because thinking about types seems too hard and quickly it spills into other areas, after a while anything can go anywhere and you start getting no method exceptions on production.
Remember, if it walks like a duck and quacks like a duck it'll throw exceptions at runtime :)