Home Programming Crystal Programming

Crystal Programming

By George Dietrich , Guilherme Bernal
books-svg-icon Book
eBook $41.99 $28.99
Print $51.99
Subscription $15.99 $10 p/m for three months
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
eBook $41.99 $28.99
Print $51.99
Subscription $15.99 $10 p/m for three months
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Chapter 1: An Introduction to Crystal
About this book
Crystal is a programming language with a concise and user-friendly syntax, along with a seamless system and a performant core, reaching C-like speed. This book will help you gain a deep understanding of the fundamental concepts of Crystal and show you how to apply them to create various types of applications. This book comes packed with step-by-step explanations of essential concepts and practical examples. You'll learn how to use Crystal’s features to create complex and organized projects relying on OOP and its most common design patterns. As you progress, you'll gain a solid understanding of both the basic and advanced features of Crystal. This will enable you to build any application, including command-line interface (CLI) programs and web applications using IOs, concurrency and C bindings, HTTP servers, and the JSON API. By the end of this programming book, you’ll be equipped with the skills you need to use Crystal programming for building and understanding any application you come across.
Publication date:
May 2022
Publisher
Packt
Pages
356
ISBN
9781801818674

 

Chapter 1: An Introduction to Crystal

Crystal is a safe, performant, general-purpose, and object-oriented language. It was heavily inspired by Ruby's syntax and Go's and Erlang's runtimes, enabling a programmer to be very productive and expressive while creating programs that run efficiently on modern computers.

Crystal has a robust type system and can compile to native programs. Consequently, most programming errors and mistakes can be identified at compile time, giving you, among other things, null safety. Having types doesn't mean you have to write them everywhere, however. Crystal relies on its unique type interference system to identify the types of almost every variable in the program. Rare are the situations where the programmer has to write an explicit type somewhere. But when you do, union types, generics, and metaprogramming help a lot.

Metaprogramming is a technique where a structured view of the written program is accessed and modified by the program itself, producing new code. This is a place where Ruby shines with all its dynamism and built-in reflection model, and so does Crystal, in its own way. Crystal is capable of modifying and generating code during compilation time with macros and a zero-cost static reflection model. It feels like a dynamic language in every way, but it will compile the program down to pure and fast machine code.

Code written in Crystal is expressive and safe, but it's also fast – really fast. Once built, it goes head to head with other low-level languages such as C, C++, or Rust. It beats pretty much any dynamic language and some compiled languages too. Although Crystal is a high-level language, it can consume C libraries with no overhead, the lingua franca of system programming.

You can use Crystal today. After 10 years of intense development and testing, a stable and production-ready version was released in early 2021. Alongside it, a complete set of libraries (called "shards") are available, including web frameworks, database drivers, data formats, network protocols, and machine learning.

This chapter will introduce a brief history of the Crystal language and present some of its characteristics regarding performance and expressiveness. After that, it will bring you up to speed by explaining how to create and run your first Crystal program. Finally, you will learn about some of the challenges for the future of the language.

In particular, we will cover the following topics:

  • A bit of history
  • Exploring Crystal's expressiveness
  • Crystal programs are also FAST
  • Creating our first program
  • Setting up the environment

This should get you started on what Crystal is, understanding why it should be used, and learning how to execute your first program. This context is essential for learning how to program in Crystal, going from small snippets to fully functional and production-ready applications.

 

Technical requirements

As part of this chapter, you will install the Crystal compiler on your machine and write some code with it. For this, you will need the following:

  • A Linux, Mac, or Windows computer. In the case of a Windows computer, the Windows Subsystem for Linux (WSL) needs to be enabled.
  • A text editor such as Visual Studio Code or Sublime Text. Any will do, but these two have good Crystal plugins ready to use.

You can fetch all source code used in this chapter from the book's GitHub repository at https://github.com/PacktPublishing/Crystal-Programming/tree/main/Chapter01.

 

A bit of history

