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:
325
docs/guide/10-advanced.md
Normal file
325
docs/guide/10-advanced.md
Normal file
@@ -0,0 +1,325 @@
|
||||
# Chapter 10: Advanced Topics
|
||||
|
||||
This chapter covers advanced features for building larger applications.
|
||||
|
||||
## Traits
|
||||
|
||||
Traits define shared behavior across types:
|
||||
|
||||
```lux
|
||||
trait Show {
|
||||
fn show(self): String
|
||||
}
|
||||
|
||||
impl Show for Int {
|
||||
fn show(self): String = toString(self)
|
||||
}
|
||||
|
||||
impl Show for Bool {
|
||||
fn show(self): String = if self then "true" else "false"
|
||||
}
|
||||
|
||||
impl Show for List<T> where T: Show {
|
||||
fn show(self): String = {
|
||||
let items = List.map(self, fn(x: T): String => x.show())
|
||||
"[" + String.join(items, ", ") + "]"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using traits:
|
||||
|
||||
```lux
|
||||
fn display<T>(value: T): Unit with {Console} where T: Show =
|
||||
Console.print(value.show())
|
||||
|
||||
display(42) // "42"
|
||||
display(true) // "true"
|
||||
display([1, 2, 3]) // "[1, 2, 3]"
|
||||
```
|
||||
|
||||
## Generic Types
|
||||
|
||||
Types with parameters:
|
||||
|
||||
```lux
|
||||
type Pair<A, B> =
|
||||
| MkPair(A, B)
|
||||
|
||||
fn first<A, B>(p: Pair<A, B>): A =
|
||||
match p {
|
||||
MkPair(a, _) => a
|
||||
}
|
||||
|
||||
fn second<A, B>(p: Pair<A, B>): B =
|
||||
match p {
|
||||
MkPair(_, b) => b
|
||||
}
|
||||
|
||||
let p = MkPair(1, "one")
|
||||
first(p) // 1
|
||||
second(p) // "one"
|
||||
```
|
||||
|
||||
## Type Constraints
|
||||
|
||||
Restrict generic types:
|
||||
|
||||
```lux
|
||||
fn maximum<T>(list: List<T>): Option<T> where T: Ord = {
|
||||
match list {
|
||||
[] => None,
|
||||
[x] => Some(x),
|
||||
[x, ...rest] => {
|
||||
match maximum(rest) {
|
||||
None => Some(x),
|
||||
Some(y) => Some(if x > y then x else y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tail Call Optimization
|
||||
|
||||
Lux optimizes tail-recursive functions:
|
||||
|
||||
```lux
|
||||
// Not tail-recursive - stack grows with each call
|
||||
fn sumBad(n: Int): Int =
|
||||
if n <= 0 then 0
|
||||
else n + sumBad(n - 1) // Addition happens AFTER recursive call
|
||||
|
||||
// Tail-recursive - constant stack space
|
||||
fn sumGood(n: Int, acc: Int): Int =
|
||||
if n <= 0 then acc
|
||||
else sumGood(n - 1, acc + n) // Recursive call is the LAST operation
|
||||
|
||||
fn sum(n: Int): Int = sumGood(n, 0)
|
||||
```
|
||||
|
||||
The compiler transforms tail calls into loops, preventing stack overflow.
|
||||
|
||||
## Effect Polymorphism
|
||||
|
||||
Functions can be polymorphic over effects:
|
||||
|
||||
```lux
|
||||
fn withLogging<E>(action: fn(): Int with {E}): Int with {E, Console} = {
|
||||
Console.print("Starting action")
|
||||
let result = action()
|
||||
Console.print("Action returned: " + toString(result))
|
||||
result
|
||||
}
|
||||
|
||||
// Works with any effect set
|
||||
fn pureAction(): Int = 42
|
||||
fn randomAction(): Int with {Random} = Random.int(1, 100)
|
||||
|
||||
withLogging(pureAction) // Works
|
||||
withLogging(randomAction) // Works
|
||||
```
|
||||
|
||||
## Behavioral Properties
|
||||
|
||||
Annotate functions with properties:
|
||||
|
||||
```lux
|
||||
// Pure function - no effects
|
||||
fn add(a: Int, b: Int): Int is pure = a + b
|
||||
|
||||
// Total function - always terminates
|
||||
fn factorial(n: Int): Int is total =
|
||||
if n <= 1 then 1 else n * factorial(n - 1)
|
||||
|
||||
// Idempotent - same result if called multiple times
|
||||
fn setConfig(key: String, value: String): Unit with {State} is idempotent =
|
||||
State.put(value)
|
||||
```
|
||||
|
||||
These are currently documentation, but future versions may verify them.
|
||||
|
||||
## Documentation Comments
|
||||
|
||||
Use `///` for documentation:
|
||||
|
||||
```lux
|
||||
/// Calculates the factorial of a non-negative integer.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `n` - A non-negative integer
|
||||
///
|
||||
/// # Returns
|
||||
/// The factorial of n (n!)
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// factorial(5) // Returns 120
|
||||
/// ```
|
||||
pub fn factorial(n: Int): Int =
|
||||
if n <= 1 then 1 else n * factorial(n - 1)
|
||||
```
|
||||
|
||||
## Performance Tips
|
||||
|
||||
### 1. Use Tail Recursion
|
||||
|
||||
```lux
|
||||
// Slow - builds up stack
|
||||
fn lengthSlow<T>(list: List<T>): Int =
|
||||
match list {
|
||||
[] => 0,
|
||||
[_, ...rest] => 1 + lengthSlow(rest)
|
||||
}
|
||||
|
||||
// Fast - constant stack
|
||||
fn lengthFast<T>(list: List<T>, acc: Int): Int =
|
||||
match list {
|
||||
[] => acc,
|
||||
[_, ...rest] => lengthFast(rest, acc + 1)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Avoid Repeated Concatenation
|
||||
|
||||
```lux
|
||||
// Slow - O(n²)
|
||||
fn buildStringSlow(n: Int): String =
|
||||
if n <= 0 then ""
|
||||
else buildStringSlow(n - 1) + "x"
|
||||
|
||||
// Fast - use List.join
|
||||
fn buildStringFast(n: Int): String =
|
||||
String.join(List.map(List.range(0, n), fn(_: Int): String => "x"), "")
|
||||
```
|
||||
|
||||
### 3. Use Built-in Functions
|
||||
|
||||
```lux
|
||||
// Slow - manual implementation
|
||||
fn sumManual(nums: List<Int>): Int =
|
||||
match nums {
|
||||
[] => 0,
|
||||
[x, ...rest] => x + sumManual(rest)
|
||||
}
|
||||
|
||||
// Fast - built-in fold
|
||||
fn sumBuiltin(nums: List<Int>): Int =
|
||||
List.fold(nums, 0, fn(acc: Int, x: Int): Int => acc + x)
|
||||
```
|
||||
|
||||
### 4. JIT Compilation
|
||||
|
||||
For performance-critical numeric code, the JIT compiler provides ~160x speedup:
|
||||
|
||||
```lux
|
||||
// In Rust code, use the JIT compiler
|
||||
let mut jit = JitCompiler::new().unwrap();
|
||||
jit.compile_function(&func).unwrap();
|
||||
let result = unsafe { jit.call_function("fib", &[30]).unwrap() };
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
### Debug Printing
|
||||
|
||||
```lux
|
||||
fn debug<T>(label: String, value: T): T with {Console} = {
|
||||
Console.print(label + ": " + toString(value))
|
||||
value
|
||||
}
|
||||
|
||||
fn process(x: Int): Int with {Console} = {
|
||||
let step1 = debug("step1", x * 2)
|
||||
let step2 = debug("step2", step1 + 10)
|
||||
step2
|
||||
}
|
||||
```
|
||||
|
||||
### The Debugger
|
||||
|
||||
Run with debugger:
|
||||
|
||||
```bash
|
||||
lux --debug program.lux
|
||||
```
|
||||
|
||||
Commands:
|
||||
- `step` / `s` - Step into
|
||||
- `next` / `n` - Step over
|
||||
- `continue` / `c` - Continue
|
||||
- `print <expr>` - Evaluate expression
|
||||
- `break <line>` - Set breakpoint
|
||||
- `quit` / `q` - Exit
|
||||
|
||||
### Effect Tracing
|
||||
|
||||
```lux
|
||||
fn traced<E>(action: fn(): T with {E}): T with {E, Console} = {
|
||||
Console.print(">>> Entering action")
|
||||
let result = action()
|
||||
Console.print("<<< Exiting with: " + toString(result))
|
||||
result
|
||||
}
|
||||
```
|
||||
|
||||
## IDE Support
|
||||
|
||||
Lux has LSP support for:
|
||||
- **VS Code**: Install Lux extension
|
||||
- **Neovim**: Configure with nvim-lspconfig
|
||||
|
||||
Features:
|
||||
- Syntax highlighting
|
||||
- Error diagnostics
|
||||
- Go to definition
|
||||
- Hover for types
|
||||
- Auto-completion
|
||||
|
||||
Start LSP server:
|
||||
```bash
|
||||
lux --lsp
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
Recommended layout for larger projects:
|
||||
|
||||
```
|
||||
my-project/
|
||||
├── lux.toml # Project manifest
|
||||
├── src/
|
||||
│ ├── main.lux # Entry point
|
||||
│ ├── lib.lux # Library code
|
||||
│ └── modules/
|
||||
│ ├── users.lux
|
||||
│ └── orders.lux
|
||||
├── std/ # Custom std extensions
|
||||
├── tests/
|
||||
│ ├── users_test.lux
|
||||
│ └── orders_test.lux
|
||||
└── examples/
|
||||
└── demo.lux
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
| Feature | Syntax |
|
||||
|---------|--------|
|
||||
| Trait | `trait Name { fn method(self): T }` |
|
||||
| Impl | `impl Trait for Type { ... }` |
|
||||
| Generic | `fn f<T>(x: T): T` |
|
||||
| Constraint | `where T: Trait` |
|
||||
| Tail recursion | Last expression is recursive call |
|
||||
| Doc comment | `/// Documentation` |
|
||||
|
||||
## What's Next?
|
||||
|
||||
You now know Lux! Try:
|
||||
|
||||
1. **Build something**: See [Tutorials](../tutorials/README.md)
|
||||
2. **Read the reference**: See [Language Reference](../reference/syntax.md)
|
||||
3. **Explore effects**: See [Effects Cookbook](../tutorials/effects-cookbook.md)
|
||||
4. **Join the community**: GitHub discussions
|
||||
|
||||
Happy coding with Lux!
|
||||
Reference in New Issue
Block a user