- behavioral.lux: use verifiable behavioral patterns (abs for idempotent)
- behavioral_types.lux: use simpler verified patterns, proper main invocation
- schema_evolution.lux: simplify to runtime schema ops, fix record access
- jit_test.lux: add proper main function with console output
All examples now parse and run correctly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix string interpolation issues: escape curly braces with \{ and \}
since unescaped { triggers string interpolation
- Fix effectful function invocation: use "let _ = run main() with {}"
instead of bare "main()" calls
- Use inline record types instead of type aliases (structural typing)
- Fix flake.nix to show build progress instead of suppressing output
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Build release binary when entering nix shell
- Add target/release to PATH automatically
- Update shell help to show lux commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Schema Evolution:
- Preserve version info in type resolution (Type::Versioned)
- Track versioned type declarations in typechecker
- Detect version mismatches at compile time (@v1 vs @v2 errors)
- Support @v2+ (at least) and @latest version constraints
- Store migrations for future auto-migration support
- Fix let bindings to preserve declared type annotations
HTTP Server Effect:
- Add HttpServer effect with listen, accept, respond, respondWithHeaders, stop
- Implement blocking request handling via tiny_http
- Request record includes method, path, body, headers
- Add http_server.lux example with routing via pattern matching
- Add type-checking test for HttpServer effect
Tests: 222 passing (up from 217)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add `lux compile <file>` command that compiles and runs Lux code using
the Cranelift JIT compiler. Includes --benchmark flag for timing.
- Add compile_file() function in main.rs
- Add jit_test.lux example with fib(30) + factorial(10)
- Update VISION.md status
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Many features were documented as "missing" or "planned" but are actually
working: generics, string interpolation, File/HTTP/Random/Time effects,
JSON parsing, module system, and JIT CLI integration.
Updated IMPLEMENTATION_PLAN.md, OVERVIEW.md with accurate status.
Added ROADMAP.md (use-case-targeted) and LANGUAGE_COMPARISON.md.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add String.fromChar function to convert Char to String
- Create four stress test projects demonstrating Lux features:
- json-parser: recursive descent parsing with Char handling
- markdown-converter: string manipulation and ADTs
- todo-app: list operations and pattern matching
- mini-interpreter: AST evaluation and environments
- Add comprehensive testing documentation (docs/testing.md)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Neovim improvements:
- Add tree-sitter text objects for functions, types, blocks
- Add folding support
- Enhanced REPL integration (toggle, send line/selection)
- New commands: LuxCheck, LuxReplToggle, LuxSend
- Better keybindings with localleader
VS Code extension:
- Full syntax highlighting with TextMate grammar
- LSP client integration
- 20+ snippets for common patterns
- Commands: run, format, check, REPL
- Keybindings and context menu
Fixes:
- Fix all cargo warnings with #[allow(dead_code)] annotations
- Clean up unused variables
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show 2 lines of context before and after errors (dimmed)
- Fix guessing_game.lux to be non-interactive for testing
- Use binary search simulation to demonstrate game logic
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add readLine and readInt operations to the Console effect for interactive
input. Create a number guessing game project demonstrating ADTs, pattern
matching, effects, and game state management.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a JIT compiler using Cranelift that compiles Lux functions to native
machine code. Achieves ~160x speedup over the tree-walking interpreter
(fib(30): 11.59ms JIT vs 1.87s interpreter).
Supports: arithmetic, comparisons, conditionals, let bindings, function
calls, and recursion. Compile time overhead is minimal (~500µs).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Http effect for making HTTP requests:
- Http.get(url) - GET request
- Http.post(url, body) - POST with string body
- Http.postJson(url, json) - POST with JSON body
- Http.put(url, body) - PUT request
- Http.delete(url) - DELETE request
Returns Result<HttpResponse, String> where HttpResponse contains
status code, body, and headers.
Includes reqwest dependency with blocking client, OpenSSL support
in flake.nix, and example at examples/http.lux demonstrating
API requests with JSON parsing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive JSON support via the Json module:
- Parse JSON strings with Json.parse() returning Result<Json, String>
- Stringify with Json.stringify() and Json.prettyPrint()
- Extract values with Json.get(), getIndex(), asString(), asInt(), etc.
- Build JSON with constructors: Json.null(), bool(), int(), string(), array(), object()
- Query with Json.isNull() and Json.keys()
Includes example at examples/json.lux demonstrating building, parsing,
and extracting JSON data with file I/O integration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds two essential effects that enable Lux to interact with the system:
File effect:
- read(path) - Read file contents as string
- write(path, content) - Write string to file
- append(path, content) - Append to file
- exists(path) - Check if file/directory exists
- delete(path) - Delete a file
- readDir(path) - List directory contents
- isDir(path) - Check if path is directory
- mkdir(path) - Create directory (including parents)
Process effect:
- exec(cmd) - Run shell command, return stdout
- execStatus(cmd) - Run command, return exit code
- env(name) - Get environment variable (returns Option)
- args() - Get command line arguments
- exit(code) - Exit program with code
- cwd() - Get current working directory
- setCwd(path) - Change working directory
Also fixes formatter bug with empty handler blocks in `run ... with {}`.
These effects make Lux capable of writing real CLI tools and scripts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Math module: abs, min, max, sqrt, pow, floor, ceil, round
- Add List functions: isEmpty, find, any, all, take, drop
- Add String functions: startsWith, endsWith, toUpper, toLower, substring
- Add 12 tests for new standard library functions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Schema module with functions for creating and migrating versioned
values. This provides the runtime foundation for schema evolution.
Schema module functions:
- Schema.versioned(typeName, version, value) - create versioned value
- Schema.migrate(value, targetVersion) - migrate to new version
- Schema.getVersion(value) - get version number
Changes:
- Add Versioned, Migrate, GetVersion builtins to interpreter
- Add Schema module to global environment
- Add Schema module type to type environment
- Add 4 tests for schema operations
- Add examples/versioning.lux demonstrating usage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for the `resume(value)` expression in effect handler
bodies. When resume is called, the value becomes the return value
of the effect operation, allowing handlers to provide values back
to the calling code.
Implementation:
- Add Resume(Value) variant to EvalResult
- Add in_handler_depth tracking to Interpreter
- Update Expr::Resume evaluation to return Resume when in handler
- Handle Resume results in handle_effect to use as return value
- Add 2 tests for resumable handlers
Example usage:
```lux
handler prettyLogger: Logger {
fn log(level, msg) = {
Console.print("[" + level + "] " + msg)
resume(()) // Return Unit to the call site
}
}
```
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Random and Time effects for random number generation and
time-based operations. These effects can be used in any
effectful code block.
Random effect operations:
- Random.int(min, max) - random integer in range [min, max]
- Random.float() - random float in range [0.0, 1.0)
- Random.bool() - random boolean
Time effect operations:
- Time.now() - current Unix timestamp in milliseconds
- Time.sleep(ms) - sleep for specified milliseconds
Changes:
- Add rand crate dependency
- Add Random and Time effect definitions to types.rs
- Add effects to built-in effects list in typechecker
- Implement effect handlers in interpreter
- Add 4 new tests for Random and Time effects
- Add examples/random.lux demonstrating usage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add runtime support for the State, Reader, and Fail effects that
were already defined in the type system. These effects can now be
used in effectful code blocks.
Changes:
- Add builtin_state and builtin_reader fields to Interpreter
- Implement State.get and State.put in handle_builtin_effect
- Implement Reader.ask in handle_builtin_effect
- Add Reader effect definition to types.rs
- Add Reader to built-in effects list in typechecker
- Add set_state/get_state/set_reader/get_reader methods
- Add 6 new tests for built-in effects
- Add examples/builtin_effects.lux demonstrating usage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Levenshtein distance-based similarity matching for undefined
variables, unknown types, unknown effects, and unknown traits.
When a name is not found, the error now suggests similar names
within edit distance 2.
Changes:
- Add levenshtein_distance() function to diagnostics module
- Add find_similar_names() and format_did_you_mean() helpers
- Update typechecker to suggest similar names for:
- Undefined variables
- Unknown types
- Unknown effects
- Unknown traits
- Add 17 new tests for similarity matching
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add full support for user-defined generic types and functions:
- Add type_params field to TypeChecker to track type parameters in scope
- Update resolve_type() to resolve type parameters to their bound variables
- Update function_type() to bind type parameters and return polymorphic TypeScheme
- Update type declaration handling for generic ADTs (e.g., Pair<A, B>)
Generic functions and types now work:
fn identity<T>(x: T): T = x
type Pair<A, B> = | MkPair(A, B)
fn first<A, B>(p: Pair<A, B>): A = ...
Add examples/generics.lux demonstrating:
- Generic identity function
- Generic Pair type with first/second accessors
- Generic mapOption function
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add string concatenation support to + operator in typechecker
- Register ADT constructors in both type environment and interpreter
- Bind handlers as values so they can be referenced in run...with
- Fix effect checking to use subset instead of exact match
- Add built-in effects (Console, Fail, State) to run block contexts
- Suppress dead code warnings in diagnostics, modules, parser
Update all example programs with:
- Expected output documented in comments
- Proper run...with statements to execute code
Add new example programs:
- behavioral.lux: pure, idempotent, deterministic, commutative functions
- pipelines.lux: pipe operator demonstrations
- statemachine.lux: ADT-based state machines
- tailcall.lux: tail call optimization examples
- traits.lux: type classes and pattern matching
Add documentation:
- docs/IMPLEMENTATION_PLAN.md: feature roadmap and status
- docs/PERFORMANCE_AND_TRADEOFFS.md: performance analysis
Add benchmarks for performance testing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a Language Server Protocol (LSP) server to enable IDE integration.
The server provides:
- Real-time diagnostics (parse errors and type errors)
- Basic hover information
- Keyword completions (fn, let, if, match, type, effect, etc.)
- Go-to-definition stub (ready for implementation)
Usage: lux --lsp
The LSP server can be integrated with any editor that supports LSP,
including VS Code, Neovim, Emacs, and others.
Dependencies added:
- lsp-server 0.7
- lsp-types 0.94
- serde with derive feature
- serde_json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for doc comments (/// syntax) that can be attached to
declarations for documentation purposes. The implementation:
- Adds DocComment token kind to lexer
- Recognizes /// as doc comment syntax (distinct from // regular comments)
- Parses consecutive doc comments and combines them into a single string
- Adds doc field to FunctionDecl, TypeDecl, LetDecl, EffectDecl, TraitDecl
- Passes doc comments through parser to declarations
- Multiple consecutive doc comment lines are joined with newlines
This enables documentation extraction and could be used for generating
API docs, IDE hover information, and REPL help.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add automatic effect inference for functions and lambdas that don't
explicitly declare their effects. The implementation:
- Tracks inferred effects during type checking via `inferred_effects`
- Uses `inferring_effects` flag to switch between validation and inference
- Functions without explicit `with {Effects}` have their effects inferred
- Lambda expressions also support effect inference
- When effects are explicitly declared, validates that inferred effects
are a subset of declared effects
- Pure functions are checked against both declared and inferred effects
This makes the effect system more ergonomic by not requiring explicit
effect annotations for every function while still maintaining safety.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for type classes (traits) with full parsing, type checking, and
validation. The implementation includes:
- Trait declarations: trait Show { fn show(x: T): String }
- Trait implementations: impl Show for Int { fn show(x: Int) = ... }
- Super traits: trait Ord: Eq { ... }
- Trait constraints in where clauses: where T: Show + Eq
- Type parameters on traits: trait Functor<F> { ... }
- Default method implementations
- Validation of required method implementations
This provides a foundation for ad-hoc polymorphism and enables
more expressive type-safe abstractions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add trampoline-based tail call optimization to prevent stack overflow
on deeply recursive tail-recursive functions. The implementation:
- Extends EvalResult with TailCall variant for deferred evaluation
- Adds trampoline loop in eval_expr() to handle tail calls iteratively
- Propagates tail position through If, Let, Match, and Block expressions
- Updates all builtin callbacks to handle tail calls via eval_call_to_value
- Includes tests for deep recursion (10000+ calls) and accumulator patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
REPL improvements:
- Tab completion for keywords, commands, and user definitions
- Persistent history saved to ~/.lux_history
- Better line editing with Emacs keybindings
- Ctrl-C to cancel input, Ctrl-D to exit
- History search with Ctrl-R
New commands:
- :info <name> - Show type information for a binding
- :env - List user-defined bindings with types
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the exhaustiveness algorithm to detect non-exhaustive pattern matches:
- Detects missing Bool patterns (true/false)
- Detects missing Option patterns (Some/None)
- Detects missing Result patterns (Ok/Err)
- Recognizes wildcards and variable patterns as catch-alls
- Warns about redundant patterns after catch-all patterns
- Integrates with the type checker to report errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement beautiful, informative error messages inspired by Elm:
- Rich diagnostic rendering with source code snippets
- Colored output with proper underlines showing error locations
- Categorized error titles (Type Mismatch, Unknown Name, etc.)
- Contextual hints and suggestions for common errors
- Support for type errors, runtime errors, and parse errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement behavioral properties for functions including:
- Property annotations: is pure, is total, is idempotent, is deterministic, is commutative
- Where clause constraints: where F is pure
- Result refinements: where result >= 0 (parsing only, not enforced)
Key changes:
- AST: BehavioralProperty enum, WhereClause enum, updated FunctionDecl
- Lexer: Added keywords (is, pure, total, idempotent, deterministic, commutative, where, assume)
- Parser: parse_behavioral_properties(), parse_where_clauses(), parse_single_property()
- Types: PropertySet for tracking function properties, updated Function type
- Typechecker: Verify pure functions don't have effects, validate where clause type params
Properties are informational/guarantees rather than type constraints - a pure
function can be used anywhere a function is expected. Property requirements
are meant to be enforced via where clauses (future work: call-site checking).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>