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:
2026-02-13 17:43:41 -05:00
parent 9ee7148d24
commit 44f88afcf8
16 changed files with 4845 additions and 0 deletions

320
docs/guide/07-modules.md Normal file
View File

@@ -0,0 +1,320 @@
# Chapter 7: Modules
As programs grow, you need to split code across files. Lux has a module system for organizing and sharing code.
## Module Basics
Every `.lux` file is a module. The file path determines the module path:
```
project/
├── main.lux # Module: main
├── utils.lux # Module: utils
└── lib/
├── math.lux # Module: lib/math
└── strings.lux # Module: lib/strings
```
## Importing Modules
### Basic Import
```lux
import lib/math
fn main(): Unit with {Console} = {
Console.print(toString(lib/math.square(5)))
}
```
Wait, that's verbose. Use an alias:
### Aliased Import
```lux
import lib/math as math
fn main(): Unit with {Console} = {
Console.print(toString(math.square(5)))
}
```
### Selective Import
Import specific items directly:
```lux
import lib/math.{square, cube}
fn main(): Unit with {Console} = {
Console.print(toString(square(5))) // No prefix needed
Console.print(toString(cube(3)))
}
```
### Wildcard Import
Import everything:
```lux
import lib/math.*
fn main(): Unit with {Console} = {
Console.print(toString(square(5)))
Console.print(toString(cube(3)))
Console.print(toString(factorial(6)))
}
```
Use sparingly—it can cause name conflicts.
## Visibility
By default, declarations are private. Use `pub` to export:
```lux
// lib/math.lux
// Public - can be imported
pub fn square(x: Int): Int = x * x
pub fn cube(x: Int): Int = x * x * x
// Private - internal helper
fn helper(x: Int): Int = x + 1
// Public type
pub type Point = { x: Int, y: Int }
```
## Creating a Module
Let's create a string utilities module:
```lux
// lib/strings.lux
/// Repeat a string n times
pub fn repeat(s: String, n: Int): String =
if n <= 0 then ""
else s + repeat(s, n - 1)
/// Check if string starts with prefix
pub fn startsWith(s: String, prefix: String): Bool =
String.startsWith(s, prefix)
/// Check if string ends with suffix
pub fn endsWith(s: String, suffix: String): Bool =
String.endsWith(s, suffix)
/// Pad string on the left to reach target length
pub fn padLeft(s: String, length: Int, char: String): String = {
let current = String.length(s)
if current >= length then s
else padLeft(char + s, length, char)
}
/// Pad string on the right to reach target length
pub fn padRight(s: String, length: Int, char: String): String = {
let current = String.length(s)
if current >= length then s
else padRight(s + char, length, char)
}
```
Using it:
```lux
// main.lux
import lib/strings as str
fn main(): Unit with {Console} = {
Console.print(str.repeat("ab", 3)) // "ababab"
Console.print(str.padLeft("5", 3, "0")) // "005"
}
let output = run main() with {}
```
## Module Organization Patterns
### Feature Modules
Group by feature:
```
project/
├── main.lux
├── users/
│ ├── types.lux # User type definitions
│ ├── repository.lux # Database operations
│ └── service.lux # Business logic
├── orders/
│ ├── types.lux
│ ├── repository.lux
│ └── service.lux
└── shared/
├── utils.lux
└── effects.lux
```
### Layer Modules
Group by layer:
```
project/
├── main.lux
├── domain/ # Business logic (pure)
│ ├── user.lux
│ └── order.lux
├── effects/ # Effect definitions
│ ├── database.lux
│ └── email.lux
├── handlers/ # Effect implementations
│ ├── postgres.lux
│ └── smtp.lux
└── api/ # Entry points
└── http.lux
```
## Standard Library
Lux has a standard library in the `std/` directory:
```lux
import std/prelude.* // Common utilities
import std/option // Option helpers
import std/result // Result helpers
import std/io // I/O utilities
```
### std/prelude
```lux
import std/prelude.*
identity(42) // 42
compose(f, g) // Function composition
not(true) // false
and(true, false) // false
or(true, false) // true
```
### std/option
```lux
import std/option as opt
opt.some(42) // Some(42)
opt.none() // None
opt.map(Some(5), double) // Some(10)
opt.flatMap(Some(5), safeDivide)
opt.unwrapOr(None, 0) // 0
```
### std/result
```lux
import std/result as res
res.ok(42) // Ok(42)
res.err("oops") // Err("oops")
res.mapOk(Ok(5), double) // Ok(10)
res.mapErr(Err("x"), upper) // Err("X")
```
## Circular Dependencies
Lux detects circular imports:
```lux
// a.lux
import b
pub fn fromA(): Int = b.fromB() + 1
// b.lux
import a
pub fn fromB(): Int = a.fromA() + 1
// Error: Circular dependency detected
```
Solution: extract shared code to a third module.
## Module Best Practices
### 1. One Concept Per Module
```lux
// Good: focused module
// user.lux - User type and operations
pub type User = { id: Int, name: String }
pub fn createUser(name: String): User = ...
pub fn validateUser(u: User): Bool = ...
// Bad: kitchen sink
// utils.lux - random stuff
pub fn parseUser(s: String): User = ...
pub fn formatDate(d: Date): String = ...
pub fn calculateTax(amount: Int): Int = ...
```
### 2. Export Deliberately
```lux
// Only export what others need
pub fn publicApi(): Result = ...
// Keep helpers private
fn internalHelper(): Int = ...
```
### 3. Use Aliases for Clarity
```lux
// Clear what comes from where
import database/postgres as db
import cache/redis as cache
fn getData(id: Int): Data with {Database, Cache} = {
match cache.get(id) {
Some(d) => d,
None => {
let d = db.query(id)
cache.set(id, d)
d
}
}
}
```
### 4. Group Related Imports
```lux
// Standard library
import std/prelude.*
import std/option as opt
// Project modules
import lib/database as db
import lib/cache as cache
// Local modules
import ./types.{User, Order}
import ./validation
```
## Summary
| Syntax | Meaning |
|--------|---------|
| `import path/to/module` | Import module |
| `import path/to/module as alias` | Import with alias |
| `import path/to/module.{a, b}` | Import specific items |
| `import path/to/module.*` | Import all exports |
| `pub fn` / `pub type` | Export declaration |
## Next
[Chapter 8: Error Handling](08-errors.md) - Handling failures gracefully.