Website rebuilt from scratch based on analysis of 11 beloved language websites (Elm, Zig, Gleam, Swift, Kotlin, Haskell, OCaml, Crystal, Roc, Rust, Go). New website structure: - Homepage with hero, playground, three pillars, install guide - Language Tour with interactive lessons (hello world, types, effects) - Examples cookbook with categorized sidebar - API documentation index - Installation guide (Nix and source) - Sleek/noble design (black/gold, serif typography) Also includes: - New stdlib/json.lux module for JSON serialization - Enhanced stdlib/http.lux with middleware and routing - New string functions (charAt, indexOf, lastIndexOf, repeat) - LSP improvements (rename, signature help, formatting) - Package manager transitive dependency resolution - Updated documentation for effects and stdlib - New showcase example (task_manager.lux) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1049 lines
30 KiB
Markdown
1049 lines
30 KiB
Markdown
# Lux Comprehensive Roadmap
|
|
|
|
*A complete design document covering modules, behavioral types, schema evolution, C backend optimizations, LSP, package manager, REPL, HTTP server, async/concurrency, documentation, and error messages.*
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Modules](#1-modules)
|
|
2. [Behavioral Types](#2-behavioral-types)
|
|
3. [Schema Evolution](#3-schema-evolution)
|
|
4. [C Backend Optimizations](#4-c-backend-optimizations)
|
|
5. [LSP Improvement Plan](#5-lsp-improvement-plan)
|
|
6. [Package Manager](#6-package-manager)
|
|
7. [REPL](#7-repl)
|
|
8. [HTTP Server](#8-http-server)
|
|
9. [Async & Concurrency](#9-async--concurrency)
|
|
10. [Documentation](#10-documentation)
|
|
11. [Error Messages](#11-error-messages)
|
|
|
|
---
|
|
|
|
## 1. Modules
|
|
|
|
### Current State: COMPLETE
|
|
|
|
The module system is production-ready with comprehensive features.
|
|
|
|
**Implemented:**
|
|
- Module imports and exports (`import foo.bar`)
|
|
- Visibility modifiers (`pub` keyword)
|
|
- Module aliases (`import foo as bar`)
|
|
- Selective imports (`import foo.{a, b, c}`)
|
|
- Wildcard imports (`import foo.*`)
|
|
- Circular dependency detection
|
|
- Module caching and lazy loading
|
|
- Package entry points (`lib.lux`, `src/lib.lux`)
|
|
|
|
**Code Locations:**
|
|
- `src/modules.rs` (797 lines) - Module loading and resolution
|
|
- `src/ast.rs` - ImportDecl structure
|
|
- `src/parser.rs` - Import parsing
|
|
- `docs/guide/07-modules.md` - User documentation
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Status |
|
|
|------|----------|--------|
|
|
| Lock file support (`lux.lock`) | P1 | Missing |
|
|
| Version resolution algorithm | P1 | Missing |
|
|
| Re-exports (`pub import foo`) | P2 | Missing |
|
|
| Private module directories | P3 | Missing |
|
|
| Type-only imports | P3 | Missing |
|
|
|
|
### Lock File Design
|
|
|
|
```toml
|
|
# lux.lock - generated, don't edit
|
|
[[package]]
|
|
name = "http-client"
|
|
version = "1.2.3"
|
|
source = "registry"
|
|
checksum = "sha256:abc123..."
|
|
|
|
[[package]]
|
|
name = "json-parser"
|
|
version = "0.5.0"
|
|
source = { git = "https://github.com/...", rev = "abc123" }
|
|
dependencies = ["utf8-utils"]
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Behavioral Types
|
|
|
|
### Current State: COMPLETE
|
|
|
|
All five behavioral properties are fully implemented with verification.
|
|
|
|
**Properties:**
|
|
|
|
| Property | Verification | Compiler Checks |
|
|
|----------|--------------|-----------------|
|
|
| `is pure` | Effect analysis | Empty effect set |
|
|
| `is total` | Structural recursion | No Fail, decreasing args |
|
|
| `is deterministic` | Effect analysis | No Random/Time effects |
|
|
| `is idempotent` | Pattern recognition | Constants, identity, clamping, abs |
|
|
| `is commutative` | Operator analysis | 2 params + commutative op |
|
|
|
|
**Code Locations:**
|
|
- `src/ast.rs:123-150` - BehavioralProperty enum
|
|
- `src/types.rs:361-462` - PropertySet
|
|
- `src/typechecker.rs:1290-1403` - Verification logic
|
|
- `docs/guide/12-behavioral-types.md` - Documentation
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Status |
|
|
|------|----------|--------|
|
|
| Property inference | P2 | Missing |
|
|
| Property testing integration | P2 | Missing |
|
|
| Effect-aware optimization hints | P1 | Missing |
|
|
| `is associative` property | P3 | Missing |
|
|
| `is monotonic` property | P3 | Missing |
|
|
|
|
### Property Testing Integration
|
|
|
|
```lux
|
|
// Compiler-generated property tests
|
|
fn add(a: Int, b: Int): Int is commutative = a + b
|
|
|
|
// Auto-generates:
|
|
test "add is commutative" = {
|
|
forAll(fn(a: Int, b: Int): Bool => add(a, b) == add(b, a))
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Schema Evolution
|
|
|
|
### Current State: COMPLETE
|
|
|
|
Full schema evolution with versioned types and migrations.
|
|
|
|
**Implemented:**
|
|
- Version annotations (`@v1`, `@v2`, `@latest`)
|
|
- Migration declarations (`from @v1 = { ... }`)
|
|
- Schema registry and compatibility checking
|
|
- Auto-migration generation for simple changes
|
|
- Migration chain execution (v1→v2→v3)
|
|
- Runtime Schema module (versioned, migrate, getVersion)
|
|
|
|
**Code Locations:**
|
|
- `src/schema.rs` - Schema registry
|
|
- `src/interpreter.rs:784-851` - Migration execution
|
|
- `src/typechecker.rs:1045-1120` - Validation
|
|
- `docs/guide/13-schema-evolution.md` - Documentation
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Status |
|
|
|------|----------|--------|
|
|
| JSON codec generation | P1 | Missing |
|
|
| Version-aware serialization | P1 | Missing |
|
|
| Binary format support | P2 | Missing |
|
|
| Avro/Protobuf interop | P3 | Missing |
|
|
| Migration visualization | P3 | Missing |
|
|
|
|
### Codec Generation Design
|
|
|
|
```lux
|
|
type User @v2 {
|
|
name: String,
|
|
email: String,
|
|
createdAt: Timestamp
|
|
} deriving (JsonCodec, BinaryCodec)
|
|
|
|
// Auto-generates:
|
|
// User.toJson(user: User@v2): String
|
|
// User.fromJson(json: String): Result<User@v2, ParseError>
|
|
// User.toBinary(user: User@v2): Bytes
|
|
// User.fromBinary(bytes: Bytes): Result<User@v2, ParseError>
|
|
```
|
|
|
|
---
|
|
|
|
## 4. C Backend Optimizations
|
|
|
|
### Current State: PRODUCTION-READY
|
|
|
|
Sophisticated C backend with Perceus-style reference counting.
|
|
|
|
**Implemented:**
|
|
- Reference counting with scope-based cleanup
|
|
- FBIP (Functional But In-Place) optimizations
|
|
- Evidence passing for zero-cost effects
|
|
- All 8 built-in effects (Console, File, Http, Random, Time, State, Reader, Process)
|
|
- Drop specialization by type
|
|
- Ownership transfer analysis
|
|
|
|
**Code Locations:**
|
|
- `src/codegen/c_backend.rs` (4,749 lines)
|
|
- `docs/C_BACKEND.md`, `docs/REFERENCE_COUNTING.md`
|
|
- `docs/COMPILER_OPTIMIZATIONS.md`
|
|
|
|
### Behavioral Type Optimizations
|
|
|
|
The C backend is ready to leverage behavioral types:
|
|
|
|
| Property | Optimization | Implementation |
|
|
|----------|--------------|----------------|
|
|
| `is pure` | Memoization | Cache results by args hash |
|
|
| `is pure` | CSE | Eliminate redundant calls |
|
|
| `is pure` | Dead code elimination | Remove unused pure calls |
|
|
| `is pure` | Auto-parallelization | `#pragma omp parallel` |
|
|
| `is total` | No exception overhead | Skip try/catch codegen |
|
|
| `is total` | Aggressive inlining | No stack overflow risk |
|
|
| `is deterministic` | Result caching | Global cache for expensive ops |
|
|
| `is idempotent` | Duplicate elimination | `f(x); f(x)` → `f(x)` |
|
|
| `is idempotent` | Retry optimization | No state reset needed |
|
|
| `is commutative` | Argument canonicalization | `f(b,a)` → `f(a,b)` for cache hits |
|
|
| `is commutative` | Parallel reduction | Tree reduction pattern |
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Effort | Impact |
|
|
|------|----------|--------|--------|
|
|
| Pure function memoization | P1 | 2 weeks | High |
|
|
| Idempotent call deduplication | P1 | 1 week | Medium |
|
|
| Commutative parallel reduction | P2 | 2 weeks | High |
|
|
| Deterministic result caching | P2 | 1 week | Medium |
|
|
| Total function inlining | P2 | 1 week | Medium |
|
|
| Drop fusion | P3 | 3 days | Low |
|
|
| LLVM backend | P3 | 8 weeks | High |
|
|
|
|
### Memoization Implementation
|
|
|
|
```c
|
|
// For: fn fib(n: Int): Int is pure = ...
|
|
|
|
typedef struct {
|
|
int64_t key;
|
|
int64_t value;
|
|
bool valid;
|
|
} MemoEntry_fib;
|
|
|
|
static MemoEntry_fib memo_fib[1024]; // Power of 2 for fast modulo
|
|
|
|
int64_t fib_lux(int64_t n) {
|
|
size_t idx = (size_t)n & 1023; // Fast modulo
|
|
if (memo_fib[idx].valid && memo_fib[idx].key == n) {
|
|
return memo_fib[idx].value; // Cache hit
|
|
}
|
|
|
|
int64_t result = (n <= 1) ? n : fib_lux(n-1) + fib_lux(n-2);
|
|
|
|
memo_fib[idx].key = n;
|
|
memo_fib[idx].value = result;
|
|
memo_fib[idx].valid = true;
|
|
return result;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 5. LSP Improvement Plan
|
|
|
|
### Current State: FUNCTIONAL
|
|
|
|
Working LSP with diagnostics, hover, completion, go-to-definition, and references.
|
|
|
|
**Implemented:**
|
|
- Diagnostics (parse + type errors)
|
|
- Hover (type signatures for functions, variables, etc.)
|
|
- Completion (context-aware, module-specific, trigger on '.')
|
|
- Go-to-definition (AST-based symbol table)
|
|
- Find references (symbol table lookup)
|
|
- Document symbols (functions, types, effects)
|
|
- Document synchronization
|
|
- Proper symbol table infrastructure (`src/symbol_table.rs`)
|
|
|
|
**Code Locations:**
|
|
- `src/lsp.rs` (~900 lines) - LSP server
|
|
- `src/symbol_table.rs` (~660 lines) - Semantic analysis infrastructure
|
|
|
|
### Gaps vs Full LSP
|
|
|
|
| Feature | Status | Priority |
|
|
|---------|--------|----------|
|
|
| Diagnostics | Complete | - |
|
|
| Hover | Complete (via symbol table) | - |
|
|
| Completion | Mostly complete | P2 |
|
|
| Go-to-definition | Complete (symbol table) | - |
|
|
| References | Complete (symbol table) | - |
|
|
| Document symbols | Complete | - |
|
|
| Rename | Missing | P2 |
|
|
| Workspace symbols | Missing | P2 |
|
|
| Signature help | Missing | P2 |
|
|
| Code actions | Missing | P3 |
|
|
| Formatting | Missing (integration) | P2 |
|
|
| Semantic tokens | Missing | P3 |
|
|
| Inlay hints | Missing | P3 |
|
|
|
|
### Architecture
|
|
|
|
**Implemented:** AST-based symbol table with scope resolution
|
|
|
|
The `SymbolTable` (`src/symbol_table.rs`) provides:
|
|
- `SymbolId` - Unique identifiers for symbols
|
|
- `Symbol` - Definitions with name, kind, span, type signature, documentation
|
|
- `Reference` - Usages of symbols with position tracking
|
|
- `Scope` - Nested scopes with parent references
|
|
- AST visitors for building the table from a parsed program
|
|
|
|
```rust
|
|
// New architecture
|
|
struct SymbolTable {
|
|
scopes: Vec<Scope>,
|
|
definitions: HashMap<SymbolId, Definition>,
|
|
references: HashMap<Position, SymbolId>,
|
|
}
|
|
|
|
struct Definition {
|
|
name: String,
|
|
kind: SymbolKind, // Function, Variable, Type, Effect
|
|
typ: Type,
|
|
span: Span,
|
|
doc: Option<String>,
|
|
}
|
|
|
|
impl LspServer {
|
|
fn on_did_change(&mut self, uri: &Url, text: &str) {
|
|
let ast = self.parser.parse(text);
|
|
let symbols = self.build_symbol_table(&ast);
|
|
self.symbol_tables.insert(uri.clone(), symbols);
|
|
}
|
|
|
|
fn goto_definition(&self, uri: &Url, pos: Position) -> Option<Location> {
|
|
let table = self.symbol_tables.get(uri)?;
|
|
let sym_id = table.references.get(&pos)?;
|
|
let def = table.definitions.get(sym_id)?;
|
|
Some(Location { uri: uri.clone(), range: def.span.to_range() })
|
|
}
|
|
}
|
|
```
|
|
|
|
### Roadmap
|
|
|
|
| Phase | Tasks | Effort |
|
|
|-------|-------|--------|
|
|
| Phase 1 | ~~Build symbol table, fix goto-def~~ | ✅ Complete |
|
|
| Phase 2 | ~~References, document symbols~~ | ✅ Complete |
|
|
| Phase 3 | Rename, signature help | 2 weeks |
|
|
| Phase 4 | Workspace symbols, formatting integration | 1 week |
|
|
| Phase 5 | Code actions, inlay hints, semantic tokens | 2 weeks |
|
|
|
|
---
|
|
|
|
## 6. Package Manager
|
|
|
|
### Current State: NEARLY COMPLETE
|
|
|
|
Full-featured package manager with manifest, lock files, version resolution, and registry integration.
|
|
|
|
**Implemented:**
|
|
- `lux pkg init` - Create lux.toml
|
|
- `lux pkg add/remove` - Manage dependencies
|
|
- `lux pkg install` - Install from manifest with lock file
|
|
- `lux pkg list` - Show dependencies
|
|
- `lux pkg update` - Update and reinstall
|
|
- `lux pkg clean` - Remove installed packages
|
|
- `lux pkg search` - Search registry
|
|
- `lux pkg publish` - Publish to registry
|
|
- Git, local path, and registry dependencies
|
|
- `.lux_packages/` directory resolution
|
|
- Lock file generation (`lux.lock`)
|
|
- Version constraint parsing (^, ~, >=, <, *, ranges)
|
|
- Semantic versioning with prerelease support
|
|
|
|
**Registry Server:**
|
|
- Full HTTP server (`src/registry.rs`)
|
|
- Package metadata and tarball storage
|
|
- Search API
|
|
- Publish endpoint
|
|
|
|
**Code Locations:**
|
|
- `src/package.rs` (~1000 lines) - Package manager and resolver
|
|
- `src/registry.rs` (~637 lines) - Registry server
|
|
|
|
### Comparison with Other Package Managers
|
|
|
|
| Feature | Cargo (Rust) | npm (JS) | pip (Python) | Lux |
|
|
|---------|--------------|----------|--------------|-----|
|
|
| Manifest | Cargo.toml | package.json | pyproject.toml | lux.toml |
|
|
| Lock file | Cargo.lock | package-lock.json | requirements.txt | lux.lock ✅ |
|
|
| Version constraints | Yes | Yes | Yes | ✅ ^, ~, >=, <, * |
|
|
| Registry | crates.io | npmjs.com | PyPI | ✅ Built-in server |
|
|
| Publish | `cargo publish` | `npm publish` | `twine upload` | ✅ `lux pkg publish` |
|
|
| Search | `cargo search` | `npm search` | `pip search` | ✅ `lux pkg search` |
|
|
| Transitive deps | Yes | Yes | Yes | ⚠️ Direct only |
|
|
| Scripts | build.rs | scripts | setup.py | Missing |
|
|
| Workspaces | Yes | Yes | No | Missing |
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Effort | Status |
|
|
|------|----------|--------|--------|
|
|
| Lock file generation | P0 | 1 week | ✅ Complete |
|
|
| Version constraint parsing | P0 | 3 days | ✅ Complete |
|
|
| Registry server | P1 | 3 weeks | ✅ Complete |
|
|
| `lux pkg publish` | P1 | 1 week | ✅ Complete |
|
|
| Package search CLI | P2 | 3 days | ✅ Complete |
|
|
| Transitive dependency resolution | P1 | 2 weeks | Partial |
|
|
| Workspaces support | P3 | 2 weeks | Missing |
|
|
| HTTPS support | P2 | 1 week | Missing |
|
|
|
|
### Version Resolution Design
|
|
|
|
```rust
|
|
// Semantic versioning constraints
|
|
enum VersionConstraint {
|
|
Exact(Version), // "1.2.3"
|
|
Caret(Version), // "^1.2.3" - compatible updates
|
|
Tilde(Version), // "~1.2.3" - patch updates only
|
|
Range(Version, Version), // ">=1.0, <2.0"
|
|
Any, // "*"
|
|
}
|
|
|
|
// Resolution algorithm (PubGrub-inspired)
|
|
fn resolve(root: &Manifest) -> Result<LockFile, ResolutionError> {
|
|
let mut solution = PartialSolution::new();
|
|
let mut incompatibilities = Vec::new();
|
|
|
|
loop {
|
|
match solution.next_undecided() {
|
|
Some(package) => {
|
|
let versions = fetch_versions(&package);
|
|
match select_version(&package, &versions, &solution) {
|
|
Some(v) => solution.decide(package, v),
|
|
None => {
|
|
// Conflict - backtrack or fail
|
|
let conflict = analyze_conflict(&solution);
|
|
incompatibilities.push(conflict);
|
|
if !solution.backtrack(&conflict) {
|
|
return Err(ResolutionError::Unsatisfiable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
None => return Ok(solution.to_lock_file()),
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Registry Design
|
|
|
|
```
|
|
registry.lux-lang.dev/
|
|
├── api/
|
|
│ ├── v1/
|
|
│ │ ├── packages/ GET list, POST publish
|
|
│ │ ├── packages/{name}/ GET metadata
|
|
│ │ ├── packages/{name}/{version}/ GET specific version
|
|
│ │ └── search?q=... GET search
|
|
│ └── auth/ Authentication
|
|
├── storage/
|
|
│ └── packages/
|
|
│ └── {name}/
|
|
│ └── {version}/
|
|
│ ├── package.tar.gz
|
|
│ └── checksum.sha256
|
|
```
|
|
|
|
---
|
|
|
|
## 7. REPL
|
|
|
|
### Current State: FUNCTIONAL
|
|
|
|
Interactive REPL with history, completions, and commands.
|
|
|
|
**Implemented:**
|
|
- Expression evaluation
|
|
- Multi-line input (brace continuation)
|
|
- History (persisted to ~/.lux_history)
|
|
- Completions (keywords, types, user definitions)
|
|
- Commands: `:help`, `:quit`, `:type`, `:info`, `:clear`, `:load`, `:env`, `:effects`
|
|
- User-defined function tracking
|
|
|
|
**Code Location:** `src/main.rs:1698-1847`
|
|
|
|
### Comparison with Other REPLs
|
|
|
|
| Feature | GHCi (Haskell) | utop (OCaml) | iex (Elixir) | Lux |
|
|
|---------|----------------|--------------|--------------|-----|
|
|
| Tab completion | Yes | Yes | Yes | Yes |
|
|
| Multi-line | Yes | Yes | Yes | Yes |
|
|
| History | Yes | Yes | Yes | Yes |
|
|
| Type query | `:t` | `#show` | `i` | `:type` |
|
|
| Load file | `:l` | `#use` | `c` | `:load` |
|
|
| Reload | `:r` | `#reload` | `r` | Missing |
|
|
| Debug/trace | Yes | Yes | `IEx.pry` | Missing |
|
|
| Step eval | Partial | No | No | Missing |
|
|
| Effect viz | N/A | N/A | N/A | Missing |
|
|
| Hot reload | No | No | Yes | Missing |
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Effort |
|
|
|------|----------|--------|
|
|
| `:reload` command | P1 | 2 days |
|
|
| Step-by-step evaluation | P2 | 2 weeks |
|
|
| Effect visualization | P2 | 2 weeks |
|
|
| Type hole support (`_`) | P2 | 1 week |
|
|
| Syntax highlighting | P2 | 1 week |
|
|
| Pretty-printed output | P2 | 3 days |
|
|
| `:bench` command | P3 | 3 days |
|
|
| WebSocket REPL server | P3 | 1 week |
|
|
|
|
### Effect Visualization Design
|
|
|
|
```
|
|
lux> :trace
|
|
Effect tracing enabled.
|
|
|
|
lux> run processOrder(order) with {}
|
|
[00:00.001] Console.print("Processing order...")
|
|
[00:00.015] Database.query("SELECT * FROM products WHERE id = 42")
|
|
→ [{ id: 42, name: "Widget", price: 9.99 }]
|
|
[00:00.023] Database.query("SELECT balance FROM accounts WHERE user = 'alice'")
|
|
→ [{ balance: 150.00 }]
|
|
[00:00.031] Database.execute("UPDATE accounts SET balance = 140.01 WHERE user = 'alice'")
|
|
→ 1 row affected
|
|
[00:00.045] Email.send({ to: "alice@example.com", subject: "Order Confirmed" })
|
|
→ Ok(())
|
|
[00:00.046] Console.print("Done!")
|
|
|
|
Result: Ok({ orderId: "ORD-123", total: 9.99 })
|
|
Effects: 4 Database ops, 1 Email, 2 Console
|
|
```
|
|
|
|
---
|
|
|
|
## 8. HTTP Server
|
|
|
|
### Current State: FUNCTIONAL
|
|
|
|
Built-in HTTP server effect with stdlib helpers.
|
|
|
|
**Implemented:**
|
|
- HttpServer effect: `listen`, `accept`, `respond`, `respondWithHeaders`, `stop`
|
|
- Http client effect: `get`, `post`, `put`, `delete`
|
|
- Stdlib helpers: Response builders, path matching, JSON utilities
|
|
- Examples: Basic server, router, REST API
|
|
|
|
**Code Locations:**
|
|
- `src/interpreter.rs` - tiny_http integration
|
|
- `stdlib/http.lux` (161 lines)
|
|
- `examples/http_server.lux`, `examples/http_api.lux`
|
|
|
|
### Comparison with Other Languages
|
|
|
|
| Feature | Express (Node) | Actix (Rust) | Phoenix (Elixir) | Gin (Go) | Lux |
|
|
|---------|----------------|--------------|------------------|----------|-----|
|
|
| Routing DSL | Yes | Yes | Yes | Yes | Basic |
|
|
| Middleware | Yes | Yes | Yes | Yes | Missing |
|
|
| WebSockets | Plugin | Yes | Yes | Plugin | Missing |
|
|
| Static files | Plugin | Yes | Yes | Yes | Missing |
|
|
| Templates | Plugin | Yes | Yes | Plugin | Missing |
|
|
| Sessions | Plugin | Yes | Yes | Plugin | Missing |
|
|
| CORS | Plugin | Yes | Plugin | Plugin | Missing |
|
|
| Rate limiting | Plugin | Plugin | Plugin | Plugin | Missing |
|
|
| Request validation | Plugin | Yes | Yes | Plugin | Missing |
|
|
| Async handling | Yes | Yes | Yes | Yes | Single-threaded |
|
|
|
|
### Is the Stdlib Too Big?
|
|
|
|
**Current stdlib size:** ~1,000 lines total
|
|
- `stdlib/http.lux`: 161 lines (16%)
|
|
- `stdlib/html.lux`: 384 lines (38%)
|
|
- `stdlib/testing.lux`: 192 lines (19%)
|
|
- `stdlib/browser.lux`: 89 lines (9%)
|
|
- `std/prelude.lux`: 38 lines (4%)
|
|
- Other: ~136 lines (14%)
|
|
|
|
**Analysis:** The stdlib is **lean and focused**. Compare:
|
|
- Go stdlib: ~1.5M lines
|
|
- Rust stdlib: ~500K lines
|
|
- Python stdlib: ~700K lines
|
|
|
|
Lux's ~1K lines is minimal. The question is whether HTTP/HTML belong in stdlib or should be external packages.
|
|
|
|
**Recommendation:** Keep HTTP/HTML in stdlib because:
|
|
1. Web is the primary use case
|
|
2. Effect integration requires compiler support
|
|
3. 550 lines is negligible
|
|
4. Ensures consistent patterns
|
|
|
|
### HTTP Server Roadmap
|
|
|
|
| Task | Priority | Effort |
|
|
|------|----------|--------|
|
|
| Middleware pattern | P1 | 1 week |
|
|
| Routing DSL | P1 | 1 week |
|
|
| Request validation | P1 | 1 week |
|
|
| Static file serving | P2 | 3 days |
|
|
| CORS handler | P2 | 2 days |
|
|
| WebSocket effect | P2 | 2 weeks |
|
|
| Sessions/cookies | P2 | 1 week |
|
|
| Rate limiting | P3 | 3 days |
|
|
| HTTP/2 support | P3 | 2 weeks |
|
|
|
|
### Middleware Design
|
|
|
|
```lux
|
|
// Middleware type
|
|
type Middleware = fn(Request, fn(Request): Response): Response
|
|
|
|
// Built-in middleware
|
|
fn logging(): Middleware = fn(req, next) => {
|
|
let start = Time.now()
|
|
let res = next(req)
|
|
let duration = Time.now() - start
|
|
Console.print("{req.method} {req.path} - {res.status} ({duration}ms)")
|
|
res
|
|
}
|
|
|
|
fn cors(origins: List<String>): Middleware = fn(req, next) => {
|
|
let res = next(req)
|
|
res with {
|
|
headers: res.headers ++ [
|
|
("Access-Control-Allow-Origin", String.join(origins, ", ")),
|
|
("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
|
|
]
|
|
}
|
|
}
|
|
|
|
// Usage
|
|
let app = compose([
|
|
logging(),
|
|
cors(["https://example.com"]),
|
|
authenticate(),
|
|
router
|
|
])
|
|
|
|
run HttpServer.listen(8080, app) with {}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Async & Concurrency
|
|
|
|
### Current State: SINGLE-THREADED
|
|
|
|
Lux currently has no async/concurrency primitives. The interpreter runs single-threaded, and HTTP requests are processed sequentially.
|
|
|
|
### Design Considerations
|
|
|
|
**Option A: Green Threads (Go-style)**
|
|
```lux
|
|
// Spawn lightweight threads
|
|
fn main(): Unit with {Spawn} = {
|
|
spawn { downloadFile("a.txt") }
|
|
spawn { downloadFile("b.txt") }
|
|
spawn { processData() }
|
|
}
|
|
```
|
|
|
|
**Option B: Async/Await (JS-style)**
|
|
```lux
|
|
// Explicit async functions
|
|
fn fetchData(): Async<Data> with {Http} = {
|
|
let a = await Http.get("api/a")
|
|
let b = await Http.get("api/b")
|
|
combine(a, b)
|
|
}
|
|
```
|
|
|
|
**Option C: Effect-based (Recommended)**
|
|
```lux
|
|
// Concurrency as an effect
|
|
effect Concurrent {
|
|
fn spawn<T>(f: fn(): T): Future<T>
|
|
fn await<T>(f: Future<T>): T
|
|
fn parallel<T>(tasks: List<fn(): T>): List<T>
|
|
}
|
|
|
|
fn main(): Unit with {Http, Concurrent} = {
|
|
let results = Concurrent.parallel([
|
|
fn() => Http.get("api/a"),
|
|
fn() => Http.get("api/b"),
|
|
fn() => Http.get("api/c")
|
|
])
|
|
// results: List<Response>
|
|
}
|
|
```
|
|
|
|
### Recommended Design: Effect-based Concurrency
|
|
|
|
**Why effects?**
|
|
1. Consistent with Lux's philosophy
|
|
2. Handlers can control scheduling
|
|
3. Testable (swap for sequential execution)
|
|
4. No colored functions (async/sync split)
|
|
|
|
**Primitives:**
|
|
|
|
```lux
|
|
effect Concurrent {
|
|
// Spawn a task
|
|
fn spawn<T>(f: fn(): T with {E}): Task<T> with {E}
|
|
|
|
// Wait for task completion
|
|
fn await<T>(task: Task<T>): T
|
|
|
|
// Run tasks in parallel, collect results
|
|
fn parallel<T>(tasks: List<fn(): T with {E}>): List<T> with {E}
|
|
|
|
// Race: return first to complete
|
|
fn race<T>(tasks: List<fn(): T with {E}>): T with {E}
|
|
|
|
// Yield execution
|
|
fn yield(): Unit
|
|
}
|
|
|
|
// Channel for communication
|
|
effect Channel<T> {
|
|
fn send(value: T): Unit
|
|
fn receive(): T
|
|
fn tryReceive(): Option<T>
|
|
}
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```lux
|
|
fn fetchAllUsers(): List<User> with {Http, Concurrent} = {
|
|
let userIds = [1, 2, 3, 4, 5]
|
|
|
|
// Fetch all in parallel
|
|
Concurrent.parallel(
|
|
List.map(userIds, fn(id) => fn() => {
|
|
let response = Http.get("/users/{id}")
|
|
Json.parse(response.body)
|
|
})
|
|
)
|
|
}
|
|
|
|
// Test with sequential execution
|
|
run fetchAllUsers() with {
|
|
Http = mockHttp,
|
|
Concurrent = sequentialHandler // No actual parallelism
|
|
}
|
|
```
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Effort |
|
|
|------|----------|--------|
|
|
| Concurrent effect definition | P1 | 1 week |
|
|
| Task/Future type | P1 | 1 week |
|
|
| Work-stealing scheduler | P1 | 3 weeks |
|
|
| Channel effect | P2 | 2 weeks |
|
|
| Select/race primitives | P2 | 1 week |
|
|
| Structured concurrency | P2 | 2 weeks |
|
|
| Cancellation tokens | P3 | 1 week |
|
|
|
|
---
|
|
|
|
## 10. Documentation
|
|
|
|
### Current State: GOOD FOUNDATION
|
|
|
|
Documentation exists but needs organization and expansion.
|
|
|
|
**Existing:**
|
|
- `docs/guide/` - 14 chapters (introduction through property testing)
|
|
- `docs/tutorials/` - Calculator, dependency injection, project ideas
|
|
- `docs/reference/` - Syntax reference
|
|
- `docs/*.md` - Design documents (C backend, evidence passing, etc.)
|
|
- `examples/` - 57 example files
|
|
|
|
### Documentation Structure Plan
|
|
|
|
```
|
|
docs/
|
|
├── guide/ # Learning path (beginner → advanced)
|
|
│ ├── 01-introduction.md
|
|
│ ├── 02-basic-types.md
|
|
│ ├── 03-functions.md
|
|
│ ├── 04-data-types.md
|
|
│ ├── 05-effects.md
|
|
│ ├── 06-handlers.md
|
|
│ ├── 07-modules.md
|
|
│ ├── 08-errors.md
|
|
│ ├── 09-stdlib.md
|
|
│ ├── 10-advanced.md
|
|
│ ├── 11-databases.md
|
|
│ ├── 12-behavioral-types.md
|
|
│ ├── 13-schema-evolution.md
|
|
│ └── 14-property-testing.md
|
|
│
|
|
├── reference/ # API reference (generated)
|
|
│ ├── syntax.md # Complete syntax reference
|
|
│ ├── types.md # Type system reference
|
|
│ ├── effects.md # Built-in effects
|
|
│ ├── stdlib/ # Stdlib API docs
|
|
│ │ ├── list.md
|
|
│ │ ├── string.md
|
|
│ │ ├── option.md
|
|
│ │ ├── result.md
|
|
│ │ ├── json.md
|
|
│ │ └── ...
|
|
│ └── cli.md # CLI reference
|
|
│
|
|
├── tutorials/ # Task-oriented guides
|
|
│ ├── web-api.md # Build a REST API
|
|
│ ├── cli-tool.md # Build a CLI application
|
|
│ ├── testing.md # Testing guide
|
|
│ ├── deployment.md # Deployment guide
|
|
│ └── migration.md # Migrating from X to Lux
|
|
│
|
|
├── cookbook/ # Copy-paste recipes
|
|
│ ├── http-patterns.md
|
|
│ ├── database-patterns.md
|
|
│ ├── error-handling.md
|
|
│ └── testing-patterns.md
|
|
│
|
|
└── internals/ # Implementation docs
|
|
├── architecture.md
|
|
├── type-system.md
|
|
├── codegen.md
|
|
└── contributing.md
|
|
```
|
|
|
|
### Website Integration
|
|
|
|
```
|
|
website/
|
|
├── index.html # Landing page
|
|
├── playground/ # Online REPL
|
|
│ └── index.html
|
|
├── docs/ # Rendered documentation
|
|
│ ├── guide/
|
|
│ ├── reference/
|
|
│ ├── tutorials/
|
|
│ └── cookbook/
|
|
├── examples/ # Interactive examples
|
|
│ └── index.html
|
|
└── blog/ # News and updates
|
|
└── index.html
|
|
```
|
|
|
|
### Roadmap
|
|
|
|
| Task | Priority | Effort |
|
|
|------|----------|--------|
|
|
| Auto-generate stdlib API docs | P1 | 2 weeks |
|
|
| Build REST API tutorial | P1 | 1 week |
|
|
| Build CLI tool tutorial | P1 | 3 days |
|
|
| Create cookbook section | P1 | 1 week |
|
|
| Online playground | P2 | 3 weeks |
|
|
| Interactive examples | P2 | 2 weeks |
|
|
| Video tutorials | P3 | 4 weeks |
|
|
|
|
### API Documentation Generator
|
|
|
|
```lux
|
|
// Source file with doc comments
|
|
/// Transforms each element of a list using the given function.
|
|
///
|
|
/// ## Example
|
|
/// ```lux
|
|
/// List.map([1, 2, 3], fn(x) => x * 2)
|
|
/// // => [2, 4, 6]
|
|
/// ```
|
|
///
|
|
/// ## Complexity
|
|
/// O(n) where n is the length of the list.
|
|
pub fn map<T, U>(list: List<T>, f: fn(T): U): List<U> = ...
|
|
```
|
|
|
|
Generated output:
|
|
```markdown
|
|
### List.map
|
|
|
|
```lux
|
|
fn map<T, U>(list: List<T>, f: fn(T): U): List<U>
|
|
```
|
|
|
|
Transforms each element of a list using the given function.
|
|
|
|
**Example:**
|
|
```lux
|
|
List.map([1, 2, 3], fn(x) => x * 2)
|
|
// => [2, 4, 6]
|
|
```
|
|
|
|
**Complexity:** O(n) where n is the length of the list.
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Error Messages
|
|
|
|
### Current State: GOOD
|
|
|
|
Elm-inspired diagnostic system with categorized errors and suggestions.
|
|
|
|
**Implemented:**
|
|
- 26 error codes (E01xx parse, E02xx type, E03xx name, etc.)
|
|
- Context lines with highlighting
|
|
- Levenshtein-based suggestions ("did you mean?")
|
|
- Color support with fallback
|
|
- Type diff visualization
|
|
|
|
**Code Location:** `src/diagnostics.rs` (1,033 lines)
|
|
|
|
### Current Error Quality
|
|
|
|
**Good:**
|
|
```
|
|
── TYPE MISMATCH ─────────────────────────────────── src/main.lux
|
|
|
|
14│ let total = calculateTotal(order.quantity)
|
|
^^^^^^^^^^^^^^
|
|
|
|
This function expects an `Int` but got a `String`.
|
|
|
|
Hint: Maybe parse the string first?
|
|
let qty = Int.parse(order.quantity)?
|
|
```
|
|
|
|
**Needs Improvement:**
|
|
- LSP only uses message field (not codes, hints, related spans)
|
|
- Some errors are generic ("Type error")
|
|
- No example-based hints
|
|
|
|
### Error Message Roadmap
|
|
|
|
| Task | Priority | Effort |
|
|
|------|----------|--------|
|
|
| LSP rich diagnostic support | P1 | 1 week |
|
|
| Example-based hints | P1 | 2 weeks |
|
|
| Effect mismatch explanations | P1 | 1 week |
|
|
| Missing pattern suggestions | P2 | 3 days |
|
|
| Error code documentation | P2 | 1 week |
|
|
| Beginner-friendly mode | P3 | 1 week |
|
|
| Localization infrastructure | P3 | 2 weeks |
|
|
|
|
### Enhanced Error Examples
|
|
|
|
**Effect mismatch (improved):**
|
|
```
|
|
── MISSING EFFECT ─────────────────────────────────── src/api.lux
|
|
|
|
23│ fn getUser(id: Int): User = {
|
|
24│ Database.query("SELECT * FROM users WHERE id = ?", id)
|
|
^^^^^^^^
|
|
25│ }
|
|
|
|
The function `getUser` uses the `Database` effect but doesn't declare it.
|
|
|
|
Add `with {Database}` to the function signature:
|
|
|
|
fn getUser(id: Int): User with {Database} = {
|
|
Database.query("SELECT * FROM users WHERE id = ?", id)
|
|
}
|
|
|
|
Or, if this should be a pure function, consider passing the user as
|
|
a parameter instead of querying the database.
|
|
|
|
See: https://lux-lang.dev/errors/E0401
|
|
```
|
|
|
|
**Pattern match (improved):**
|
|
```
|
|
── INEXHAUSTIVE PATTERN ──────────────────────────── src/parser.lux
|
|
|
|
45│ match token {
|
|
46│ Token.Number(n) => Expr.Lit(n),
|
|
47│ Token.Ident(s) => Expr.Var(s)
|
|
48│ }
|
|
|
|
This match doesn't cover all cases. Missing patterns:
|
|
|
|
Token.String(_)
|
|
Token.Operator(_)
|
|
Token.Eof
|
|
|
|
Add the missing cases:
|
|
|
|
match token {
|
|
Token.Number(n) => Expr.Lit(n),
|
|
Token.Ident(s) => Expr.Var(s),
|
|
Token.String(s) => ...,
|
|
Token.Operator(op) => ...,
|
|
Token.Eof => ...
|
|
}
|
|
|
|
Or use a catch-all pattern if appropriate:
|
|
|
|
_ => Expr.Error("unexpected token")
|
|
|
|
See: https://lux-lang.dev/errors/E0501
|
|
```
|
|
|
|
---
|
|
|
|
## Implementation Priority Matrix
|
|
|
|
### Phase 1: Foundation (Next 3 months)
|
|
|
|
| Area | Task | Priority | Effort |
|
|
|------|------|----------|--------|
|
|
| Package | Lock file + version resolution | P0 | 3 weeks |
|
|
| LSP | Symbol table architecture | P0 | 2 weeks |
|
|
| C Backend | Pure function memoization | P1 | 2 weeks |
|
|
| HTTP | Middleware + routing DSL | P1 | 2 weeks |
|
|
| Docs | API documentation generator | P1 | 2 weeks |
|
|
|
|
### Phase 2: Polish (Months 4-6)
|
|
|
|
| Area | Task | Priority | Effort |
|
|
|------|------|----------|--------|
|
|
| Package | Registry server | P1 | 3 weeks |
|
|
| LSP | References + rename | P1 | 2 weeks |
|
|
| REPL | Step evaluation + effect viz | P2 | 4 weeks |
|
|
| Async | Concurrent effect | P1 | 5 weeks |
|
|
| Errors | Rich LSP diagnostics | P1 | 1 week |
|
|
|
|
### Phase 3: Advanced (Months 7-12)
|
|
|
|
| Area | Task | Priority | Effort |
|
|
|------|------|----------|--------|
|
|
| C Backend | Full behavioral optimizations | P2 | 8 weeks |
|
|
| Schema | JSON codec generation | P1 | 3 weeks |
|
|
| HTTP | WebSocket effect | P2 | 2 weeks |
|
|
| Docs | Online playground | P2 | 3 weeks |
|
|
| Modules | Workspaces | P3 | 2 weeks |
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
Lux has a **solid foundation** with most core features complete:
|
|
|
|
| Area | Status | Next Steps |
|
|
|------|--------|------------|
|
|
| Modules | Complete | Lock files, registry |
|
|
| Behavioral Types | Complete | Optimization integration |
|
|
| Schema Evolution | Complete | Codec generation |
|
|
| C Backend | Production-ready | Behavioral optimizations |
|
|
| LSP | Basic | Symbol table rewrite |
|
|
| Package Manager | Functional | Version resolution |
|
|
| REPL | Functional | Effect visualization |
|
|
| HTTP Server | Functional | Middleware, routing |
|
|
| Async/Concurrency | Missing | Effect-based design |
|
|
| Documentation | Good | API generator, tutorials |
|
|
| Error Messages | Good | LSP integration |
|
|
|
|
The highest-impact work is:
|
|
1. **Package manager version resolution** - Essential for real projects
|
|
2. **LSP symbol table** - Unlocks modern IDE experience
|
|
3. **Behavioral type optimizations** - Unique value proposition
|
|
4. **Concurrent effect** - Required for production web services
|