Crystal. Think it is like Ruby? You are Wrong.
Crystal vs Ruby - GO!
I've been using Ruby professionally since one fated day in the California summer heat of 2005. Although the details have faded in my mind, I'm pretty sure I heard about Rails before Ruby - via the venerable Slashdot. I know it was sometime before Rails 0.13 was released on July 6, 2005 because I remember not having migrations for my first iteration of the app: I was tasked at the time with building an online scrapbooking app and I was looking for something that would be a good fit for a dynamic app like that. After seeing examples of the Ruby language, I fell in love with the alluring, almost gossamer, syntax.
You had me at
5.times do |i| puts i end
"Everything an object?" It just made sense to me. It clicked.
So when I came across a language touting a Ruby-like syntax but was compiled, and *GASP* fast, I held my breath. Things are rarely as good as the promote themselves to be. So with a healthy dose of skepticism I dove into writing some Crystal.
Crystal is "Fast as C, slick as Ruby". Crystal programming is a lot like Ruby in many ways but I want to point out some of idiosyncrasies of Crystal versus Ruby.
The Obvious: Speed
First up is the thing catches the ear of every Rubyist that gets wind of Crystal. "What? Ruby syntax AND it's fast you say?" Fast it is. Theres been lots of talk about Crystal's speed so I won't get too crazy here. If you are interested, Mike Perham has some insight on his blog. Also, Taichiro Suzuki (@tbrand) last week (2018-04-10) released the latest benchmarks for web servers and frameworks on his github repo which_is_the_fastest.
According to @tbrand, and as of today April 18th, 2018, a Crystal project
router_cr tops the list and Crystal projects make up 1/2 of the top 12.
- router_cr (crystal)
- iron (rust)
- raze (crystal)
- nickel (rust)
- japronto (python)
- actix (rust)
- spider-gazelle (crystal)
- fasthttprouter (go)
- mofuw (nim)
- lucky (crystal)
- amber (crystal)
- kemal (crystal)
Crystal is crazy fast. It's up there with the top languages.
In my own admittedly unscientific tests, I had similar findings (Gist). I had text output of PDF highlights that needed munging before importing into a data analysis tool. I wrote the first version in Ruby and realized it would be very easy to port it to Crystal and I was curious about the results.
# Ruby time ./fix-annotations.rb annotations.txt > annotations-fixed.txt ./fix-annotations.rb annotations.txt > annotations-fixed.txt 0.14s user 0.10s system 68% cpu 0.346 total
# Crystal time ./fix-annotations annotations.txt > annotations-fixed.txt ./fix-annotations annotations.txt > annotations-fixed.txt 0.00s user 0.00s system 55% cpu 0.013 total
As you can see, Crystal is zero-seconds-fast. 😝
Diving In: Crystal is written in Crystal
Crystal is written almost entirely in Crystal. They have some C still hanging around but it seems pretty insignificant. Contrast this with Ruby which is written in something like 64-65% Ruby and the rest in C.
Honestly I wouldn't have thought too much about this in the past. I cared a lot more about the language usage, rather than the implementation. But as I have gotten used to Crystal, I've found myself digging right into the implementation details of the language to find answers to my questions. I suppose if I was stronger with C this wouldn't stand out as a difference between the two, but for me it is. I've come to appreciate how nice it really is to get down to that level sometimes.
Surprises: Jewels in the Standard Library
Did you know Crystal has Levenshtein distance methods available in the standard library? Cool, huh? It also has Colorize for working with colored output in terminals. And OAuth2. And Markdown. Just thought that was cool to see those shipping with Crystal.
Coding Standards: One Way to Do It
This one might be controversial but Crystal has embraced the One Way to Do It philosophy. This isn't a bad thing though. And I'm not going all Python on you, either. Let me explain: For instance, in Crystal, Enumerable implements a single method to inspect the number of items in the collection,
:size. The method
:length is absent and
:count returns the count of the item in the collection. In Ruby I expect those three to work relatively similarly under most circumstances. But in Crystal, they've made a decision that feels more like optimization than limitation.
The Crystal community really cares about coding conventions. Check out the coding style pages for more details.
The Little Things: Attributes
I've noticed little differences between the languages like declaring attributes in a class.
:attr_accessor are fine and dandy. But in Crystal we've got
:property. It's different but I approve of the change.
A Beginning: Crystal's Journey
Crystal is still pre-1.0 and in its relative infancy compared to Ruby. Again, some view that lack of maturity as a negative, but I tend to look at the situation Crystal is in now, with a dearth of libraries and occasional bugs with the language itself, as an opportunity. You see, I have always felt like I missed a lot of opportunity to help move forward Ruby because I was too timid to open source any of my code. I've grown a lot since then. I realize the disadvantages of NOT putting myself out there. I've got plenty of code out in the open and had plenty of code reviews. The immaturity of Crystal gives me a chance to contribute in a way I felt I wasn't able to at the beginning of my Ruby journey.
Type System: Everybody Wants One
Yes, Crystal has a type system. I'll say no more for now.
In Summary: Crystal is not Ruby BUT-
Crystal stands apart from it's inspiration, Ruby, in several ways. In parting I want to point out one aspect of Crystal that it shares with Ruby. You read about Crystal's speed, type system, etc., but you may not realize that the Crystal community is amazing. Friendly and honestly helpful. If you are at all interested in working with Crystal, I hope you find these same things.
Matt Petty is a web software developer living outside of Kansas City, Missouri. He runs this here site and gets to say whatever he darn well pleases. Matt is a → Dev, Geek, Father, Artist, Writer, Freethinker, Linguaphile, Photog, Long-time Tabletop Role-Player and Dungeon Master.