Nithin Bekal About

Notes / Crystal

Crystal is a compiled, statically typed programming language that has a syntax very similar to Ruby. Crystal uses much of Ruby’s syntax and the object model, but it compiles to native code, which makes Crystal programs run faster than Ruby ones.

The dynamically typed nature of Ruby makes it a very expressive language. However, this expressiveness comes at the cost of performance, making it much slower than compiled languages like Go or Java.

Crystal has static types, which helps catch a lot of errors at compile time. Don’t worry, though - you won’t be writing verbose type annotations everywhere. The Crystal compiler infers the type of your variables, allowing you to take advantage of static typing while writing Ruby-like code.

Running your first crystal program

Let’s start off with a hello world program in Crystal.

puts "Hello, world!"

You can run the program by using the crystal run command. Crystal programs use the .cr file extension.

$ crystal run hello.cr
Hello, world!

If you wish to only create the crystal executable, you can use the crystal build command. This would create a compiled executable file called hello, which you can then run.

$ crystal build hello.cr
$ ./hello
Hello, world!

Creating a crystal project

$ crystal init lib Foo
      create  Foo/.gitignore
      create  Foo/LICENSE
      create  Foo/README.md
      create  Foo/.travis.yml
      create  Foo/shard.yml
      create  Foo/src/Foo.cr
      create  Foo/src/Foo/version.cr
      create  Foo/spec/spec_helper.cr
      create  Foo/spec/Foo_spec.cr
Initialized empty Git repository in ~/Foo/.git/

Basic data types

  • Number
  • Boolean
  • Tuple
  • Boolean
  • String
  • Array
  • Hash
  • Struct

Arrays and hashes

Type inference

a = 1    # a :: Int32
b = a    # b :: Int32

if some_condition?
  a = 1
else
  a = "Hello"
end
# a :: (Int32 | String)

Methods and overloading

def add(x : String, y : String)
  x.to_i + y.to_i
end

def add(x, y)
  x+y
end

Generic types

class Stack(T)
  def initialize
    @values = Array(T).new
  end
end

Concurrency

spawn creates a new Fiber to execute the block. The program continues running after creating fiber.

spawn do
  # do something
end

Channels are a way to send messages to a fiber.

ch = Channel(Int32).new
spawn do
  puts ch.receive
end

ch.send(42)

Metaprogramming

macro attr_reader(*names)
  {% for name in names %}
    def {{name}}
      @{{name}}
    end
  {% end %}
end