Roc is the fast, friendly, functional programming language designed for building reliable software — with no runtime exceptions, automatic memory management without GC, and compilation to native binaries.
What Is Roc?
Created by Richard Feldman (author of Elm in Action), Roc is a functional language that:
- Compiles to native code via LLVM — fast like Rust, friendly like Elm
- No runtime exceptions — if it compiles, it runs
- No null, no undefined — algebraic types eliminate entire categories of bugs
- Automatic memory management — reference counting, not GC
- Platforms — separable IO model (the killer architectural feature)
The Platform Model (Unique to Roc)
In Roc, your application code is pure — it can't do IO directly. Instead, you choose a platform that handles IO:
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.17.0/lZFLstMUCUvd5bjnnpNROaxkxKSierke.tar.br" }
import pf.Stdout
import pf.Task
main =
Stdout.line! "Hello from Roc!"
Different platforms for different use cases:
-
basic-cli— command-line apps -
basic-webserver— HTTP servers -
basic-graphics— GUI applications
Pattern Matching
Color : [Red, Green, Blue, Custom Str]
colorToHex : Color -> Str
colorToHex = \color ->
when color is
Red -> "#FF0000"
Green -> "#00FF00"
Blue -> "#0000FF"
Custom hex -> hex
The compiler guarantees you handle every case. Miss one? Compile error.
Records and Type Inference
# Roc infers types — no annotations needed
makeUser = \name, email ->
{ name, email, createdAt: "2026-03-30", active: Bool.true }
# But you can annotate if you want
User : { name : Str, email : Str, createdAt : Str, active : Bool }
greet : User -> Str
greet = \user ->
"Hello, $(user.name)!"
List Operations (Functional Style)
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Filter, map, reduce — no mutations
evenDoubled =
numbers
|> List.keepIf \n -> n % 2 == 0
|> List.map \n -> n * 2
# Result: [4, 8, 12, 16, 20]
sum =
numbers
|> List.walk 0 \state, n -> state + n
# Result: 55
Web Server
app [Model, server] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.9.0/..." }
import pf.Http exposing [Request, Response]
Model : {}
server = { init: Task.ok {}, respond }
respond : Request, Model -> Task Response [ServerErr Str]_
respond = \req, _model ->
when req.method is
Get ->
if req.url == "/api/health" then
Task.ok { status: 200, headers: [], body: Str.toUtf8 "{\"status\":\"ok\"}" }
else
Task.ok { status: 404, headers: [], body: Str.toUtf8 "Not found" }
_ ->
Task.ok { status: 405, headers: [], body: Str.toUtf8 "Method not allowed" }
Error Handling (No Exceptions)
parseAge : Str -> Result U32 [InvalidAge]
parseAge = \input ->
when Str.toU32 input is
Ok n if n > 0 && n < 150 -> Ok n
_ -> Err InvalidAge
# Caller MUST handle both cases
handleAge = \input ->
when parseAge input is
Ok age -> "You are $(Num.toStr age) years old"
Err InvalidAge -> "Please enter a valid age"
Quick Start
# Install Roc
curl -fsSL https://github.com/roc-lang/roc/releases/latest/download/roc_nightly-linux_x86_64-latest.tar.gz | tar xz
# Run a Roc program
roc run main.roc
# Build optimized binary
roc build --optimize main.roc
# Format code
roc format main.roc
# Run tests
roc test main.roc
Roc vs Elm vs Haskell vs Rust
| Feature | Roc | Elm | Haskell | Rust |
|---|---|---|---|---|
| Target | Native binary | JavaScript | Native binary | Native binary |
| Memory | Ref counting | GC (JS) | GC | Ownership |
| IO Model | Platforms | Elm Architecture | Monads | Direct |
| Learning curve | Low | Low | High | High |
| Speed | Fast (LLVM) | JS speed | Fast | Fastest |
| Null/exceptions | None | None | Maybe/Either | None |
Need to scrape data from any website and get it in structured JSON? Check out my web scraping tools on Apify — no coding required, results in minutes.
Have a custom data extraction project? Email me at spinov001@gmail.com — I build tailored scraping solutions for businesses.
Top comments (0)