Hacker News new | ask | show | jobs
by zeeone 4033 days ago
Just curious, why Crystal? It looks just like Ruby. What problem(s) are you addressing with Crystal?
2 comments

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.

https://gist.github.com/chrisseaton/91c7cbf8f6f4f6ea44bb

However Crystal does start faster, and I'm sure it has lower overhead.

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.
No, I didn't, sorry!

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.

Yeah, we need to document this better, sorry!
Get used to this, watching people run benchmarks after having forgotten to compile with optimizations is basically a meme in the Rust community. :)
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.)

That aside, it looks neat! :)

You are right, it's far from obvious after reading that list. I updated it. Thanks!
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.
It's a compiled language.
A statically-typed compiled language.
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.