by Craig Buchek

St. Louis Ruby User Group

March 10, 2014


Crystal Is Inspired by Ruby

If you know Ruby, it's easy to get started

Syntax is about 90% the same as Ruby

Semantics are about 80% the same as Ruby

(Differences mainly due to being compiled)

							class Foo(T)
							  property :bar
							  def initialize(@bar : T)
							foo ="string")
							puts #=> "string"
							foo2 = Foo(Int).new(123)
							puts #=> 123

Crystal Is Compiled

No support for dynamic features:

  • define_method
  • method_missing
  • eval

Supported "dynamic" features:

  • instance_eval
  • responds_to?
  • macro

Binaries range from 100 KB to 20 MB

Crystal Is Fast

Compiles pretty quickly

  • Compiles itself in less than 45 seconds
  • My Date class takes less than 1 second

Binaries are fast

  • My Date specs run in about 7 milliseconds
  • Newing up 1 million objects: 30 ms
    • 275 ms in Ruby (including 120 ms startup time)

Compiles and runs quickly

  • Full test suite takes less than 60 seconds
    • 2200 specs
  • Standard lib test suite takes about 5 seconds
    • 500 specs

Compiling LLVM bytecode to assembler is multithreaded

Crystal Is Typed

Types are inferred in most cases

  • Including union types

Eliminates NullPointerException errors

							def nil_or_string
							  rand(2) == 0 ? nil : "string"
							nil_or_string.capitalize #=> Compile error: undefined method 'capitalize' for Nil

Methods can have variants with different signatures

							struct Date
							  def initialize(year : Int, month : Int, day : Int, @calendar = Date::Calendar.default)
							    @jdn = @calendar.ymd_to_jdn(year, month, day).to_i64
							  def initialize(jdn : Int, @calendar = Date::Calendar.default)
							    @jdn = jdn.to_i64

Empty arrays and hashes have to declare their type

							x = [1] # OK
							x = [1, 1.5, 'a', "abc"] # OK
							x = []  # Syntax Error
							x = [] of Int
							x = [] of String|Nil|Int32
							y = {} of Symbol => String

No support for send

Crystal Is High-Level

Based on the Ruby we love

Strong OOP

Strong sense of getting things right and no surprises

Crystal Is Low-Level

Easy to interface with C libraries

							lib LibReadline("readline")
							  fun readline(prompt : UInt8*) : UInt8*
							module Readline
							  def self.readline(prompt)
							    line = LibReadline.readline(prompt)
							    line ? : nil

C types

							lib C
							  fun atoi(str : UInt8*) : Int32
							  fun atoll(str : UInt8*) : Int64
							  fun atof(str : UInt8*) : Float64
							  fun strtof(str : UInt8*, endp : UInt8**) : Float32
							  fun sprintf(str : UInt8*, format : UInt8*, ...) : Int32

Low-level types

  • Pointer
  • Reference
  • Value
  • Struct
  • enum

Crystal Is Innovative

Shorthand syntax for initializer params

							class URI
							  def initialize(@scheme, @host, @port, @path, @query_string)
							    @uri = "#{@scheme}://#{@host}:#{@port}/#{@path}?#{@query_string}"

Macros for getter, setter, property, and delegate

							class Object
							  macro self.getter(name)"
							    def #{name}

Hash initialization takes an optional key comparator

							h = Hash(String, Int).new(nil, Hash::CaseInsensitiveComparator)
							h["abc"] = 123
							puts h["AbC"] #=> 123

Block shorthand syntax

							[1, 20, 300].map &.to_s.length #=> [1, 2, 3]

Null checking


Crystal Is Young

Started in September 2012

Standard library is somewhat minimal

  • Array, Hash, Set, Regex
  • Time, Env, File, Dir, Socket, MD5
  • Net::HTTP
  • Missing: Date, Logger, Pathname

Spec library is minimal

  • describe
  • it
  • should

No database support

No Windows support

No debugger

REPL is a hack

  • Can't raise exceptions in some cases - just crashes
  • Anything with a side effect will be executed on every command
  • Several things just don't work

Crystal Is In Flux

Ported compiler from Ruby to self-hosting

They don't want to document too much

  • Because things are changing so fast

Things are broken sometimes

  • REPL was not compiling

Lots of changes in the past year

  • Garbage collection

Crystal Is Undocumented

Implicit conversions:

  • String to UInt8* for C functions
  • Nil to 0 for C functions taking a pointer

Class v. Struct

Syntax for complex types

No introspection

Crystal Is Full of Potential

I like what I see

I think it's pretty fast

  • The primary devs think it's too slow



Primary Developers