My favorite things in Crystal Lang
Tags: crystal, programming
Published: 2018-07-07 01:43:03

---
title: My favorite things in Crystal Lang
published: true
description: Some features the crystal language has that I find attractive
tags: crystal, programming
---

When learning a new language, there will be some moments that really make you appreciate that language. And occasionally, some moments that make you question your sanity. 

As I have been learning Crystal, there's a few things that I find myself saying "I love this!" giving me those same feelings I had for Ruby 12+ years ago. This list is the "out-of-the-box" features, methods, and constructs in [Crystal Lang](https://crystal-lang.org/) that I had to tell others about after I learned it.

_NOTE: before some of you say it, I know that these are not original language ideas_

## Method overloading

This is a concept where a class can have multiple methods with the same name. The way the compiler decides which method to call is based on the arguments that are passed (or not passed).

The thing I love about this is a lot of times you want a method to be called something specific, but you have to use it in a few different ways.

```ruby
class Pagination

  def initialize(opts = {} of String => String)
    initialize(opts["page"].to_i, opts["per"].to_i
  end

  def initialize(page : Int32, per : Int32)
    # setup the class
  end
end

Pagination.new({"page" => "1", "per" => "12"})
Pagination.new(1, 12)
```

In this example, you can have multiple ways to instantiate an object, but best of all, they can all funnel down to the actual implementation. This just gives you the ability to make a friendly DSL for the developers, while still keeping your implementation details how you need them. 

Other applications for this might be splitting your methods out for one to handle successful use, and another to handle error handling, or even several for different types of errors!

```ruby
def call(some_string : String)
  # do thing since a string was passed
end

def call(not_a_string : Nil)
  raise "some error instead because nil was passed"
end
```

## Instance Variables

Speaking of initialize... This is awesome.

```ruby
# Setting instance variable values in crystal
class Spot
  def initialize(@x : Int32, @y : Int32)
  end
end

# Setting instance variable values in ruby
class Spot
  def initialize(x, y)
    @x = x
    @y = y
  end
end
```

When you have just 2 arguments, it's not a huge deal. You generally want to keep the amount of arguments down anyway; however, have you looked at some art/game type setups? [looking at you gosu](https://www.rubydoc.info/github/gosu/gosu/Gosu/Image#draw_rot-instance_method). Having these setup when you define the method just makes things less noisy in your code.

## Tuples

These are collections of objects with a known size, and types in them. Since they don't exist in Ruby, PHP, or JavaScript, I never really knew what they were for.

```ruby
class Thing
  @x : Tuple(String, String)
end
```

In this example, I know that the instance variable `@x` will always and only ever contains 2 strings like `{"this", "that"}`. That's it. I defined it to be strictly 2 strings, and you can't add or remove from it. You could use an Array and put 2 elements in it, but from what I understand (which could be wrong) is that the Tuple is going to have a performance benefit since the compiler does a lot less guess work. You still use the Tuple like you would an array `@x[0] == "this"` `@x[1] == "that"` `@x.each ...`. 

## Map shortcut

You can do some fancy shorthand stuff in Ruby with blocks like `things.map(&:to_s)` which would map the `to_s` method on to each of the things. But if `things` was an array of hashes, and you wanted to pull out a value of a specific key, you couldn't use the shortcut. In crystal, you can!

```ruby
data = [{a: 1, b: 2}, {a: 3, b: 4}]
data.map(&.[:a]) # in crystal

data.map {|h| h[:a]} # in ruby
```


## Macros

A macro is some code that gets ran before your app is compiled. The macro code is expanded in to other code. If you've ever built a web application using some templating language (like ERB in ruby), then it's sort of like that. They're still kind of confusing to me, but here's a small example.

```ruby
macro run_tests
  {% for number in ["one", "two", "three"] %}
    def test_{{number.id}}
      puts "Testing {{number.id}}"
    end
  {% end %}
end
# actually run the macro
run_tests

# This would expand to:

def test_one
  puts "Testing one"
end
def test_two
  puts "Testing two"
end
def test_three
  puts "Testing three"
end
```

This macro would expand out to the three methods being defined, but only where you would actually call the `run_tests` method. It's sort of a way to get some metaprogramming in to your code to make things a bit more simple. The nice thing though is this expands before (during) the compilation of your program. Which means that when you run the program, those methods exist, and have already been type checked, etc...

Speaking of macros... There's a tool you can use from your command line with crystal to expand these macros out and see what they really look like. 

```ruby
macro test
  [
  {% for x in [0,1,2] %}
    {% for y in [4,5,6] %}
    [{{x.id}}, {{y.id}}],
    {% end %}
  {% end %}
  ]
end

test
```

```
$ crystal tool expand -c test.cr:11:1 ./test.cr
1 expansion found
expansion 1:
   test

# expand macro 'test' (/Users/jeremywoertink/Development/crystal/test.cr:1:1)
~> [[0, 4], [0, 5], [0, 6], [1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6]]
```

## T

The constant `T` is convention for this nifty feature, though, I'm sure you could really use any constant name (that doesn't conflict). Let's say you have a module that does some cool stuff, but this module requires some special types. You can setup the module to take this anonymous type `T` and have it as your placeholder.


```ruby
module Shared::PaginationComponent(T)
  private def render_pagination(pagination : T)
    # do pagination rendering
  end
end
```

Ok, so this module takes the T because the method takes an argument of `pagination` that's type `T`. In my case, this `T` could actually be a collection of `User` objects, or `Video` objects, or `Site` objects, etc... I could do something like

```ruby
def render_pagination(pagination : User::Collection | Video::Collection | Site::Collection | Whatever::Collection)
end
```

but then I would have to eventually figure out which of those it is, and then type cast `.as(User::Collection)`. Instead, with this I do


```ruby
class User::IndexPage
  include Shared::PaginationComponent(User::Collection) # see! It know exactly which to use here
end

class Site::IndexPage
  include Shared::PaginationComponent(Site::Collection)
end
```

## Make

Ok, so [Make](https://www.gnu.org/software/make/) actually has nothing to do with Crystal. I'm adding this in though because I've never had a reason to learn Make. I've seen some gnarly Makefiles in the past, and they've always scared me. Since starting with crystal, I've learned to use Make, and write my own Makefile to build my app. It makes me feel like a "real" programmer. 

```
OUT_DIR=bin
build: clean
	@mkdir -p $(OUT_DIR)
        @crystal build --release -o $(OUT_DIR)/app src/my_app.cr
clean:
    rm $(OUT_DIR)/app
```

This is a simple Makefile that you would put in the root of your project, then run `make build` to build your crystal project and put it in to your bin directory. 


## More

There's tons more I could talk about, but I think this is long enough. I'll probably add more specifics in later blogs as I start to understand some stuff better.