docs: add comprehensive language documentation
Documentation structure inspired by Rust Book, Elm Guide, and others: Guide (10 chapters): - Introduction and setup - Basic types (Int, String, Bool, List, Option, Result) - Functions (closures, higher-order, composition) - Data types (ADTs, pattern matching, records) - Effects (the core innovation) - Handlers (patterns and techniques) - Modules (imports, exports, organization) - Error handling (Fail, Option, Result) - Standard library reference - Advanced topics (traits, generics, optimization) Reference: - Complete syntax reference Tutorials: - Calculator (parsing, evaluation, REPL) - Dependency injection (testing with effects) - Project ideas (16 projects by difficulty) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
222
docs/guide/01-introduction.md
Normal file
222
docs/guide/01-introduction.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# Chapter 1: Introduction to Lux
|
||||
|
||||
Welcome to Lux, a functional programming language where side effects are first-class citizens.
|
||||
|
||||
## Why Lux?
|
||||
|
||||
Every program does more than compute. It reads files, makes network requests, prints output, handles errors. In most languages, these *effects* are invisible—a function's type doesn't tell you what it might do.
|
||||
|
||||
Lux changes this. Effects are:
|
||||
- **Visible** in the type signature
|
||||
- **Controllable** via handlers
|
||||
- **Composable** without boilerplate
|
||||
|
||||
This isn't just academic. It means:
|
||||
- Tests can swap real I/O for mocks—automatically
|
||||
- Error handling is explicit, not exceptional
|
||||
- Dependencies are injected through the type system
|
||||
|
||||
## Installation
|
||||
|
||||
### From Source (Cargo)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/your-org/lux
|
||||
cd lux
|
||||
cargo build --release
|
||||
|
||||
# Add to PATH
|
||||
export PATH="$PATH:$(pwd)/target/release"
|
||||
```
|
||||
|
||||
### With Nix
|
||||
|
||||
```bash
|
||||
# Enter development shell
|
||||
nix develop
|
||||
|
||||
# Or build
|
||||
nix build
|
||||
./result/bin/lux
|
||||
```
|
||||
|
||||
### Verify Installation
|
||||
|
||||
```bash
|
||||
$ lux --version
|
||||
Lux 0.1.0
|
||||
|
||||
$ lux --help
|
||||
Usage: lux [OPTIONS] [FILE]
|
||||
|
||||
Options:
|
||||
-c, --check Type check without running
|
||||
--lsp Start LSP server
|
||||
--repl Start interactive REPL
|
||||
-h, --help Print help
|
||||
```
|
||||
|
||||
## Your First Program
|
||||
|
||||
Create a file called `hello.lux`:
|
||||
|
||||
```lux
|
||||
// hello.lux - Your first Lux program
|
||||
|
||||
fn main(): Unit with {Console} =
|
||||
Console.print("Hello, Lux!")
|
||||
|
||||
let output = run main() with {}
|
||||
```
|
||||
|
||||
Run it:
|
||||
|
||||
```bash
|
||||
$ lux hello.lux
|
||||
Hello, Lux!
|
||||
```
|
||||
|
||||
Let's break this down:
|
||||
|
||||
### The Function Signature
|
||||
|
||||
```lux
|
||||
fn main(): Unit with {Console}
|
||||
```
|
||||
|
||||
- `fn main()` - A function named `main` with no parameters
|
||||
- `: Unit` - Returns `Unit` (like `void`)
|
||||
- `with {Console}` - **Uses the Console effect**
|
||||
|
||||
That last part is key. The type tells us this function prints to the console. A function without `with {...}` is *pure*—it can only compute.
|
||||
|
||||
### The Body
|
||||
|
||||
```lux
|
||||
Console.print("Hello, Lux!")
|
||||
```
|
||||
|
||||
`Console.print` is an *effect operation*. It's not a regular function—it's a request to the environment to print something.
|
||||
|
||||
### Running Effects
|
||||
|
||||
```lux
|
||||
let output = run main() with {}
|
||||
```
|
||||
|
||||
The `run ... with {}` expression executes a computation with its effects. The `{}` means "use the default handlers for all effects." Console's default handler prints to stdout.
|
||||
|
||||
## The REPL
|
||||
|
||||
Lux has an interactive mode:
|
||||
|
||||
```bash
|
||||
$ lux
|
||||
Lux v0.1.0 - Type :help for commands
|
||||
|
||||
>
|
||||
```
|
||||
|
||||
Try some expressions:
|
||||
|
||||
```
|
||||
> 1 + 2
|
||||
3
|
||||
|
||||
> "Hello, " + "World"
|
||||
"Hello, World"
|
||||
|
||||
> [1, 2, 3]
|
||||
[1, 2, 3]
|
||||
|
||||
> List.map([1, 2, 3], fn(x: Int): Int => x * 2)
|
||||
[2, 4, 6]
|
||||
```
|
||||
|
||||
Define functions:
|
||||
|
||||
```
|
||||
> fn square(x: Int): Int = x * x
|
||||
<function>
|
||||
|
||||
> square(5)
|
||||
25
|
||||
|
||||
> fn greet(name: String): Unit with {Console} = Console.print("Hi, " + name)
|
||||
<function>
|
||||
|
||||
> run greet("Alice") with {}
|
||||
Hi, Alice
|
||||
```
|
||||
|
||||
REPL commands:
|
||||
|
||||
```
|
||||
:help - Show help
|
||||
:type e - Show type of expression
|
||||
:quit - Exit REPL
|
||||
:clear - Clear screen
|
||||
```
|
||||
|
||||
## A Slightly Bigger Program
|
||||
|
||||
Let's write a program that asks for your name:
|
||||
|
||||
```lux
|
||||
// greet.lux
|
||||
|
||||
fn askName(): String with {Console} = {
|
||||
Console.print("What's your name?")
|
||||
Console.readLine()
|
||||
}
|
||||
|
||||
fn main(): Unit with {Console} = {
|
||||
let name = askName()
|
||||
Console.print("Hello, " + name + "!")
|
||||
}
|
||||
|
||||
let output = run main() with {}
|
||||
```
|
||||
|
||||
```bash
|
||||
$ lux greet.lux
|
||||
What's your name?
|
||||
> Alice
|
||||
Hello, Alice!
|
||||
```
|
||||
|
||||
Notice how:
|
||||
- `askName` returns `String` but has `with {Console}` because it does I/O
|
||||
- Both functions declare their effects
|
||||
- The `run` at the end provides the runtime
|
||||
|
||||
## Pure vs Effectful
|
||||
|
||||
Here's the key insight. Compare:
|
||||
|
||||
```lux
|
||||
// Pure - no effects, only computes
|
||||
fn add(a: Int, b: Int): Int = a + b
|
||||
|
||||
// Effectful - uses Console
|
||||
fn printSum(a: Int, b: Int): Unit with {Console} =
|
||||
Console.print(toString(a + b))
|
||||
```
|
||||
|
||||
You can call `add` from anywhere. But `printSum` can only be called from:
|
||||
1. Another function that declares `Console`
|
||||
2. Inside a `run ... with {}` block
|
||||
|
||||
This is the effect discipline. Effects propagate up until handled.
|
||||
|
||||
## What's Next
|
||||
|
||||
Now that you can run programs, let's learn:
|
||||
|
||||
- [Chapter 2: Basic Types](02-basic-types.md) - Numbers, strings, booleans
|
||||
- [Chapter 3: Functions](03-functions.md) - Definitions, closures, composition
|
||||
- [Chapter 4: Data Types](04-data-types.md) - ADTs and pattern matching
|
||||
|
||||
Or jump ahead to what makes Lux special:
|
||||
|
||||
- [Chapter 5: Effects](05-effects.md) - The core innovation
|
||||
Reference in New Issue
Block a user