🚀 Crystal Introduction
🎯 Complete Definition
Crystal is a statically typed, compiled language with Ruby‑inspired syntax, but compiles to efficient native code via LLVM. Created by Ary Borenszweig and Juan Wajnerman in 2014, it combines the productivity of a high‑level language with the performance of C. Crystal features global type inference (no need to write types explicitly), nullable reference safety, and a powerful macro system. It is designed for building fast, concurrent systems with a clean syntax.
🔬 Core Characteristics
- Compiled (LLVM): Executes at speeds close to C, with link‑time optimisation.
- Statically typed: All types are known at compile time; type inference makes it feel dynamic.
- Ruby‑inspired syntax: Clean, readable, and expressive – but compiled, not interpreted.
- Nil‑safe: The compiler forces handling of nil through
Nilunion checks. - Concurrency: Lightweight fibers (like Go routines) with channel‑based communication.
- C bindings: Easy to call C libraries without writing glue code.
- Macros: Compile‑time code generation and metaprogramming.
📊 Industry Usage
Crystal powers high‑performance web apps (Kemal, Amber frameworks), API microservices, and systems programming where developer productivity and speed are both critical. Used by companies like Manas.Tech, PlaceOS, and many startups for its blend of productivity and native performance.
📊 Variables & Types
🎯 Complete Definition
Variables in Crystal are statically typed but type‑inferred. Once a variable is
assigned a value, its type is fixed (unless declared with a union). The language provides primitive
types (Int32, Int64, Float64, Bool, Char, String), as well as compound types
(Array, Hash, Tuple, NamedTuple, Set). Type annotations are optional thanks to
global type inference.
🏷️ Core Type System
- Int: Int8, Int16, Int32, Int64, UInt8 … UInt64 – fixed size, no overflow checks.
- Float: Float32, Float64 – IEEE 754.
- Bool: true / false.
- Char: single Unicode codepoint (e.g. 'A', 'é').
- String: UTF‑8 encoded, immutable.
- Symbol: Interned, immutable constants (:name).
- Nil: the only instance is
nil– must be handled explicitly. - Union types: e.g.
Int32 | String– automatically created.
🔧 Advanced Features
Type aliases (alias Age = Int32), typeof, as casting,
is_a? runtime checks, responds_to?, and Pointer for low‑level
memory access. Everything is an object – even primitives have methods.
🔢 Operators
🎯 Complete Definition
Operators in Crystal are methods (like Ruby) but compiled. Most operators can be overloaded via method definitions. Standard categories: arithmetic, comparison, bitwise, logical, assignment, and range. Operator precedence follows C/Ruby conventions.
📋 Operator Categories
- Arithmetic: +, -, *, /, %, ** (power, as method)
- Comparison: ==, !=, <, >, <=, >=, <=> (spaceship)
- Bitwise: &, |, ^, ~, <<, >>
- Logical: &&, ||, ! (short‑circuit)
- Assignment: =, +=, -=, *=, etc.
- Range: .. (inclusive) , ... (exclusive end)
- Misc: &+ (wrapping addition), | (union type), -> (literal pointer)
⚡ Precedence & Overloading
Same as Ruby: `**` highest, then unary `+ - ! ~`, then `* / %`, then `+ -`, then bit shifts, then bitwise AND, then `| ^`, then comparison, then `&&`, then `||`, then ranges, then assignment. Overload by defining method e.g. `def +(other)`.
🔀 Control Flow
🎯 Complete Definition
Control flow uses if, unless, case, and
ternary expressions. Crystal adds when (inside case) with flexible matching,
and the in operator for membership checks. All conditionals return values (like Ruby).
No `switch`, but case covers it with powerful type matching.
🏗️ Structures
- if / unless – also postfix: `puts "ok" if ok`
- ternary: `condition ? true_expr : false_expr`
- case … when – matches with `===` (case equality)
- in – checks membership: `x in 1..10`
- as – safe type casting in control flow
🔄 Loops
🎯 Complete Definition
Loops in Crystal use while, until, and iterators over
ranges/enumerables. There's no traditional `for` loop – instead you call `.each` on collections.
loop creates an infinite loop with `break`/`next`. Crystal's loops are expressions
(they return the value passed to `break`).
🏗️ Loop Forms
- while condition – runs while truthy
- until condition – runs while falsy
- loop – infinite, use `break`
- iterators: `each`, `times`, `upto`, `downto`, `step`
- break / next – with optional value
⚙️ Methods & Def
🎯 Complete Definition
Methods are defined with def and can have type restrictions, default
parameters, splats (*args), double splats (**options), and named arguments.
They return the last expression implicitly. Methods can be overloaded by arity and type restrictions
(multiple definitions with same name but different signatures).
🏗️ Method Features
- def name(arg : Type) : ReturnType – optional type restrictions
- default values:
def greet(name = "world") - splat:
def sum(*numbers)collects into Tuple - named args:
def foo(bar, baz)called asfoo(bar: 1, baz: 2) - block parameter:
&blockyields to block - forwarding:
def foo(*args, **options, &block)
📋 Structs & Tuples
🎯 Complete Definition
Structs are value types (stack allocated, copied on assignment) defined with struct.
They are ideal for small, immutable data. Tuples are fixed‑size, immutable sequences of
heterogeneous types, written as {1, "hello", true}. Named tuples ({name: "Crystal", year: 2014})
provide field access by name. Structs can have methods and implement interfaces.
🏗️ Key Differences
- class – reference type, heap allocated, inheritance.
- struct – value type, no inheritance, but can include modules.
- Tuple – immutable, positional, created with
{...}. - NamedTuple – immutable, keys, created with
{key: value}.
🔑 Modules & Libs
🎯 Complete Definition
Modules serve as namespaces and mixins. They can contain methods, constants, and
even include other modules. Crystal’s standard library provides JSON, HTTP,
YAML, Regex, File, etc. External dependencies are managed via
shards (Crystal's package manager) and require.
🏗️ Module Features
- include – adds methods as instance methods (mixin)
- extend – adds methods as class methods
- require – loads file or library
- import – for C bindings (similar to extern)
📝 Strings
🎯 Complete Definition
String is an immutable UTF‑8 encoded sequence. Strings support interpolation
("Hello #{name}"), multi‑line with """ , and a rich API for
manipulation (size, split, strip, index, etc.). Character encoding is always UTF‑8; invalid byte
sequences raise. Strings are comparable, and can be used as keys in hashes.
🔧 Important Methods
size/length– number of characters (not bytes)bytesize– raw byte lengthincludes?,starts_with?,ends_with?gsub,sub,scancamelcase,underscore,capitalize
💾 File I/O
🎯 Complete Definition
File handling is done via the File class and IO module.
Common operations: read whole file (File.read), write (File.write),
open with block for auto‑close. IO also supports pipes, sockets, and memory buffers.
Use File.open with mode: "r", "w", "a", "r+", etc.
📁 Modes & Methods
File.read(path)– returns stringFile.write(path, content)– writes (overwrites)File.open(path, "w") { |f| f.puts line }Dir.entries,File.exists?,File.deleteIO::Memoryfor in‑memory string/binary I/O
🛡️ Exceptions
🎯 Complete Definition
Exceptions are objects derived from Exception. Raised with raise,
rescued with begin … rescue … else … ensure. Multiple rescue clauses can match different
exception types. ensure always runs. Crystal also has try macro for nil handling.
🏗️ Structure
raise "message"– raises RuntimeErrorrescue ex : ArgumentError– specific typerescue– catches any Exceptionelse– runs if no exceptionensure– always runs
🏗️ Classes & OOP
🎯 Complete Definition
Classes are reference types supporting inheritance, polymorphism, and encapsulation.
Instance variables begin with @, class variables with @@. Constructors are
initialize. Getters/setters with property macro. Abstract classes and methods
can be defined with abstract. Modules can be mixed in (include, extend).
🏛️ OOP Features
- inheritance:
class Child < Parent - abstract class / def – must be overridden
- super – calls parent method
- method missing via
responds_to?/ macro - virtual / polymorphic calls – automatic
⚡ Concurrency
🎯 Complete Definition
Concurrency in Crystal uses spawn to create lightweight fibers
(not OS threads). Fibers are scheduled cooperatively on a thread pool. Communication happens via
channels (Channel(T)) similar to Go. The event loop (libevent) handles non‑blocking I/O.
This model enables high‑concurrency servers with low overhead.
🏗️ Concurrency primitives
spawn– create fiberChannel(T)– send/receive between fibersselect– wait on multiple channelssleep,yield– cooperative schedulingMutex,Atomicfor shared memory
🔮 Macros & Metaprogramming
🎯 Complete Definition
Macros are methods that run at compile time, operating on the AST to generate code.
They are defined with macro and can manipulate syntax nodes, conditionally emit code,
and inspect types. Macros enable DSLs, boilerplate reduction, and performance optimisations without
runtime overhead.
🔧 Macro Capabilities
{% if … %}/{% for … %}– compile‑time control{{ expression }}– output evaluated macro value\{{ run("./generator") }}– run external program@type– access current type infodef macro– define macro method