Crystal was created in mid 2011 at Manas Technology Solutions (https://manas.tech/), an Argentinian consulting company that worked a lot with creating Ruby on the Rails applications at that time. Ruby is an enjoyable language to work with but has always been questioned for its lacking performance. Crystal came to life when Ary Borenszweig, Brian Cardiff, and Juan Wajnerman started experimenting with the concept of a new language similar to Ruby. It would be a statically typed, safe, and compiled language with pretty much the same elegant syntax as Ruby but taking advantage of global type inference to remove runtime dynamism. Much has changed since then, but these core concepts remain the same.

The result? Today, Crystal is a stable and production-ready, 10-year-old language with over 500 contributors and a growing community. The team behind it successfully implemented a language with a fast concurrent runtime and a unique type inference system that looks at the entire program in one go while retaining Ruby's best features.

The initial motiving factor for the creators was performance. They enjoyed programming in Ruby and using Ruby's vast ecosystem, but the performance wasn't there. Ruby has improved a lot since then, but even today, there is a sensible gap compared to other dynamic languages such as Python or JavaScript.

It began with a simple idea – what if we could have the same expressiveness as Ruby, infer the types of all variables and arguments based on the call sites, and then generate native machine code similar to the C language? They began prototyping it as a side project in 2011, and it worked. Early on, it was adopted as a Manas project, allowing the trio to work on it during paid hours.

Crystal has been developed in the open since its very beginning in a public repository on GitHub at https://github.com/crystal-lang/crystal. It brought a community of users, contributors, and also sponsors banking on Crystal's success. The initial interest came from the Ruby community, but it quickly expanded beyond that. You can see in the following figure the growth in people interested in Crystal, measured by the number of GitHub "stars" on the main repository.

Figure 1.1 – The steady growth of GitHub stars

Figure 1.1 – The steady growth of GitHub stars

At the time of writing, the latest version is 1.2.2, and it can be installed from Crystal's official website, at https://crystal-lang.org/.

Much inspiration came from Ruby, but Crystal evolved into a different language. It kept the best pieces of Ruby but changed, improved, and removed some of its legacies. Neither language aim to be compatible with the other.

Understanding this history gives you the perspective to follow what motivated Crystal to be created and to evolve into what it is today. Crystal has grown to be very performant but also very expressive. Now, let's see what empowers this expressiveness.

 

Exploring Crystal's expressiveness

It is often said that Crystal is a language for humans and computers. This is because Crystal strives for a balance of being a surprisingly enjoyable language for programmers while also being very performant for machines. One cannot go without the other, and in Crystal, most abstractions come with no performance penalties. It has features and idioms such as the following:

  • Object-oriented programming: Everything is an object. Even classes themselves are objects, that is, instances of the Class. Primitive types are objects and have methods, too, and every class can be reopened and extended as needed. In addition, Crystal has inheritance, method/operator overloading, modules, and generics.
  • Static-typed: All variables have a known type at compile time. Most of them are deduced by the compiler and not explicitly written by the programmer. This means the compiler can catch errors such as calling methods that are not defined or trying to use a value that could be null (or nil in Crystal) at that time. Variables can be a combination of multiple types, enabling the programmer to write dynamic-looking code.
  • Blocks: Whenever you call a method on an object, you can pass in a block of code. This block can then be called from the method's implementation with the yield keyword. This idiom allows all sorts of iterations and control flow manipulation and is widespread among Ruby developers. Crystal also has closures, which can be used when blocks don't fit.
  • Garbage collection: Objects are stored in a heap, and their memory is automatically reclaimed when they are no longer in use. There are also objects created from a struct, allocated in the stack frame of the currently executing method, and they cease to exist as soon as the method finishes. Thus, the programmer doesn't have to deal with manual memory management.
  • Metaprogramming: Although Crystal isn't a dynamic language, it can frequently behave as if it were, due to its powerful compile-time metaprogramming. The programmer can use macros and annotations, together with information about all existing types (static reflection) to generate or mutate code. This enables many dynamic-looking idioms and patterns.
  • Concurrent programming: A Crystal program can spawn new fibers (lightweight threads) to execute blocking code, coordinating with channels. Asynchronous programming becomes easy to reason and follow. This model was heavily inspired by Go and other concurrent languages such as Erlang.
  • Cross-platform: Programs created with Crystal can run on Linux, macOS, and FreeBSD, targeting x86 or ARM (both 32-bit and 64-bit). This includes the new Apple Silicon chips. Support for Windows is experimental, it isn't ready just yet. The compiler can also produce small static binaries on each platform without dependencies for ease of distribution.
  • Runtime safety: Crystal is a safe language – this means there are no undefined behaviors and hidden crashes such as accessing an array outside its bounds, accessing properties on null, or accessing objects after they have already been freed. Instead, these become either runtime exceptions, compile-time errors, or can't happen due to runtime protections. The programmer has the option of weaving safety by using explicitly unsafe features of the language when necessary.
  • Low-level programming: Although Crystal is safe, using unsafe features is always an option. Things such as working with raw pointers, calling into native C libraries, or even using assembly directly are available to the brave. Many common C libraries have safe wrappers around them ready to use, allowing them to use their features from a Crystal program.

At first glance, Crystal is very similar to Ruby, and many syntactic primitives are the same. But Crystal took its own road, taking inspiration from many other modern languages such as Go, Rust, Julia, Elixir, Erlang, C#, Swift, and Python. As a result, it keeps most of the good parts of Ruby's slick syntax while providing changes to core aspects, such as metaprogramming and concurrency.

 

Crystal programs are also FAST

From its very start, Crystal was designed to be fast. It follows the same principles as other fast languages such as C. The compiler can analyze the source code to know every variable's exact type and memory layout before execution. Then, it can produce a fast and optimized native executable without having to guess anything during runtime. This process is commonly known as ahead-of-time compilation.

Crystal's compiler is built upon LLVM, the same compiler infrastructure that powers Rust, Clang, and Apple's Swift. As a result, Crystal benefits from the same level of optimizations available to these languages, making it well suited for computationally intensive applications such as machine learning, image processing, or data crushing.

But not all applications are CPU-bound. Most of the time, there are other resources at stake, such as network communications or a local disk. Those are collectively known as I/O. Crystal has a concurrency model similar to Go's goroutines or Erlang's processes, where multiple operations can be performed behind an event loop without blocking the process or delegating too much work to the operating system. This model is ideal for applications such as web services or file manipulation tools.

Using an efficient language such as Crystal will help you reduce hardware costs and improve perceived responsiveness from your users. In addition, it means you can run smaller and fewer instances of your application to address the same processing volume.

Let's take a look at a simple implementation of the selection sort algorithm written in Crystal:

def selection_sort(arr)
  # For each element index...
  arr.each_index do |i|
    # Find the smallest element after it
    min = (i...arr.size).min_by { |j| arr[j] }
    # Swap positions with the smallest element
    arr[i], arr[min] = arr[min], arr[i]
  end
end
# Produce a reversed list of 30k elements
list = (1..30000).to_a.reverse
# Sort it and then print its head and tail
selection_sort(list)
p list[0...10]
p list[-10..-1]

This example already shows some neat things about Crystal:

  • First of all, it is relatively small. The main algorithm has a total of four lines.
  • It's expressive. You can iterate over lists with specialized blocks or use ranges.
  • There isn't a single type notation. Instead, the compiler deduces every type, including the method argument.

Surprisingly, this same code is also valid in Ruby. Taking advantage of that, if we take this file and run it as ruby selection_sort.cr (note that Ruby doesn't care about file extensions), it will take about 30 seconds to finish. On the other hand, executing this program after it has been compiled with Crystal in optimized mode takes about 0.45 seconds, 60x less. Of course, this difference isn't the same for any program. It varies depending on what kind of workload you are dealing with. It's also important to note that Crystal takes time to analyze, compile, optionally optimize and produce a native executable.

The following graph shows a comparison of this selection sort algorithm written for a variety of languages. Here, you can see that Crystal competes near the top, losing to C and coming very close to Go. It is important to note that Crystal is a safe language: it has full exception handling support, it tracks bounds on arrays to avoid unsafe access, and it checks for overflow on integer math operations. C, on the other hand, is an unsafe language and won't check any of that. Having safety comes at a slight performance cost, but Crystal remains very competitive despite that:

Figure 1.2 – A comparison of a simple selection sort implementation among different languages

Figure 1.2 – A comparison of a simple selection sort implementation among different languages

Note

Comparing different languages and runtimes in a synthetic benchmark such as this isn't representative of real-world performance. Proper performance comparisons require a problem more realistic than selection sort and a broad coding review from experts on each language. Still, different problems might have very different performance characteristics. So, consider benchmarking for your use case. As a reference for a comprehensive benchmark, consider looking into the TechEmpower Web Framework Benchmarks (https://www.techempower.com/benchmarks).

A web server comparison

Crystal isn't only great for doing computation on small cases but also performs well on larger applications such as web services. The language includes a rich standard library with a bit of everything, and you will learn about some of its components in Chapter 4, Exploring Crystal via Writing a Command-Line Interface. For example, you can build a simple HTTP server, such as this:

require "http/server"
server = HTTP::Server.new do |context|
  context.response.content_type = "text/plain"
  context.response.print "Hello world, got #{context
    .request.path}!"
end
puts "Listening on http://127.0.0.1:8080"
server.listen(8080)

The first line, require "http/server", imports a dependency from the standard library, which becomes available as HTTP::Server. It then creates the server with some code to handle each request and starts it on port 8080. This is a simple example, so it has no routing.

Let's compare this against some other languages to see how well it performs. But, again, this isn't a complex real-world scenario, just a quick comparative benchmark:

Figure 1.3 – A comparison of the request per second rate of simple HTTP servers among different languages

Figure 1.3 – A comparison of the request per second rate of simple HTTP servers among different languages

Here we see that Crystal is well ahead of many other popular languages (very close to Rust and Go) while also being very high-level and developer-friendly to code. Many languages achieve performance by using low level code, but it doesn't have to cost expressiveness or expose abstractions. Crystal code is simple to read and evolve. The same trend happens in other kinds of applications as well, not only web servers or microbenchmarks.

Now, let's get hands-on with using Crystal.

 

Setting up the environment

Let's prepare ourselves to create and run Crystal applications, which we will begin in the Creating our first program section. For this, the two most important things you will need are a text editor and the Crystal compiler:

  • Text editor: Any code editor will get the job done, but using one with good plugins for Crystal will make life much easier. Visual Studio Code or Sublime Text are recommended. You can find more details about the editor setup in Appendix A.
  • Crystal compiler: Please follow the installation instructions on Crystal's website at https://crystal-lang.org/install/.

After installing a text editor and the compiler, you should have a working Crystal installation! Let's check it: open up your terminal and type the following: crystal eval "puts 1 + 1":

s

Figure 1.4 – Evaluating 1 + 1 using Crystal

Figure 1.4 – Evaluating 1 + 1 using Crystal

This command will compile and execute the puts 1 + 1 Crystal code, which writes the result of this computation back to the console. If you see 2 then all is set and we can move forward to writing actual Crystal code.

 

Creating our first program

Now let's experiment with creating our first program using Crystal. This is the basis for how you will write and execute code for the remainder of this book. Here is our first example:

who = "World"
puts "Hello, " + who + "!"

After that, perform the following steps:

  1. Save this on a file called hello.cr.
  2. Run it with crystal run hello.cr on your terminal. Note the output.
  3. Try changing the who variable to something else and running again.

There is no boilerplate code such as creating a static class or a "main" function. There is also no need to import anything from the standard library for this basic example. Instead, you can just start coding right away! This is good for quick scripting but also makes applications simpler.

Note that the who variable doesn't need to be declared, defined, or have an explicit type. This is all deduced for you.

Calling a method in Crystal doesn't require parentheses. You can see puts there; it's just a method call and could have been written as puts("Hello, " + who + "!").

String concatenation can be done with the + operator. It's just a method defined on strings, and you'll learn how to define your own in later chapters.

Let's try something else, by reading a name inputted by the user:

def get_name
  print "What's your name? "
  read_line
end
puts "Hello, " + get_name + "!"

After that, we'll do this:

  1. Save the above code on a file called "hello_name.cr".
  2. Run it with crystal run hello_name.cr on your terminal.
  3. It will ask you for your name; type it and press Enter.
  4. Now, run it again and type a different name. Note the output changing.

In this example, you created a get_name method that interacts with the user to obtain a name. This method calls two other methods, print and read_line. Note that as calling a method doesn't require parentheses, a method call without arguments looks precisely like a variable. That's fine. Also, a method always returns its last expression. In this case, the result of get_name is the result of read_line.

This is still simple, but will get you started on writing more complex code later on. Here, you can already see some console interaction and the use of methods for code reusability. Next let's see how you can make a native executable out of this code.

Creating an executable

When you need to ship your application, either to your end user's computer or to a production server, it isn't ideal to send the source code directly. Instead a better approach is to compile the code down to a native binary executable. Those are more performant, hard to reverse-engineer, and simpler to use.

So far, you have been using crystal run hello.cr to execute your programs. But Crystal has a compiler, and it should also produce native executables. This is possible with another command; try crystal build hello.cr.

As you will see, this won't run your code. Instead, it will create a "hello" file (without an extension), which is a truly native executable for your computer. You can run this executable with ./hello.

In fact, crystal run hello.cr works mostly as a shorthand for crystal build hello.cr && ./hello.

You can also use crystal build --release hello.cr to produce an optimized executable. This will take longer, but will apply several code transformations to make your program run faster. For more details on how to deploy a final version of your application, take a look at Appendix B, The Future of Crystal.

 

Summary

Crystal delivers very well on performance, stability, and usability. It is a complete language with a growing community and ecosystem that can be used in production today. Crystal is highly innovative and has all the components of a successful programming language.

Knowing how to create and run Crystal programs will be fundamental in the following chapters, as there will be many code examples for you to try.

Now that you know about Crystal's origins and the significant characteristics of the language (namely its expressiveness and performance), let's move forward to learn the basics of programming in Crystal and get you started and productive in the language.

About the Authors
  • George Dietrich

    George Dietrich is a software engineer, open-source aficionado, and Crystal community moderator. He holds a Master of Science degree in internet information systems and a Bachelor of Science degree in information sciences.

    Browse publications by this author
  • Guilherme Bernal

    Guilherme Bernal is the chief technology officer at Cubos Tecnologia. He holds a bachelor's degree in TI management. Guilherme co-founded a software development company and several tech start-ups, including one that focused on teaching programming skills to a new generation of developers. He is also a two-time world finalist in the coding competition, ACM ICPC.

    Browse publications by this author
Latest Reviews (2 reviews total)
The book is great, and Crystal is an awesome programming language. Main complaint is that the e-book doesn't have color images, which needs to be acquired from an external link, however said link returns "access denied" and doesn't let me access it. Not a huge issue as the code examples are available externally, but it's a shame the digital experience can't be a bit nicer. Still highly recommended to anyone interested in Crystal. UPDATE: The support team has resolved the issue and provided me with a working link to the color images, the rating has been updated to reflect this.
はじめての本格的なCrystal言語の技術書として、この本が出版された事自体ですでに価値がある。
Crystal Programming
Unlock this book and the full library FREE for 7 days
Start now