Add `lux compile <file>` command that compiles and runs Lux code using the Cranelift JIT compiler. Includes --benchmark flag for timing. - Add compile_file() function in main.rs - Add jit_test.lux example with fib(30) + factorial(10) - Update VISION.md status Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Lux Documentation
Lux is a functional programming language with first-class algebraic effects. It combines the safety of static typing with the flexibility of effect handlers, letting you write pure code that can do impure things—without losing control.
Quick Links
| I want to... | Go to... |
|---|---|
| Try Lux in 5 minutes | Quick Start |
| Learn Lux systematically | The Lux Guide |
| Understand effects | Effects Guide |
| Look up syntax | Language Reference |
| See the standard library | Standard Library |
| Build something | Tutorials |
Quick Start
Install
# Clone and build
git clone https://github.com/your-org/lux
cd lux
cargo build --release
# Or with Nix
nix build
Hello World
Create hello.lux:
fn main(): Unit with {Console} =
Console.print("Hello, World!")
let output = run main() with {}
Run it:
lux hello.lux
# Output: Hello, World!
The REPL
$ lux
Lux v0.1.0 - Type :help for commands
> 1 + 2 * 3
7
> fn square(x: Int): Int = x * x
<function>
> square(5)
25
> List.map([1, 2, 3], fn(x: Int): Int => x * 2)
[2, 4, 6]
What Makes Lux Different?
1. Effects Are Explicit
In most languages, a function can do anything—print, crash, launch missiles—and the type doesn't tell you. In Lux, side effects are tracked:
// This function ONLY does math—the type guarantees it
fn add(a: Int, b: Int): Int = a + b
// This function uses Console—you can see it in the signature
fn greet(name: String): Unit with {Console} =
Console.print("Hello, " + name)
2. Effects Are Handleable
Effects aren't just tracked—they're values you can intercept and redefine:
effect Logger {
fn log(msg: String): Unit
}
fn compute(): Int with {Logger} = {
Logger.log("Starting")
let result = 42
Logger.log("Done")
result
}
// Run with console logging
handler consoleLogger: Logger {
fn log(msg) = {
Console.print("[LOG] " + msg)
resume(())
}
}
let result = run compute() with { Logger = consoleLogger }
3. Handlers Can Resume
Unlike exceptions, effect handlers can continue the computation:
effect Ask {
fn ask(question: String): String
}
fn survey(): Unit with {Ask, Console} = {
let name = Ask.ask("What's your name?")
let color = Ask.ask("Favorite color?")
Console.print(name + " likes " + color)
}
// Handler that provides answers
handler autoAnswer: Ask {
fn ask(q) =
if String.contains(q, "name") then resume("Alice")
else resume("blue")
}
run survey() with { Ask = autoAnswer }
// Output: Alice likes blue
Documentation Structure
The Lux Guide
A sequential guide to learning Lux, from basics to advanced topics.
- Introduction - Why Lux, installation, first program
- Basic Types - Int, String, Bool, functions
- Functions - Definitions, closures, higher-order
- Data Types - ADTs, pattern matching, records
- Effects - The core innovation
- Handlers - Defining and using handlers
- Modules - Code organization, imports
- Error Handling - Fail effect, Option, Result
- Standard Library - Built-in functions
- Advanced Topics - Traits, generics, optimization
Language Reference
Complete syntax and semantics reference.
- Syntax - Grammar and syntax rules
- Types - Type system details
- Effects - Effect system reference
- Standard Library - All built-in functions
Tutorials
Project-based learning.
Standard Programs:
- Calculator - Basic REPL calculator
- Todo App - File I/O and data structures
- HTTP Client - Fetching web data
Effect Showcases:
- Dependency Injection - Testing with effects
- State Machines - Modeling state with effects
- Parser Combinators - Effects for backtracking
Project Ideas
Once you've learned the basics, try building:
Beginner
- Unit converter - Temperatures, distances, weights
- Word counter - Count words, lines, characters in files
- Quiz game - Random questions with scoring
Intermediate
- Markdown parser - Parse and render Markdown
- Task manager - CLI todo list with file persistence
- API client - Fetch and display data from a REST API
Advanced
- Effect-based testing framework - Use effects for test isolation
- Configuration DSL - Effect-based config with validation
- Interpreter - Build a small language interpreter
Showcasing Effects
- Transactional file system - Rollback on failure using effects
- Mock HTTP for testing - Swap real HTTP with mock handlers
- Async simulation - Model concurrency with effect handlers
- Capability-based security - Effects as capabilities
Philosophy
Lux is designed around these principles:
- Explicitness over magic - Effects in the type signature, not hidden
- Composition over inheritance - Effects combine freely
- Safety with escape hatches - Type safety by default, but practical
- Functional core, imperative shell - Pure logic, effectful boundaries
Getting Help
- REPL: Type
:helpfor commands - LSP: Full IDE support in VS Code, Neovim
- Examples: See
examples/directory - Issues: Report bugs on GitHub
Lux: Where effects are first-class citizens.