# Lux Language Overview ## What is Lux? Lux is a statically-typed functional programming language with **algebraic effects** as a first-class feature. It makes side effects explicit, trackable, and testable. ## What Can You Do With It? ### Currently Working ```lux // Functions with type inference fn factorial(n: Int): Int = if n <= 1 then 1 else n * factorial(n - 1) // Higher-order functions fn apply(f: fn(Int): Int, x: Int): Int = f(x) fn double(x: Int): Int = x * 2 let result = apply(double, 21) // 42 // Lambdas and closures let add = fn(a: Int, b: Int): Int => a + b let addFive = fn(x: Int): Int => add(5, x) // Pattern matching fn describe(n: Int): String = match n { 0 => "zero", 1 => "one", _ => "many" } // Records let person = { name: "Alice", age: 30 } let age = person.age // Tuples let point = (10, 20) // Lists let numbers = [1, 2, 3, 4, 5] // Pipe operator let result = 5 |> double |> addOne // (5 * 2) + 1 = 11 // Built-in effects (Console, Fail) Console.print("Hello, world!") // Custom effects effect Logger { fn log(level: String, msg: String): Unit } // Effect handlers handler consoleLogger: Logger { fn log(level, msg) = Console.print("[" + level + "] " + msg) } // Running with handlers fn greet(name: String): Unit with {Logger} = Logger.log("info", "Hello, " + name) run greet("Alice") with { Logger = consoleLogger } ``` ### Standard Library (Built-in) ```lux // List operations List.map([1, 2, 3], fn(x: Int): Int => x * 2) // [2, 4, 6] List.filter([1, 2, 3, 4], fn(x: Int): Bool => x > 2) // [3, 4] List.fold([1, 2, 3], 0, fn(acc: Int, x: Int): Int => acc + x) // 6 List.head([1, 2, 3]) // Some(1) List.tail([1, 2, 3]) // Some([2, 3]) List.concat([1, 2], [3]) // [1, 2, 3] List.reverse([1, 2, 3]) // [3, 2, 1] List.length([1, 2, 3]) // 3 List.get([1, 2, 3], 0) // Some(1) List.range(0, 5) // [0, 1, 2, 3, 4] // String operations String.split("a,b,c", ",") // ["a", "b", "c"] String.join(["a", "b"], "-") // "a-b" String.trim(" hello ") // "hello" String.contains("hello", "ell") // true String.replace("hi", "i", "ey") // "hey" String.length("hello") // 5 String.chars("hi") // ['h', 'i'] String.lines("a\nb") // ["a", "b"] // Option operations let x = Some(42) let y = None Option.map(x, fn(n: Int): Int => n * 2) // Some(84) Option.flatMap(x, fn(n: Int): Option => Some(n + 1)) // Some(43) Option.getOrElse(y, 0) // 0 Option.isSome(x) // true Option.isNone(y) // true // Result operations let ok = Ok(42) let err = Err("failed") Result.map(ok, fn(n: Int): Int => n * 2) // Ok(84) Result.getOrElse(err, 0) // 0 Result.isOk(ok) // true Result.isErr(err) // true // Utility functions print("Hello") // prints to stdout toString(42) // "42" typeOf([1, 2, 3]) // "List" ``` ### Planned (Not Yet Implemented) - **Schema Evolution**: Versioned types with automatic migrations - **Behavioral Types**: Properties like `is pure`, `is idempotent` - **Modules/Imports**: Code organization - **Compilation**: Currently interpreter-only --- ## Primary Use Cases ### 1. Learning Effect Systems Lux is an excellent educational tool for understanding algebraic effects without the complexity of Haskell's monad transformers or the academic syntax of languages like Koka. ### 2. Testable Application Code Effects make dependencies explicit. Swap handlers for testing: ```lux // Production run app() with { Database = postgres, Http = realHttp } // Testing run app() with { Database = mockDb, Http = mockHttp } ``` ### 3. Domain Modeling Explicit effects document what code can do: ```lux fn processOrder(order: Order): Receipt with {Database, Email, Logger} // ^ The signature tells you exactly what side effects this function performs ``` ### 4. Prototyping Quick iteration with type inference and a REPL. --- ## Pros and Cons ### Pros | Advantage | Description | |-----------|-------------| | **Explicit Effects** | Function signatures show what side effects are possible | | **Testability** | Swap effect handlers for mocking—no dependency injection frameworks | | **Type Safety** | Static types catch errors at compile time | | **Type Inference** | Write less type annotations, compiler figures it out | | **Clean Syntax** | ML-family inspired, minimal boilerplate | | **Pattern Matching** | Destructure data elegantly | | **Immutable by Default** | Easier to reason about | | **REPL** | Interactive development | ### Cons | Limitation | Description | |------------|-------------| | **Interpreter Only** | No compilation to native/JS/WASM yet | | **No Modules** | Can't split code across files | | **Limited IO** | Only Console built-in, no file/network | | **No Generics** | Polymorphic functions not fully implemented | | **New Paradigm** | Effects require learning new concepts | | **Small Ecosystem** | No packages, libraries, or community | | **Early Stage** | Bugs likely, features incomplete | --- ## Complexity Assessment ### Conceptual Complexity | Concept | Difficulty | Notes | |---------|------------|-------| | Basic syntax | Easy | Similar to other ML-family languages | | Functions | Easy | Standard functional style | | Pattern matching | Easy | If you know any FP language | | Type system | Medium | Hindley-Milner inference helps | | Effects | Medium | New concept, but simpler than monads | | Handlers | Medium | Requires understanding of continuations | ### Comparison to Other Languages | Language | Complexity | Comparison to Lux | |----------|------------|-------------------| | Python | Simpler | No types, no effect tracking | | TypeScript | Similar | Lux has effects, TS has larger ecosystem | | Elm | Similar | Both pure FP, Lux has general effects | | Haskell | More Complex | Monads harder than algebraic effects | | Koka | Similar | Koka more academic, Lux more practical syntax | | Rust | More Complex | Ownership adds significant complexity | ### Learning Curve **Beginner** (1-2 hours): - Basic expressions, functions, let bindings - If/else, pattern matching - REPL usage **Intermediate** (1-2 days): - Custom types and records - Higher-order functions - Built-in effects (Console) **Advanced** (1 week): - Custom effect definitions - Effect handlers - Understanding when to use effects vs. regular functions --- ## When to Use Lux ### Good Fit - Learning algebraic effects - Prototyping with explicit effect tracking - Small tools where testability matters - Teaching functional programming concepts ### Not a Good Fit (Yet) - Production applications (too early) - Performance-critical code (interpreter) - Large codebases (no modules) - Web development (no JS compilation) - Systems programming (no low-level control) --- ## Example Session ``` $ cargo run Lux v0.1.0 Type :help for help, :quit to exit lux> let x = 42 lux> x * 2 84 lux> fn greet(name: String): Unit with {Console} = Console.print("Hello, " + name) lux> greet("World") Hello, World () lux> let nums = [1, 2, 3] lux> nums [1, 2, 3] lux> :quit ``` --- ## Architecture ``` Source Code │ ▼ ┌─────────┐ │ Lexer │ → Tokens └─────────┘ │ ▼ ┌─────────┐ │ Parser │ → AST └─────────┘ │ ▼ ┌─────────────┐ │ Type Checker│ → Typed AST + Effect Tracking └─────────────┘ │ ▼ ┌─────────────┐ │ Interpreter │ → Values + Effect Handling └─────────────┘ ``` --- ## Future Roadmap 1. **Standard Library** - List, String, Option utilities 2. **Module System** - Import/export, namespaces 3. **JavaScript Backend** - Run in browsers 4. **Schema Evolution** - Versioned types 5. **Behavioral Types** - is pure, is idempotent 6. **LSP Server** - IDE support 7. **Package Manager** - Share code