Examples
Overview
Elle ships with 20+ executable example programs. Each file is self-contained — run it, read the output, read the source. Start with hello.lisp and work down.
cargo run -- examples/hello.lisp # start here
cargo run -- examples/basics.lisp # then exploreExample Inventory
| File | What It Covers |
|---|---|
| hello.lisp | Smoke test — one line, proves the toolchain works |
| basics.lisp | Type system tour: immediates, truthiness, arithmetic, the mutable/immutable split, bytes, boxes, equality |
| functions.lisp | A gradebook built with defn/fn, closures, higher-order functions, composition, pipelines, variadic and mutual recursion |
| control.lisp | An expression evaluator: if, cond, case, when/unless, if-let/when-let, while, forever, block/break, full match patterns, -> / ->> |
| collections.lisp | A contact book app exercising literal syntax, get/put, destructuring, each, threading, splice, string ops, grapheme clusters |
| destructuring.lisp | Unpacking data: silent nil semantics, wildcards, & rest, nested patterns, struct/table by-key, match dispatch on struct tags |
| errors.lisp | Error handling: error, try/catch, protect, defer, with, propagation, safe wrappers, validation |
| coroutines.lisp | Cooperative sequences: coro/new, yield, lifecycle, Fibonacci generator, interleaving, nesting, yield delegation |
| meta.lisp | Macros and hygiene: defmacro, quasiquote/unquote, gensym, datum->syntax, syntax->datum |
| concurrency.lisp | Parallel threads: spawn, join, closure capture across threads, parallel computation |
| processes.lisp | Erlang-style actors: fiber-based scheduler, message passing with send/recv, links, trap-exit, crash propagation |
| io.lisp | Files, JSON, modules: slurp/spit, paths, directories, json-parse/json-serialize, import-file |
| introspection.lisp | Looking inside: clock primitives, time/elapsed, closure introspection, disbit/disjit, benchmarking |
| ffi.lisp | C interop: ffi/native, ffi/defbind, structs, variadic calls, callbacks (qsort) |
| signals.lisp | User-defined signals, silence restrictions, early termination, progress reporting, logging, plugin sandboxing |
| fuel.lisp | Instruction budget management |
| parameters.lisp | Dynamic bindings |
| channels.lisp | Message passing channels |
| async_io.lisp | Async I/O operations |
| http.lisp | HTTP client |
Hello World
The simplest Elle program — hello.lisp:
#!/usr/bin/env elle
# Simple hello world example
(print "Hello, World!")
(println)Functions and Closures
From functions.lisp — a gradebook application that introduces Elle's function features:
View source excerpt
# fn creates an anonymous function (a "lambda").
# (fn [params] body) — brackets delimit the parameter list.
(def average (fn [a b] (/ (+ a b) 2)))
(assert (= (average 80 90) 85) "fn: average")
(print " (average 80 90) = ") (println (average 80 90))
# defn is shorthand for (def name (fn [params] body))
(defn letter-grade [score]
(cond
((>= score 90) "A")
((>= score 80) "B")
((>= score 70) "C")
((>= score 60) "D")
(true "F")))
(assert (= (letter-grade 95) "A") "defn: A")
(assert (= (letter-grade 72) "C") "defn: C")Coroutines
From coroutines.lisp — cooperative sequences with coro/new, yield, and lifecycle tracking:
View source excerpt
# coro/new wraps a zero-arg function into a coroutine.
# coro/resume steps it forward; yield suspends and returns a value.
(def co (coro/new (fn [] (yield 42))))
(assert (coro? co) "coro/new returns a coroutine")
(assert (= (coro/status co) :new) "initial status is :new")
(def v (coro/resume co))
(print " first resume: ") (println v)
(assert (= v 42) "first resume returns yielded value")
(assert (= (coro/status co) :paused) "status after yield is :paused")
(coro/resume co)
(assert (= (coro/status co) :dead) "status after body completes is :dead")Signals
From signals.lisp — user-defined signals for flow control:
View source excerpt
# Declare user-defined signal keywords
(signal :abort) # early termination — caller catches and uses the value
(signal :progress) # progress update — caller can display or collect
(signal :log) # log entry — caller decides whether to record it
# find-first scans a list and signals :abort the moment pred is satisfied.
# The rest of the list is never visited — no wasted work.
(defn find-first [pred xs]
(each x in xs
(when (pred x)
(emit :abort x))))
# Drive from a fiber with a signal mask
(def f (fiber/new (fn [] (find-first even? [1 3 5 4 7])) |:abort|))
(fiber/resume f)
(assert (= (fiber/value f) 4) "found first even")Processes
From processes.lisp — Erlang-style actors built on fibers, with message passing via send/recv, links, and crash propagation.
FFI
From ffi.lisp — calling C functions directly with automatic type marshalling:
View source excerpt
# Load a shared library and bind a C function
(def libc (ffi/native nil))
(ffi/defbind libc puts [:string] :int)
(puts "hello from C")