Getting Started with Quartz
This guide walks you through installing Quartz, writing your first program, and building something real.
Prerequisites
- macOS (arm64 or x86_64) or Linux (x86_64 or aarch64)
- LLVM (version 15+) — provides
llcandclang
Install LLVM
macOS (Homebrew):
brew install llvm
export PATH="/opt/homebrew/opt/llvm/bin:$PATH" # Add to your shell profile
Ubuntu/Debian:
sudo apt install llvm clang
Verify LLVM is available:
llc --version | head -1 # Should show LLVM version
clang --version | head -1 # Should show clang version
Install Quartz
git clone https://github.com/mattkel/quartz.git
cd quartz
The compiler binary is pre-built at self-hosted/bin/quartz. Verify it works:
./self-hosted/bin/quartz examples/hello.qz | head -1
# Should print: ; Generated by Quartz self-hosted compiler (incremental)
Hello World
Create a file called hello.qz:
def main(): Int
puts("Hello, Quartz!")
return 0
end
Compile and run it:
# 1. Compile to LLVM IR
./self-hosted/bin/quartz hello.qz > hello.ll
# 2. Assemble to object file
llc -filetype=obj hello.ll -o hello.o
# 3. Link to binary
clang hello.o -o hello -lm -lpthread
# 4. Run
./hello
# Output: Hello, Quartz!
A Real Program: Word Counter
Let’s build a simple word counter that reads from stdin.
Create wc.qz:
def count_words(text: String): Int
var count = 0
var in_word = false
for ch in text
if ch == ' ' or ch == '\n' or ch == '\t'
in_word = false
elsif not in_word
in_word = true
count += 1
end
end
return count
end
def main(): Int
input = read_stdin()
lines = str_split(input, "\n")
var total_lines = 0
var total_words = 0
var total_chars = 0
for line in lines
total_lines += 1
total_words += count_words(line)
total_chars += line.size
end
puts(" #{total_lines} lines")
puts(" #{total_words} words")
puts(" #{total_chars} chars")
return 0
end
Compile and test:
./self-hosted/bin/quartz wc.qz > wc.ll
llc -filetype=obj wc.ll -o wc.o
clang wc.o -o wc -lm -lpthread
echo "hello world\nfoo bar baz" | ./wc
Key Language Features
# Const by default — no `let` keyword needed
name = "Quartz"
version = 5
# Mutable variables use `var`
var count = 0
count += 1
# Single-expression functions (endless def)
def double(x: Int): Int = x * 2
def pi = 3.14159
# String interpolation
puts("#{name} v#{version}")
# Pattern matching
match status
200 => puts("OK")
404 => puts("Not Found")
_ => puts("Unknown: #{status}")
end
# For-in loops
for i in 0..10
puts("#{i}")
end
# Lambdas
squared = items.map(x -> x * x)
# Implicit `it` in trailing blocks
evens = items.filter() { it % 2 == 0 }
# Safe navigation and nil coalescing
port = config?.port ?? 8080
Using the Build System
For multi-file projects, use Quake (Quartz’s build system):
# Run all tests
./self-hosted/bin/quake test
# Format your code
./self-hosted/bin/quake format
# See all available tasks
./self-hosted/bin/quake --list
Next Steps
- QUARTZ_REFERENCE.md — Complete language syntax and semantics
- STYLE.md — Idiomatic code conventions
- INTRINSICS.md — All built-in functions
- QUAKE.md — Build system documentation
- examples/ — Working example programs covering closures, concurrency, generics, FFI, and more