Based on analysis of what makes developers love languages: - P0: Elm-quality errors, HTTP framework, PostgreSQL driver - P1: Property-based testing, better REPL, benchmarks - P2: LSP improvements, docs generator, schema tools - P3: Effect visualization, package registry, production hardening Focus on high-impact features that showcase Lux's unique advantages. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8.8 KiB
Lux Priority Implementation Plan
Based on analysis of what makes developers love languages
Core Insight
From studying successful languages (Rust, Elm, Go, Gleam), the pattern is clear:
- Elm has 0% runtime exceptions and legendary error messages → developers evangelize it
- Rust has "if it compiles, it works" confidence → 72% admiration
- Go has simplicity and fast feedback → massive adoption
- Gleam has type safety on BEAM → 70% admiration (2nd highest)
Lux's unique pitch: Effects you can see. Tests you can trust. No mocks needed.
Phase 1: Make Developers Smile (Highest Impact)
1.1 Elm-Quality Error Messages
Why: Elm's error messages are the #1 reason people recommend it. This is free marketing.
Current state: Basic errors with location Target state: Conversational, helpful, with suggestions
Current:
Type error at 5:12: Cannot unify Int with String
Target:
── TYPE MISMATCH ─────────────────────────── src/main.lux
The `age` field expects an Int, but I found a String:
5│ age: "twenty-five"
^^^^^^^^^^^^
Hint: Did you mean to use String.parseInt?
age: String.parseInt("twenty-five") |> Option.getOrElse(0)
Implementation:
- Add error code catalog (E001, E002, etc.)
- "Did you mean?" suggestions using Levenshtein distance
- Show expected vs actual with visual diff
- Context-aware hints based on error type
Effort: 2-3 weeks Impact: HIGH - This is what people tweet about
1.2 HTTP Framework (Routing + Middleware)
Why: Web services are the most common use case. Without this, Lux is a toy.
// Target API
let app = Router.new()
|> Router.get("/users", listUsers)
|> Router.get("/users/:id", getUser)
|> Router.post("/users", createUser)
|> Router.use(loggerMiddleware)
|> Router.use(authMiddleware)
fn main(): Unit with {HttpServer} =
HttpServer.serve(app, 3000)
Implementation:
- Path pattern matching with params
- Middleware composition
- Request/Response types
- JSON body parsing integration
Effort: 2 weeks Impact: HIGH - Enables real projects
1.3 PostgreSQL Driver
Why: SQLite is nice for demos, real apps need Postgres/MySQL.
effect Postgres {
fn connect(url: String): Connection
fn query(conn: Connection, sql: String, params: List<Value>): List<Row>
fn execute(conn: Connection, sql: String, params: List<Value>): Int
fn transaction<T>(conn: Connection, f: fn(): T with {Postgres}): T
}
Implementation:
- Native Rust driver (tokio-postgres)
- Connection pooling
- Parameterized queries (SQL injection prevention)
- Transaction support
Effort: 2 weeks Impact: HIGH - Enables production backends
Phase 2: Showcase Unique Features
2.1 Property-Based Testing Framework
Why: This showcases behavioral types - Lux's most unique feature.
test "reverse is involutive" =
forAll(listOf(int), fn(xs) =>
List.reverse(List.reverse(xs)) == xs
) is pure is total // Compiler verifies!
test "sort produces sorted output" =
forAll(listOf(int), fn(xs) =>
let sorted = List.sort(xs)
isSorted(sorted) && sameElements(xs, sorted)
) where result is idempotent // Compiler verifies!
Implementation:
- Generator combinators (int, string, listOf, oneOf, etc.)
- Shrinking for minimal failing cases
- Integration with behavioral type checker
- Nice failure output
Effort: 2 weeks Impact: HIGH - Unique selling point
2.2 Schema Evolution Showcase
Why: This is unique to Lux. Need a compelling demo.
Build: Database migration tool that generates SQL from Lux types
type User @v1 = { name: String, email: String }
type User @v2 = { name: String, email: String, age: Option<Int> }
from @v1 = fn(u) => { ...u, age: None }
// Tool generates:
// ALTER TABLE users ADD COLUMN age INTEGER;
Effort: 1 week Impact: MEDIUM - Differentiator for data teams
2.3 Effect Visualization
Why: Make the invisible visible. Show effect flow in code.
lux visualize src/main.lux
processOrder: Order -> Receipt
├── Database.query (line 12)
│ └── SQL: "SELECT * FROM inventory"
├── PaymentGateway.charge (line 18)
│ └── Amount: order.total
└── Email.send (line 25)
└── To: order.customer.email
Effort: 1 week Impact: MEDIUM - Educational, impressive in demos
Phase 3: Developer Experience Polish
3.1 Better REPL
Why: First impression matters. REPL is how people try the language.
Add:
- Syntax highlighting
- Multi-line editing
- Tab completion for modules
:doccommand for documentation:browse Moduleto list exports- Pretty-printed output
Effort: 1 week Impact: MEDIUM
3.2 LSP Improvements
Why: IDE experience is expected in 2025.
Add:
- Inlay hints (show inferred types)
- Code actions (import suggestions, fix suggestions)
- Rename symbol
- Find all references
- Semantic highlighting
Effort: 2 weeks Impact: MEDIUM
3.3 Documentation Generator
Why: Rust's docs.rs is beloved. Good docs = adoption.
/// Calculate the factorial of a number.
///
/// # Examples
/// ```
/// factorial(5) // => 120
/// ```
///
/// # Properties
/// - factorial(n) is pure
/// - factorial(n) is total for n >= 0
fn factorial(n: Int): Int is pure is total = ...
Effort: 1 week Impact: MEDIUM
Phase 4: Performance & Production
4.1 Performance Benchmarks
Why: Need to prove Lux is fast. Numbers matter.
Targets:
| Benchmark | Target | Comparison |
|---|---|---|
| Fibonacci(40) | < 1s | Rust: 0.3s |
| HTTP req/sec | > 50k | Go: 100k |
| JSON parse 1MB | < 50ms | Node: 30ms |
Effort: 1 week Impact: MEDIUM - Removes adoption blocker
4.2 Production Hardening
Why: Memory leaks and crashes kill adoption.
Add:
- Memory leak detection in debug mode
- Graceful shutdown handling
- Signal handling (SIGTERM, SIGINT)
- Structured logging
Effort: 2 weeks Impact: MEDIUM
Phase 5: Ecosystem Growth
5.1 Package Registry
Why: Central place to share code.
- Host at packages.lux-lang.org
lux pkg publishlux pkg search- Version resolution
Effort: 2 weeks Impact: HIGH long-term
5.2 Starter Templates
Why: Reduce friction for new projects.
lux new my-api --template web-api
lux new my-cli --template cli-tool
lux new my-lib --template library
Effort: 1 week Impact: LOW-MEDIUM
Implementation Order (Bang for Buck)
| Priority | Feature | Effort | Impact | Why First |
|---|---|---|---|---|
| P0 | Elm-quality errors | 2-3 weeks | HIGH | Free marketing, retention |
| P0 | HTTP framework | 2 weeks | HIGH | Enables real projects |
| P0 | PostgreSQL driver | 2 weeks | HIGH | Production database |
| P1 | Property testing | 2 weeks | HIGH | Unique selling point |
| P1 | Better REPL | 1 week | MEDIUM | First impression |
| P1 | Performance benchmarks | 1 week | MEDIUM | Removes doubt |
| P2 | LSP improvements | 2 weeks | MEDIUM | Developer experience |
| P2 | Documentation generator | 1 week | MEDIUM | Ecosystem |
| P2 | Schema evolution tool | 1 week | MEDIUM | Differentiator |
| P3 | Effect visualization | 1 week | MEDIUM | Demos |
| P3 | Package registry | 2 weeks | HIGH | Long-term ecosystem |
| P3 | Production hardening | 2 weeks | MEDIUM | Enterprise readiness |
Success Metrics
Short-term (3 months)
- 10 example projects building without issues
- Error messages rated "helpful" by 80% of users
- HTTP "hello world" benchmark > 30k req/sec
- 5 external contributors
Medium-term (6 months)
- 1000 GitHub stars
- 50 packages on registry
- 3 production users
- 1 conference talk
Long-term (1 year)
- Self-hosted compiler
- 100 packages
- 10 production users
- Featured in "State of Developer Ecosystem" survey
What NOT to Build (Yet)
| Feature | Why Skip |
|---|---|
| WASM backend | JS backend covers browser use case |
| Mobile targets | Small market, high effort |
| GUI framework | Web handles most UI needs |
| AI/ML libraries | Python dominates, wrong battle |
| Distributed systems | Need core stability first |
| Advanced optimizations | Correctness before speed |
The Pitch After Phase 1
Lux: A functional language where the compiler tells you exactly what your code does.
- See effects in signatures:
fn save(user: User): Unit with {Database, Email}- Test without mocks: Just swap the handler. No DI framework needed.
- Evolve your schemas: Types track versions. Migrations are code.
- Compiler catches more: Pure, total, idempotent - verified, not hoped.
Effects you can see. Tests you can trust.