# Lux Stress Test Findings This document summarizes issues found during systematic stress testing of the Lux parser, typechecker, and REPL. ## Critical Bugs (All Fixed) ### 1. ~~Record Equality Returns False for Equal Records~~ (FIXED) ```lux let r1 = { x: 1, y: 2 } let r2 = { x: 1, y: 2 } r1 == r2 // Now returns true ``` **Fix**: Added Record case to `Interpreter::values_equal` in `src/interpreter.rs` ### 2. ~~Invalid Escape Sequences Silently Accepted~~ (FIXED) ```lux "\z" // Now produces error: "Invalid escape sequence: \z" ``` **Fix**: Modified lexer in `src/lexer.rs` to error on unknown escape sequences ### 3. ~~Unknown Effects Silently Accepted in Declarations~~ (FIXED) ```lux fn test(): Unit with {CompletelyFakeEffect} = () // Now produces error with suggestions ``` **Fix**: Added effect validation in `TypeChecker::check_function` in `src/typechecker.rs` ### 4. ~~No Forward References for Mutual Recursion~~ (FIXED/DOCUMENTED) ```lux fn isEven(n: Int): Bool = if n == 0 then true else isOdd(n - 1) fn isOdd(n: Int): Bool = if n == 0 then false else isEven(n - 1) // Works in files (two-pass type checking), REPL limitation documented ``` **Note**: Works when loaded from files due to two-pass type checking. REPL processes line-by-line, so forward references don't work there. ### 5. ~~Circular Type Definitions Silently Fail~~ (FIXED) ```lux type A = B type B = A // Now produces error: "Circular type definition detected: A -> B -> A" ``` **Fix**: Added `check_type_cycles` method with DFS cycle detection in `src/typechecker.rs`. Also fixed parser to require `|` for enum variants, allowing `type A = B` to be parsed as a type alias. ## Parser Issues ### Missing Features | Feature | Status | Notes | |---------|--------|-------| | Hex literals (`0x10`) | Not supported | Generic parse error | | Binary literals (`0b101`) | Not supported | Generic parse error | | Octal literals (`0o77`) | Not supported | Generic parse error | | Scientific notation (`1e10`) | Not supported | Generic parse error | | Leading dot floats (`.5`) | Not supported | Generic parse error | | Trailing dot floats (`1.`) | Not supported | Generic parse error | | Underscore separators (`1_000_000`) | **Supported** | Works correctly | | List patterns in match (`[a, b, c]`) | Not supported | Parse error | | Guard clauses (`x if x > 0 =>`) | Not working | Shows redundant pattern error | ### Poor Error Messages | Input | Current Error | Better Error | |-------|---------------|--------------| | `[1 2 3]` | "Expected declaration" | "Missing comma between list elements" | | `{ x 1 }` | "Undefined variable: x" | "Missing colon in record field" | | `funtion foo()` | "Expected declaration" | "Unknown keyword 'funtion'. Did you mean 'fn'?" | | `(1 + 2` | No error | "Unclosed parenthesis" | | `{ x: 1` | No error | "Unclosed brace" | | `[1,, 2]` | No output | "Unexpected comma" | ### Identifier Issues - Double underscore identifiers (`__name`) not allowed - Unicode identifiers (`café`) partially work but may have issues ## Type Checker Issues ### Good Error Messages - Type mismatches: Clear "Cannot unify X with Y" - Undefined variables: Includes "Did you mean..." suggestions - Wrong argument count: Clear arity mismatch message - Non-exhaustive match: Lists uncovered patterns - Effect mismatches: Shows expected vs actual effects - Undefined record field: Clear "Record has no field" - Calling non-function: Clear type mismatch ### Issues - `:type 42` shows "(type checking passed)" but not the actual type - No type inference for function parameters - must be annotated ## Runtime Issues ### Division Handling - Integer `/0`: Proper "Division by zero" error - Integer `%0`: Proper "Modulo by zero" error - Float `/0.0`: Returns `inf` (IEEE 754 compliant) ### Recursion - Deep recursion (10,000 calls): Works! Good tail call optimization - Infinite recursion: Eventually times out (expected) ### Missing Stdlib Functions - `String.get(s, i)` - not implemented - `String.charAt(s, i)` - not implemented ## REPL Issues ### Working Well - State persistence between lines - Function redefinition - Multi-line input - `:help`, `:quit`, `:load` commands - Tab completion (noted in help) ### Issues - `:type expr` doesn't show the type, just "(type checking passed)" - No `:ast` or `:tokens` debugging commands - String interpolation syntax is `{x}` not `${x}` (unexpected) - `"Hello {name}"` works - `"Hello ${name}"` outputs `"Hello $"` (keeps literal `$`) ## Comparison & Equality | Type | `==` Works? | |------|-------------| | Int | Yes | | Float | Yes | | Bool | Yes | | String | Yes | | List | Yes | | Tuple | Yes | | Option/Result | Yes | | **Record** | **NO (BUG)** | | Function | No (expected) | ## Short-Circuit Evaluation Works correctly: - `true || crash()` - doesn't call `crash()` - `false && crash()` - doesn't call `crash()` - `if true then 1 else crash()` - doesn't call `crash()` ## Recommendations ### High Priority 1. Fix record equality 2. Error on invalid escape sequences 3. Validate effect names at declaration time ### Medium Priority 4. Add forward reference support for mutual recursion 5. Improve parser error messages with context 6. Add list pattern matching support 7. Error on circular type definitions ### Low Priority 8. Add hex/binary/octal literal support 9. Add scientific notation support 10. Fix `:type` command to show actual type 11. Document actual string interpolation syntax ## Test Commands Used ```bash # Run stress tests ./target/release/lux test examples/test_math.lux # Test specific edge case echo 'let r1 = {x: 1}; let r2 = {x: 1}; r1 == r2' | ./target/release/lux ```