Crystal – Lets Call it Ruby Plus Plus

In the world of thousands of languages, added one more to the list is Crystal, which is General Purpose Object Oriented Programming language. It is a compiled language, and compiles to an ultra optimized native code using Low Level Virtual Machine or LLVM as the backend.

But what’s so special about it you ask?

Well, if you have heard about Ruby, and how every person who has used it, loves the language. Crystal looks almost like Ruby, but it goes one step further and fixes its shortcomings, some of which are:

Concurrency

Speed

Though a Statically Typed language, we don’t always have to specify the Type of a variable, Crystal infers the type from the data assigned. More about this below.

Oh, and did I tell you, its a compiled language. Crystal code compiles to effective native code, which helps it with the Speed part.

Also, Crystal allows you to use C libraries, without writing a single line of C code. Cool, isn’t it!!

Now, lets jump in to the necessary things, The Hello World program.

# The customary Hello World program
puts "Hello World!"

Yup, thats it. And this is how you run a program. You first compile it using:

crystal build hello.cr

Which gives you a binary named hello, and, then you just run it, which prints ‘Hello World’ on the terminal:

○ → ./helloHello World!

That looked pretty easy, and the syntax is eerily similar to Ruby, which is certainly not a bad thing :).

Now that out of the way, lets do something meaningful. How about writing an HTTP Server in Crystal? Well, had it been Java, I wouldn’t dare jump to writing an HTTP server after a Hello World program.

But with Crystal, its really simple. It provides an http library out of the box, using which you can create an HTTP Server in minutes. Here’s the code:

Type Inference

The above will work, even though Crystal being a Statically Typed language. The compiler will infer the type of the variable by checking what value is assigned to it in all the usages of User, but this does make the code a bit non-performant, as some compiler optimizations cannot be applied.

When types for variables are not defined, Crystal has some rules that it applies, and tries to guess the kind of variable, according to how the variable is being used. If it has been assigned multiple values, Crystal maintains a Set of Types, that the variable can be of. If a variable is not being initialized in the constructor, it adds the Nil Type to the Set as well.

In the above example, @role would be inferred as String | Nil : String, because customer was assigned to it & Nil as the constructor didn’t initialize @role

Concurrency

Crystal uses fibers to achieve concurrency, which communicate with each other using Channels like in Go. Fiber is like an Operating System Thread, but ultra lightweight. A program can spawn multiple fibers and Crystal with execute them.

Channels, which are based on Communicating Sequential Processes are used. They allow communication between fibers without sharing any memory or worrying about locks.

You create a Fiber using the spawn keyword, which work in the background.

Lets create a concurrent Hello World program which uses Channels and Fibers:

This won’t do much though, just print Hello Concurrent World!! 10 times. The spawn block creates a background Fiber. The Channel.new creates a channel, which is a medium between the sender & receiver to communicate with each other.

In the above code, we are sending a message to our channel inside spawn using channel.send, and receive it back with channel.receive.

Crystal supports Concurrency, as well as Parallelism.

Speed

So, lets compare, how fast Crystal really is compared to Ruby and say Java. Lets run the Base64 benchmark for all of them.

Its a simple benchmark, which tries to encode & decode a huge string 100 times using the Base64 algorithm. You can find the code used for each language here.

If you check the benchmarks in the above URL, you will see, that Crystal is faster than both Java and Ruby in all cases.

Finally

So, we can clearly see that Crystal has potential, its got the speed of Lower level languages and syntactic sugar of Higher level languages. Its yet to release a production ready Version 1.0, the latest version released being 0.21.0.