00:00:13.519
Thank you, everyone. It's a real honor to be back here again. This is such a great conference! If there's anything you want to talk to me about, you can reach me on Twitter. My website is also available for reference. I’m currently working at a company called Situs Data, which provides a Postgres extension that manages sharding. This allows you to have very regular tables. You can specify which tables you want to shard across several machines, enabling you to handle a large volume of data. It's pretty cool! So if you use Postgres and anticipate having a lot of data, come talk to me! If you don't use Postgres, that's okay too.
00:00:59.250
This talk is going to be divided into a couple of different parts. The first part will cover what the Crystal programming language is and why I'm excited about it. Then, in the last part, I'll provide some examples to illustrate how Crystal is similar to and different from Ruby. Last week, the Crystal team released a new feature where you can type 'crystal play' at the command line, which opens a browser window where you can interactively execute code. I thought this was really cool, so I worked on it with the help of one of the members of the Crystal core team.
00:01:10.650
It's not released yet, but in the next version of Crystal, it will function like a workbook. You will be able to have sample code snippets that accompany your library. So, I adjusted my talk to utilize that feature instead. The good news is that I think it’s going to be more engaging to see the code actually run. However, it does involve a lot of code, which can get dull. I also struggled to find a way to include pictures, so instead of visuals, I decided to share one of my favorite Norm Macdonald jokes to lighten the mood.
00:01:36.600
The joke goes like this: A frog walks into a bank and asks the teller for a loan. The teller is skeptical, saying, "You're a frog!" The frog responds, "I get that a lot, but can you help me?" The teller tells him that the loan manager is Patricia Whack. The frog waits until Patricia opens her door and invites him into her office. She then states, "This is quite irregular; we usually only give loans to humans." The frog insists that he needs a loan, so Patricia collects some information from him. She asks for his name, and the frog says, "My name is Kermit Jagger, my father was Mick Jagger, and my mother is a frog." Patricia, confused, realizes he is not Kermit the Frog. As they continue, the frog explains he simply needs a larger lily pad for his family. Patricia asks for collateral, and he offers her a small carving of an elephant. She takes it to the loan manager, who looks at it and says, "Oh, I see! It's a knick-knack, Patty Whack, give the frog a loan — his old man's a rolling stone!"
00:04:21.670
Now, completely shifting gears, let's talk about the Crystal programming language. Crystal is a language that is unabashedly Ruby-inspired. The syntax, the idioms, everything is quite similar to Ruby, but it's completely compiled. There is no virtual machine running the code at runtime. Instead, it's built on top of LLVM, which has become a remarkable project in recent years, thanks to the efforts of companies like Apple and Google.
00:04:51.590
LLVM generates incredibly optimized machine code, which is impressive. There aren't many contributors to the entire Crystal project; I have contributed around 80 commits, but I’m one of the more significant contributors. This is possible because the top contributors are incredibly proficient and prolific, especially the main creator. Also, because LLVM handles all the optimizations, we can achieve highly efficient programs.
00:05:11.270
Crystal acts more like a front-end to LLVM. I believe that in the next ten years, languages will evolve significantly. The past decade, dynamic languages like Ruby have seen phenomenal growth, but as computers become faster and more powerful, one would expect to see dynamic languages achieve greater performance. Instead, it seems that the compile time in compiled languages is decreasing, which leads me to think that languages built on LLVM will dominate in the coming years.
00:05:36.300
Crystal has several key differences from Ruby. For instance, it uses static method dispatch, meaning it knows everything about the program at compile time. However, you still maintain a lot of the nice features found in Ruby, like the ability to create programmatic getters and setters and macros. Crystal is statically typed, and even though I'm not a language expert, it has a fantastic type system that offers a seamless experience. You rarely have to specify types; the language figures it all out for you.
00:06:03.900
Automatic unions of types are part of the language too, which I'll demonstrate through examples. Moreover, linking against C libraries is straightforward, making it easy to have a robust ecosystem. Crystal also excels in performance, and while micro-benchmarking should be approached with caution, it's worth noting that a Crystal program can outperform a corresponding Ruby program significantly.
00:06:23.760
For example, when running a Crystal program, which is a Sinatra clone, we see it operates an order of magnitude faster, with less latency and lower memory consumption, compared to regular Sinatra running on Puma. While micro-benchmarks can vary greatly, they showcase the incredible potential of Crystal.
00:06:35.820
The language has been evolving over the past few years, achieving self-hosted status early on. This means that the compiler, standard library, and everything else is written in Crystal itself, making it easy to contribute to the project. For comparison, Rubinius is mostly written in Ruby, whereas everything in Crystal is Crystal.
00:06:50.080
Now, I’m going to show you some code examples. I had to compile a custom version since it’s not quite released yet, but I hope it works as expected. When you run the custom version, a browser interface opens where you can interact. All the code samples are available, but you can't use them until the next release, which I believe is coming very soon.
00:07:11.369
To follow the theme of my talk, I’ve included a couple of carpentry jokes as well. Here’s one: I never really wanted to be remembered as stealing from my job as a road worker, but when I got home, all the signs were there! Now let’s look at the similarities between Ruby and Crystal. Of course, ranges are the same in both languages. For example, if you want to do a 'puts', you can put 'puts with inspect' to turn it into an array. You can also chain methods, use blocks, lambdas, and closures — all functionalities that work identically in both.
00:07:32.520
The foundation of object-oriented programming remains consistent as well. In Crystal, classes are open, which means that any last definition of a class will override previous ones, quite similar to Ruby. Instance variables act in the same manner, promoting flexibility in code design. The standard library is also written in Crystal, and programmers can modify parts of it without incurring any performance penalties. For instance, if I want to reopen a string and add my own size method, I can do it as if I were working with Ruby.
00:07:56.610
Equally important are modules and mix-ins. The inclusion of common elements is handled similarly with 'include' and 'extend' keywords. Notably, idioms around naming conventions, such as question marks for boolean methods, as well as the optional parentheses for calls, remain intuitive and consistent.
00:08:23.170
This creates familiarity for Ruby developers transitioning to Crystal, as they can apply their existing knowledge and experiences to solve problems effectively in this new language. Learning syntax or properties of a new language isn’t terribly difficult, but to truly be proficient and confident can take years of practice.
00:08:35.600
That said, it's worth noting that the spec framework is included in the standard library, offering an interesting twist. Speaking of twists, consider this humorous anecdote: construction workers have to be careful — when they raise the roof, they could end up in an unexpected situation!
00:08:47.660
Now, you might be wondering whether Crystal is fundamentally the same as Ruby. What are the differences? One notable difference lies in syntax when assigning arguments to instance variables, to reduce boilerplate code. In Crystal, you can place the '@' sign right next to the name, which simplifies the process.
00:09:01.500
Additionally, instead of using 'attr_accessor', Crystal uses 'property'. While this may seem like a small difference, Crystal allows various ways to gather type information about classes, leading to streamlined implementations. For instance, we can explore class attributes using built-in inspection tools.
00:09:19.530
My favorite feature in Crystal, which is a subtle one that brings added value, is the ability to use the 'to_proc' method, which is represented by a period instead of a dot, making it easier to chain methods together. This affords more elegant and powerful functionality than is typically possible in Ruby.
00:09:36.110
The principal distinction, however, lies within the type system. For example, if we define a method that takes parameters and handles different types of inputs, we can see how the method distinguishes between them. For instance, the return type changes depending on the input type due to the compile-time type system in Crystal.
00:09:59.790
If we pass an integer, the type is an Int32, and if we pass a string, it returns a string. What’s happening behind the scenes is the creation of multiple method copies based on the argument types, which facilitates structured handling of various input cases.
00:10:17.700
Crystal also supports Union types for methods that might return different outcomes. In this case, a method could return an Int32 when the input is high enough but return a string if the input is low enough. This means you can track the running type at any time, ensuring robust compatibility and validation.
00:10:37.300
Despite this efficiency, situations may arise where handling union types causes issues. When methods downstream require compatibility with all union type members, it might lead to compile-time errors if incompatible methods are invoked. This is a true distinction that's clear in Crystal's type system.
00:10:56.930
For example, if we try to add a string and an integer, it results in a compile-time error because there's no defined method that recognizes plus for both types. Thus, this compile system prevents pitfalls commonly encountered in dynamically typed languages.
00:11:08.160
When we encounter these issues, we can write conditional checks to ensure we only evaluate specific code if the relevant parameters are present. If we are certain about types, we could pursue explicit type casting, but we have to be cautious since any oversight could bring runtime errors.
00:11:23.630
What persists through this is that type inference allows capabilities without substantial type annotations throughout the codebase. The language compiles quickly and you're not bogged down by typing constraints unless you choose to specify them.
00:11:41.120
This is exemplified with method overloading — the definition can accept varied argument types, allowing for clean method management. Whenever writing methods that handle similar logic, specifying types ensures the right execution at runtime.
00:12:06.130
Another interesting feature is leveraging interfaces. If an abstract class method isn't implemented where it's required, an immediate compilation error guarantees that you address the shortcoming. Crystal’s compile-time guarantees prompt structured programming patterns.
00:12:19.230
When dealing with arrays and containers, defining type specificity can sometimes impose constraints. For instance, if you attempt to reverse the placement of elements in an array, the error can emerge due to mismatched types. Crystal alleviates this with tuple support, which maintains strict conformity to expected type orders.
00:12:36.290
Tuples present a firm way to enforce structure. If we misplace items in positional definitions, the system throws an error, ensuring appropriate handling and strong typings throughout the code.
00:12:55.750
Conversely, instantiating empty arrays can necessitate explicit specifications — a constraint not typical for dynamically typed languages. Users of Crystal must specify the type while declaring arrays to match the rigorous nature of the compiler.
00:13:09.230
Reflecting on my experience with Crystal, I quickly embraced the seamless integration of operations such as linking against C code. Building a Postgres driver was a straightforward experience, illustrating how direct operations can be executed with minimal boilerplate compared to languages like Ruby.
00:13:20.095
When linking against systems like LibPQ, the coded requirements were succinct, enabling direct connections to running Postgres instances, accompanied by ease in executing queries. This efficiency was among the first things that left a strong impression on me regarding Crystal.
00:13:33.450
Exploring various facets of performance profiling reveals that numerous existing Linux tools function seamlessly with Crystal applications. Developers can leverage tools they might already be familiar with, eliminating the burden of additional instrumentation processes.
00:13:44.590
Working with standard profiling tools provides clarity into program execution down to the assembly level. In projects where performance is pivotal, the ability to monitor where time is spent helps optimize critical areas effectively.
00:14:01.920
With the construction jokes, I was initially worried about messing those up, but I feel like I’m nailing it! Let’s shift into some unique characteristics. Structs in Crystal serve distinct purposes as they exist akin to classes, but allocate on the stack, conferring a specific advantage in efficiency while keeping immutability in mind.
00:14:14.245
I/O operations are optimized thoroughly in this language. All of the string interpolations and buffer manipulations weave through efficient abstraction, ultimately delivering impactful performance. Crystal’s approach capitalizes on ideas popularized by Go, bringing built-in formatters for code consistency throughout projects.
00:14:32.580
On the topic of concurrency, the model draws inspiration from Go as well, utilizing channels and coroutines effectively, though it remains crucial to note that parallelism isn't fully realized just yet. The Crystal community is persistent in evolving the language, and I encourage anyone interested to try it out.
00:14:54.480
For those eager to explore, visit crystal-lang.org/docs for installation instructions applicable across various platforms. Reflecting on my journey, I grew up in a small town in Illinois where everyone placed immense hopes on one individual, Justin. He was expected to achieve greatness but ultimately carved his own path in an unexpected way.
00:15:11.530
During a visit to Niagara Falls, I serendipitously found him feeding dolphins at an aquatic park. I asked him about his journey, and he humorously remarked about capturing his passion for serving a youthful purpose in a manner entirely different from what was anticipated. Thank you!