We like the way Ruby lets you quickly prototype things, but its performance isn't very good (it's just good) and it also lacks static type checks (for example "undefined method '...' for Nil" is a very common runtime error).
So, we are trying to create a language with all the nice aspects of Ruby but with static checks and better performance. Of course that comes at a price: no dynamic aspects (no eval, no instance_eval, no methods or classes created at runtime, no methods redefined at runtime, etc.). But we try to compensate those with macros and compile-time reflection.
One thing that is definitely not one of our goals is to replace Ruby: every tool has its place.
People talk about how Crystal's performance is better because it's statically compiled and removes Ruby's dynamic features, but I'm not sure static compilation is the best way to achieve performance, and I don't think the dynamic features need to damage performance.
For example, JRuby+Truffle runs Crystal's own sample programs around twice as fast as Crystal does, without static compilation, and while still supporting all the metaprogramming and dynamic features of Ruby such as monkey patching, send, method_missing, set_trace_func, ObjectSpace etc.
Did you compile the Crystal program with the --release flag? That turns on optimizations. On our machines we see Crystal is faster in this benchmark, it always takes about 1.6s while JRuby+Truffle reaches 2.38 at most.
I don't see that option documented anywhere except the changelog, and one passing reference in the docs that says it sets the release flag, but neither say it has any effect on optimisation.
Right, but if you want the static checks for safety, then even if you run on something like Truffle, you will lose a lot of dynamic behavior. Either that or your static checks won't be able to check as much, and will give you weaker guarantees.
I recommend adding something about static type checking to the list at the top of Crystal's homepage. I saw "never have to specify the type of...", and believed it was another dynamically typed language.
I actually didn't know it had static type checking until I had closed the tab, and glanced at this comment you posted here. (I know, I didn't read very far in the linked page.)
I came across this a few months ago and ignored it for similar reasons: the homepage doesn't talk about the fact that nil is a type not a value (which is AWESOME, btw). It wasn't until a coworker encouraged me to dig into the docs that I realised Crystal is actually pretty sweet.
I recommend stating something like "No unexpected nils at runtime" and for those curious, a link for where to read more. Not having nil is basically the most important feature in most new languages I take the time to play with. Now that I know Crystal treats nil responsibly, I'm really keen to start playing with it.
Macros is something I really miss in Ruby. But static classes strikes me as a bit of a limitation. E.g. a Crystal REPL can't create classes if I understand it correctly.
The important thing is that it’s statically-typed. All languages are compiled nowadays, except Bash. Ruby, Python and the likes all use VMs, and the code you write is compiled in VM bytecode before being executed.
So, we are trying to create a language with all the nice aspects of Ruby but with static checks and better performance. Of course that comes at a price: no dynamic aspects (no eval, no instance_eval, no methods or classes created at runtime, no methods redefined at runtime, etc.). But we try to compensate those with macros and compile-time reflection.
One thing that is definitely not one of our goals is to replace Ruby: every tool has its place.