Crystal – A Ruby-esque programing language
Crystal Clear
Crystal is an open source project that seeks to combine the best of two worlds: the simplicity of a language syntax similar to Ruby and the speed and capabilities of the LLVM platform.
In the fall of 2012, Argentinian Ary Borenszweig implemented his Crystal project [1] as a "programming language for people and computers." This sentence probably best expresses what this language sets out to combine: the simplicity and elegance of a Ruby-esque language syntax with the efficiency and speed benefits of compiled languages such as C.
The driving force behind the development of Crystal in recent years has been the Argentine software consulting company Manas [2], which is where Borenszweig works. As of this writing, some 100 volunteers are pushing forward with the project on GitHub [3]. You can look up all of the language's functions in a GitBook [4]. Newcomers can take their first steps without installing anything by entering code into a simple web-based Crystal editor and compiler [5].
Benchmark
The script in Figure 1 runs the Ruby code from Listing 1 as a simple benchmark. It includes a loop containing a multiplication. From the time measured at the start and end of the program, a simple subtraction gives you the execution time. Ruby 1.9.3 takes around six seconds, or around four seconds for JRuby. On the website [5], the same script takes only around 0.3 seconds (Figure 2).
Listing 1
Benchmark
§§nonumuber 01 time1 = Time.now 02 (0..100000000).each do |i| 03 i*16 04 end 05 time2 = Time.now - time1 06 puts time2.to_f
After installing Crystal on your computer (see the "Installation" box), you will find the crystal
command-line tool. To execute the Ruby script from Listing 1, all you need to do is enter:
Installation
Right now, Crystal is not found in the official repositories of major distributions.You can add the repository and install Crystal on your system, then install a number of additional libraries needed by Crystal at run time [6] as follows:
Debian and Ubuntu:
curl http://dist.crystal-lang.org/apt/ setup.sh | sudo bash sudo apt-get install crystal sudo apt-get install libbsd-dev libedit-dev libevent-core-2.0-5 \ libevent-dev libevent-extra-2.0-5 libevent-openssl-2.0-5 \ libevent-pthreads-2.0-5 libgc-dev libgmp-dev libgmpxx4ldbl \ libpcl1-dev libssl-dev libxml2-dev libyaml-dev libreadline-dev
Red Hat and CentOS:
curl http://dist.crystal-lang.org/rpm/setup.sh | sudo bash sudo yum install crystal sudo dnf -y install gc-devel gmp-devel libbsd-devel \ libedit-devel libevent-devel libxml2-devel libyaml-devel \ llvm-static openssl-devel pcl-devel pcllib-devel readline-devel
Some packages automatically resolve dependencies against other packages.
$ crystal bench1.rb
On the test system, the benchmark program only took 0.23 seconds to run the program code; thus, it ran 30 times faster than the plain vanilla Ruby version.
Crystal does not interpret the Ruby script; first, it compiles the script using the LLVM infrastructure (see the box "Victory for LLVM Compiler Infrastructures") to create native code. Crystal generates pure C code, which is strictly typecast – in contrast to Ruby code.
Victory for LLVM Compiler Infrastructures
At the University of Illinois, developers Vikram Adve and Chris Lattner, launched a study project in 2000 to implement a new compiler infrastructure. Their Low-Level Virtual Machine project (LLVM) [7] was intended to take all state-of-the-art principles for building compilers into account. In contrast to the legacy structure of the compiler, comprising a front end, optimizer, and back end, LLVM was created from the outset to fulfill the aim of developers to compile and optimize more than one language. For this reason, they created an internal version of the program code after the compilation process that is known as LLVM Intermediate Representation (IR).
The now very popular Clang compiler [8], which compiles C, C++, Objective C, and Objective C++, also stems from this project. With the help of Clang, LLVM generates executable code, not only on known desktop systems from the x86 processor family, but also on ARM systems, as used by most mobile devices.
A Ruby interpreter decides at program run time the variable type based on its situation. Dave Thomas, the author of the first language reference for Ruby [9], called this Duck Typing. The term goes back to the poem "Little Orphant Annie" by US poet James Whitcomb Riley, which says: "See a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck." In Listing 2, Ruby determines the type of variable a
at run time.
Listing 2
Ruby Type Determination
In contrast to Ruby, Crystal identifies the type of a
at compilation time. It comes as little surprise then that Listing 2 causes totally different error messages in Ruby and Crystal. Ruby runs the first puts
command (line 3) but refuses to add the string to an integer (Figure 3).
The Crystal compiler also stumbles across this problem, but – in contrast to Ruby – does not even run the program up to the line with the first puts
(Figure 4). Crystal not only detects the right types for simple literals such as nil
, false
, 1, 3.14159265, 'a'
, :crystal
, and "crystal"
but also correctly typecasts assignments such as a = 1
and function arguments.
As an example, Ruby's language syntax lets you define a simple subtraction function as follows:
def sub(a,b) a - b end
The application can use this function in different ways:
c = sub(2,1) c = sub(2.5,1.6)
Crystal also supports this argument typecasting through alternative functions (for Int32 on the one hand, and for Float64 on the other).
However, Crystal can do more. Using the build
command, it influences the production of code in multiple ways. For example, the call
$ crystal build --release bench1.cr
creates a size-optimized executable that can run without Crystal. The tool
option, on the other hand, displays the source code of a Crystal file, so the developer can troubleshoot it. The command
$ crystal tool types bench1.cr
shows the different variable types that Crystal assigns to the program during the compilation process.
Language Functionality
Crystal solves some problems differently from Ruby. Unions are an important language construct that makes the code more flexible with static typecasting. A call to
alias Int32OrString = Int32 | String
generates the type Int32OrString
, which can optionally be an integer or a string.
Another interesting case has Crystal using Procs, function pointers with optional contexts, to create anonymous functions of the following type:
a = ->(x : Int32, y : Int32) { x - y } a.call(42, 23) #=> 19
If you want to manage multiple processes in Crystal programs, you can resort to fiber and channel constructs, which are known from the Go and Erlang languages. Listing 3 shows a socket server that creates 10 processes to serve a corresponding number of clients.
Listing 3
Channel, Spawn
Integrating C libraries also makes sense. For example, you can use the declaration in Listing 4 to include the mathematical functions of the standard C library. Using the structs known from C, you can also implement declarations like the one in Listing 5.
Listing 4
Math with Libc
Listing 5
Structs
Speed Benefits
To evaluate the speed benefits that Crystal seems to have, you need applications that can do more than just optimize loops. Table 1 shows a speed comparison between Ruby, JRuby, and Crystal for the multiplication of two 100x100 matrixes [10].
Table 1
Computing 100 x 100 Matrixes
Language | Time (s) |
---|---|
Crystal |
0.005 |
Ruby |
0.136 |
JRuby |
3.874 |
|
5,207 |
To keep this comparison fair, the program simply measures the execution time; it does not include the time that Crystal requires for compilation. Two values were determined for JRuby: direct execution time and a Java class file, which was created with the JRuby compiler (jrubyc
), so it could run on the Java Virtual Machine. The results for computing a Fibonacci sequence are similar (Table 2).
Table 2
Fibonacci Sequence
Language | Time (s) |
---|---|
Crystal |
0.206 |
Ruby |
0.250 |
JRuby |
3.849 |
|
5,311 |
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Gnome 47.2 Now Available
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.
-
Latest Cinnamon Desktop Releases with a Bold New Look
Just in time for the holidays, the developer of the Cinnamon desktop has shipped a new release to help spice up your eggnog with new features and a new look.
-
Armbian 24.11 Released with Expanded Hardware Support
If you've been waiting for Armbian to support OrangePi 5 Max and Radxa ROCK 5B+, the wait is over.
-
SUSE Renames Several Products for Better Name Recognition
SUSE has been a very powerful player in the European market, but it knows it must branch out to gain serious traction. Will a name change do the trick?
-
ESET Discovers New Linux Malware
WolfsBane is an all-in-one malware that has hit the Linux operating system and includes a dropper, a launcher, and a backdoor.
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.