00:00:06.759
Hello everyone. I'm going to talk to you about the power of Crystal, which is a programming language that's intended for both humans and computers.
00:00:13.360
I’ll give a short introduction to what Crystal is, how it works, how it relates to Ruby, and how you can use both together to leverage the combined power of the two.
00:00:25.240
At the end, I'll share some learnings for Ruby developers. Even if you leave this talk and decide you never want to work with Crystal, you can still gain insights that will help you improve your Ruby development.
00:00:37.760
If you want to follow the slides, you can use this QR code. They'll be available later as well. At the bottom of the presentation, I have some links for installing Crystal or trying it out on an online playground.
00:00:50.800
This playground is essentially a full Crystal compiler that lets you run Crystal code directly in your web browser. So I'll leave this slide on for a moment if you want to copy something.
00:01:12.240
My name is Johannes Müller. When I first learned Ruby, it was the first time I really fell in love with a programming language. Ruby is great, and it was fun to work with. Later, I came into contact with Crystal and once again found a programming language that I loved.
00:01:28.439
Crystal builds upon Ruby and adds some extra features that I find incredibly attractive. When I first encountered Crystal, it was very young, and even though it still is, there were many things missing in the standard library. I started contributing to it and eventually joined the core team.
00:01:48.799
Currently, I work on Crystal full-time as the principal engineer at Manas, the company where Crystal was born. Manas is a software agency that develops software for international clients.
00:02:02.119
The team is international as well—I'm based in Germany, for example, while my colleagues are in Argentina, France, and the US. We use various technologies depending on our clients' needs and projects, but we particularly love Ruby, especially Ruby on Rails.
00:02:30.319
Ruby has fantastic properties, such as a user-friendly syntax, versatility, and high productivity. You can accomplish a lot with minimal effort, and its simplicity and intuitive nature are just a few of its strengths.
00:02:56.640
The greatness of Ruby stems from the creator's vision. A few years ago, a developer in Japan thought about what a truly great programming language would look like, and he realized this vision in Ruby.
00:03:11.039
Many people agreed with this vision. At Manas, there's a developer in Argentina named Ari Bensik who wondered what would happen if a really good programming language could be statically compiled. This brainstorming led to the creation of Crystal.
00:03:50.280
Initially, Ari experimented with Ruby syntax to make it statically compiled. He presented this to his colleagues, sparking further interest, which eventually evolved into a language, an ecosystem, and a community now beneficial to many.
00:04:01.680
In this way, Matz became the grandfather of Ruby, instilling the principle of creating good programming languages. Every programming language, including Ruby, has its downsides.
00:04:20.080
For instance, type checking in Ruby offers options like RBS, but these are added features rather than core functionalities, leading to some challenges in effective utilization.
00:04:34.720
Additionally, Ruby's performance has improved significantly with Ruby 3 and JIT compilation, but it still falls short compared to natively compiled optimized code for specific CPU architectures.
00:05:03.680
Also, Ruby requires a language runtime and various dependencies, making software distribution challenging. Concurrency in Ruby can be a cumbersome adventure, especially if anyone has attempted to create concurrent software without leveraging tools like Web Server Frontends.
00:05:39.279
Programming languages are always a compromise; they come with features and non-features. While you may attempt to include all features, this often doesn't work due to conflicts.
00:05:56.960
Ruby is a dynamic language with immense power but lacks some optimizations due to this. Crystal, on the other hand, maintains most good aspects of Ruby while shifting the feature set towards being more static.
00:06:24.560
While this loses some dynamic nature, it still feels dynamic. Crystal balances static typing with type inference, eliminating the need for excessive type annotations in most cases.
00:06:51.000
The result is clean code that's easy to read. Crystal compiles to highly efficient machine code and has a strong concurrency model, presenting a fresh approach compared to Ruby.
00:07:23.680
Crystal can be seen as a different dialect of Ruby, sharing familiar syntaxes but creating a more distinct language overall.
00:07:58.120
Many parts of the structure are almost identical. As a Ruby developer, you can leverage your existing Ruby knowledge when transitioning to Crystal.
00:08:30.320
Let’s look at some examples. Here’s a simple program that outputs a hello world message along with the language being executed.
00:08:48.640
This program works in both Crystal and Ruby, loaded with a bit of a trick to demonstrate that both languages share a common superset.
00:09:06.840
For instance, when executed in Ruby, it outputs 'Hello Ruby,' and in Crystal, it outputs 'Hello Crystal.' Another example is an HTTP server implementation.
00:09:26.760
This server comes with a crystal-centered library that is feature-rich and provides several useful tools out of the box.
00:09:47.360
This server is simple yet super efficient, capable of handling tens of thousands of requests per second seamlessly.
00:10:06.160
Let’s discuss static typing. Here’s a function that accepts two parameters and uses the plus operator on them.
00:10:34.600
The first call adds two numbers, while the second call concatenates two strings. Despite Crystal being statically typed, the compiler checks all expressions at compile time.
00:10:54.880
The type varies depending on how you call the method. The compiler can deduce the return type based on the parameters used during the method call.
00:11:14.800
If you attempt to add a number to a string, neither Crystal nor Ruby supports this operation, and the compiler promptly warns you.
00:11:48.480
Static typing in Crystal enhances error detection, as the compiler identifies potential issues before execution. This leads to greater assurance in program soundness.
00:12:12.840
In this way, static typing reduces common errors, such as method calls on unexpected types due to dynamic language behavior.
00:12:47.280
For example, an array in Crystal is more than just a single type; it can be initialized to hold specific types. The compiler understands that elements within the array must conform to its defined type.
00:13:12.680
In developing with Crystal, it's necessary to provide type information explicitly to clarify the intended usage.
00:13:36.720
While explicit types may not always be necessary, they act as documentation defining method interfaces, which aids in understanding the code.
00:14:01.680
Next, let's explore what compilation means. When you build a program in Crystal, you can use the 'crystal build' command, producing an executable file.
00:14:26.480
This file, while requiring an additional step, significantly enhances runtime efficiency. The resulting executable is dynamically linked to the current system libraries.
00:14:52.520
Dynamically linked programs may work across different machines, with preconditions around available libraries or dependencies like regular expressions.
00:15:21.280
Alternatively, statically linking an executable means that all required libraries are embedded, offering greater portability but at a larger file size.
00:15:46.960
Static linking affords the benefit of deploying programs without needing to manage dependencies, making server deployment easier.
00:16:12.320
Crystal employs LLVM, a compiler framework that produces highly efficient code. This optimization process ensures phenomenal runtime performance.
00:16:41.440
The compilation process requires all the code to be known at compile time, contrasting Ruby's dynamic nature where you can modify the program at runtime.
00:17:06.480
Crystal provides alternatives to dynamic programming through features like macros, which generate code at compile time, thus optimizing execution.
00:17:39.600
Macros serve as code generators that operate at compile time, offering functionality similar to template processing in languages like Ruby.
00:18:09.320
Additionally, Crystal supports hooks that activate during inheritance, mirroring some operations in Ruby, albeit using different mechanisms.
00:18:39.840
Crystal and Ruby share many similarities across APIs but differ in specifics, adjusting features like meta-programming for performance.
00:19:12.000
For the sake of simplicity, Crystal avoids offering multiple names for identical methods, which can lead to confusion among programmers.
00:19:40.440
As such, Crystal may provide only one naming convention—for example, 'size' instead of 'length.' This approach eases learning for newcomers.
00:20:01.240
Transitioning from Ruby to Crystal is manageable, and embedding the two languages together is facilitated by libraries like `Crystal Ruby`.
00:20:31.920
This gem allows Ruby applications to utilize Crystal code, compiling it into a dynamically linked library that can be accessed via FFI.
00:20:54.960
You can also embed a Ruby interpreter in a Crystal program, allowing type mappings between the two languages, offering flexibility in operations.
00:21:23.320
Additionally, performance-critical Ruby workloads can be optimized by implementing Crystal backends, like background job processing with libraries such as Sidekiq.
00:21:46.520
Now, let's summarize some learnings for Rubyists. Crystal prompts you to be more mindful of types in your code.
00:22:06.480
For instance, if a method returns either a string or nil, and another method accepts only a string, the Crystal compiler will highlight potential issues.
00:22:43.920
You should store the method return value in a local variable to ensure it remains stable throughout usage.
00:23:02.640
This approach enhances efficiency, preventing multiple calls and reinforcing code stability.
00:23:24.640
Ruby's tendency towards semi-structured hashes can be problematic in Crystal due to its static typing. The compiler favors explicit, structured types, making code cleaner.
00:23:49.440
For example, utilizing defined classes instead of generic hashes provides clear expectations and usage.
00:23:55.440
Structured types are more efficient to document and maintain than changing hashes, preventing confusion in code readability.
00:24:29.520
For learning resources, there are excellent materials available for Rubyists. Some concise guides and translation tables for Ruby gems to Crystal shards are particularly useful.
00:25:03.600
The Exorcism track is a great platform for deeper learning in Crystal, albeit potentially a bit lower-level for Rubyists.
00:25:41.440
In conclusion, I showed you how Crystal can enhance your toolkit and improve your Ruby projects. Using Crystal might be a good option if you need more performance.
00:26:02.560
Crystal and Ruby work harmoniously together, providing significant benefits to developers.
00:26:26.960
Thank you for listening. I also want to thank our sponsors, like 84codes, who are instrumental in the development of the language.
00:26:49.440
They’re currently assisting with improving multi-threading, alongside ongoing performance optimization in Crystal. We’ve been using it productively for some time now, and we're excited to enhance its capabilities.