15 KiB
Sugar Syntax Proposals - 22 Ergonomics Enhancements
Generated by: Task Agent 1 (Language Features Analysis) Date: 2025-10-12 Philosophy: Desugar everything to Box operations, maintain MIR 16-instruction set
📊 Priority Matrix
| Priority | Difficulty | Count | Examples |
|---|---|---|---|
| High | Easy | 3 | List comprehension, Null coalescing assignment, Range operator |
| High | Medium | 3 | Null-safe operator, Arrow functions, String interpolation |
| Medium | Easy | 4 | Multiple return, Default parameters, Named parameters, With expression |
| Medium | Medium | 6 | Pattern matching in let, Spread operator, Destructuring, Guard clauses, Switch expression, Do expression |
| Low | Medium | 3 | Pipeline operator enhancement, For...in sugar, Partial application |
| Low | Hard | 3 | Async/await sugar, Generator functions, Tail call optimization |
🚀 High Priority - Easy Implementation
1. List Comprehension
Impact: 60-70% code reduction in data processing Difficulty: Easy (desugar to loop + ArrayBox)
// Syntax
[expression for variable in iterable if condition]
// Example
local evens = [x * 2 for x in numbers if x % 2 == 0]
// Desugars to:
local evens = new ArrayBox()
local __iter = numbers.iterator()
loop(__iter.has_next()) {
local x = __iter.next()
if x % 2 == 0 {
evens.push(x * 2)
}
}
Implementation strategy:
- Parser recognizes
[... for ... in ... if ...]pattern - AST node:
ListComprehension { expr, var, iter, condition } - Desugar in MIR builder to loop + conditional + push
2. Null Coalescing Assignment
Impact: Eliminate boilerplate null checks Difficulty: Easy (desugar to if + assignment)
// Syntax
variable ??= default_value
// Example
local config
config ??= load_default_config() // Only assigns if config is null
// Desugars to:
if config == null {
config = load_default_config()
}
Implementation strategy:
- Parser recognizes
??=operator - AST node:
NullCoalescingAssign { lhs, rhs } - Desugar to null check + conditional assignment
3. Range Operator
Impact: Clean array slicing and iteration Difficulty: Easy (RangeBox or builtin)
// Syntax
start..end // Exclusive end
start..=end // Inclusive end
array[start..end] // Slice syntax
// Example
local range = 0..10 // RangeBox(0, 10)
local slice = array[2..5] // array.slice(2, 5)
loop(i in 0..10) { // Iterator sugar
print(i)
}
// Desugars to:
local range = RangeBox.new(0, 10)
local slice = array.slice(2, 5)
local i = 0
loop(i < 10) {
print(i)
i = i + 1
}
Implementation strategy:
- Introduce
RangeBoxcore type - Parser recognizes
..and..=operators - Array indexing with range → slice() method call
for x in rangesugar → loop + counter
🔥 High Priority - Medium Implementation
4. Null-Safe Operator
Impact: Crash prevention, cleaner code Difficulty: Medium (short-circuit evaluation)
// Syntax
object?.method()
object?.field
// Example
local street = person?.address?.street // Returns null if any intermediate is null
// Desugars to:
local street
if person != null {
local __temp1 = person.address
if __temp1 != null {
street = __temp1.street
} else {
street = null
}
} else {
street = null
}
Implementation strategy:
- Parser recognizes
?.operator - AST node:
NullSafe { object, chain } - Desugar to nested null checks with short-circuit
- MIR: use branch + phi nodes for null propagation
5. Arrow Functions
Impact: Cleaner callbacks and functional programming Difficulty: Medium (closure capture)
// Syntax
(params) => expression
(params) => { statements }
// Example
local doubled = array.map(x => x * 2)
local filtered = array.filter(x => x > 10)
// Desugars to:
box __Lambda1 {
call(x) {
return x * 2
}
}
local doubled = array.map(new __Lambda1())
Implementation strategy:
- Parser recognizes
=>operator - AST node:
ArrowFunction { params, body } - Desugar to anonymous box with
call()method - Capture environment variables as box fields
6. String Interpolation
Impact: Eliminate ugly concatenation Difficulty: Medium (expression parsing inside strings)
// Syntax
`string with ${expression}`
// Example
local message = `Hello, ${name}! You have ${count} messages.`
// Desugars to:
local message = new StringBox("Hello, ")
.concat(name.to_string())
.concat("! You have ")
.concat(count.to_string())
.concat(" messages.")
Implementation strategy:
- Parser recognizes
`...${...}...`pattern - AST node:
StringInterpolation { parts: Vec<StringOrExpr> } - Desugar to StringBox concatenation chain
- Call
.to_string()on interpolated expressions
💡 Medium Priority - Easy Implementation
7. Multiple Return Values
Impact: Cleaner function signatures Difficulty: Easy (TupleBox or multiple assignments)
// Syntax
return value1, value2, value3
// Example
divide(a, b) {
if b == 0 {
return null, "Division by zero"
}
return a / b, null
}
local result, error = divide(10, 2)
// Desugars to:
divide(a, b) {
if b == 0 {
return TupleBox.new(null, "Division by zero")
}
return TupleBox.new(a / b, null)
}
local __tuple = divide(10, 2)
local result = __tuple.get(0)
local error = __tuple.get(1)
Implementation strategy:
- Introduce
TupleBoxcore type return a, b, c→return TupleBox.new(a, b, c)local a, b, c = expr→ destructuring assignment
8. Default Parameters
Impact: Fewer function overloads Difficulty: Easy (desugar to null check)
// Syntax
function(param = default_value)
// Example
greet(name = "World") {
print(`Hello, ${name}!`)
}
greet() // "Hello, World!"
greet("Alice") // "Hello, Alice!"
// Desugars to:
greet(name) {
if name == null {
name = "World"
}
print(`Hello, ${name}!`)
}
Implementation strategy:
- Parser recognizes
param = defaultin function signature - AST node:
DefaultParam { name, default_expr } - Desugar to null check at function entry
9. Named Parameters
Impact: Better API ergonomics Difficulty: Easy (MapBox or ordered params)
// Syntax
function(name: value, other: value)
// Example
create_user(name: "Alice", age: 30, admin: true)
// Desugars to:
local __args = new MapBox()
__args.set("name", "Alice")
__args.set("age", 30)
__args.set("admin", true)
create_user(__args)
Implementation strategy:
- Parser recognizes
name: valuesyntax in call - Collect into MapBox
- Function receives MapBox and extracts values
10. With Expression
Impact: Cleaner resource management (already have cleanup)
Difficulty: Easy (combine with existing cleanup)
// Syntax
with resource = expression {
// use resource
} // automatic cleanup
// Example
with file = FileBox.open("data.txt") {
local content = file.read()
print(content)
} // file.close() called automatically
// Desugars to:
local file = FileBox.open("data.txt")
cleanup {
file.close()
}
local content = file.read()
print(content)
Implementation strategy:
- Parser recognizes
with variable = expr { ... }pattern - Desugar to variable binding + cleanup block
- Reuse existing
cleanupmechanism
🎯 Medium Priority - Medium Implementation
11. Pattern Matching in Let
Impact: Destructure complex data structures Difficulty: Medium (pattern matching engine)
// Syntax
local Pattern = expression
// Example
local Ok(value) = result // Panic if result is Err
local [first, rest...] = array
local {name, age} = person
// Desugars to:
match result {
Ok(value) => {
local value = value
}
_ => panic("Pattern match failed")
}
Implementation strategy:
- Extend existing
matchimplementation - Allow patterns in
localstatements - Generate runtime check + panic if no match
12. Spread Operator
Impact: Clean array/object merging Difficulty: Medium (iterate + copy)
// Syntax
[...array1, ...array2]
{...object1, ...object2}
// Example
local merged = [...arr1, item, ...arr2]
local combined = {name: "Alice", ...defaults}
// Desugars to:
local merged = new ArrayBox()
local __iter1 = arr1.iterator()
loop(__iter1.has_next()) {
merged.push(__iter1.next())
}
merged.push(item)
local __iter2 = arr2.iterator()
loop(__iter2.has_next()) {
merged.push(__iter2.next())
}
Implementation strategy:
- Parser recognizes
...exprin array/map literals - Desugar to iterator loops + push operations
- For maps, use
.entries()+.set()chain
13. Destructuring Assignment
Impact: Cleaner variable extraction Difficulty: Medium (pattern matching)
// Syntax
local [a, b, c] = array
local {name, age} = person
// Example
local [first, second, rest...] = [1, 2, 3, 4, 5]
// first = 1, second = 2, rest = [3, 4, 5]
// Desugars to:
local first = array.get(0)
local second = array.get(1)
local rest = array.slice(2, array.length())
Implementation strategy:
- Parser recognizes patterns in
localstatements - AST node:
Destructure { pattern, expr } - Desugar to individual assignments
14. Guard Clauses
Impact: Reduce nesting Difficulty: Medium (early return transformation)
// Syntax
guard condition else return/break/continue
// Example
function process(value) {
guard value != null else return null
guard value > 0 else return -1
return value * 2
}
// Desugars to:
function process(value) {
if value == null {
return null
}
if value <= 0 {
return -1
}
return value * 2
}
Implementation strategy:
- Parser recognizes
guard ... else ...pattern - AST node:
Guard { condition, action } - Desugar to inverted condition + action
15. Switch Expression
Impact: Cleaner value-producing conditionals Difficulty: Medium (extend match to primitives)
// Syntax
switch value {
case1 => result1,
case2 => result2,
_ => default
}
// Example
local grade = switch score {
90..=100 => "A",
80..=89 => "B",
70..=79 => "C",
_ => "F"
}
// Desugars to:
local grade
if score >= 90 && score <= 100 {
grade = "A"
} else if score >= 80 && score <= 89 {
grade = "B"
} else if score >= 70 && score <= 79 {
grade = "C"
} else {
grade = "F"
}
Implementation strategy:
- Extend
matchto work with expressions - Support range patterns
- Desugar to if-else chain with phi nodes
16. Do Expression
Impact: Expression-oriented programming Difficulty: Medium (block as expression)
// Syntax
local value = do {
statements...
final_expression
}
// Example
local result = do {
local temp = calculate()
local adjusted = temp * 2
adjusted + 10
}
// Desugars to:
local temp = calculate()
local adjusted = temp * 2
local result = adjusted + 10
Implementation strategy:
- Parser recognizes
do { ... }as expression - AST node:
DoExpression { stmts, final_expr } - Desugar to inline statements + final assignment
🔮 Low Priority - Medium/Hard Implementation
17. Pipeline Operator Enhancement (already exists, enhance)
Current: a |> b |> c
Enhancement: Support method chaining syntax
// Current
data |> transform1 |> transform2 |> transform3
// Enhanced
data
|> transform1(?, arg)
|> obj.method(?)
|> ?.optional_method()
// Desugars to:
local __pipe1 = transform1(data, arg)
local __pipe2 = obj.method(__pipe1)
local __pipe3 = __pipe2?.optional_method()
18. For...In Sugar
Impact: Cleaner iteration syntax Difficulty: Medium
// Syntax
for variable in iterable {
// body
}
// Example
for item in array {
print(item)
}
// Desugars to:
local __iter = array.iterator()
loop(__iter.has_next()) {
local item = __iter.next()
print(item)
}
19. Partial Application
Impact: Functional programming patterns Difficulty: Medium
// Syntax
function(?, arg2, ?) // ? is placeholder
// Example
local add_10 = add(?, 10)
add_10(5) // Returns 15
// Desugars to:
box __Partial_add_10 {
call(arg1) {
return add(arg1, 10)
}
}
local add_10 = new __Partial_add_10()
20. Async/Await Sugar Enhancement
Impact: Better async ergonomics (already have nowait/await) Difficulty: Medium
// Current
nowait future = async_operation()
local result = await future
// Enhanced
async function fetch_data() {
local response = await http.get(url)
local data = await response.json()
return data
}
// Desugars to existing nowait/await
21. Generator Functions
Impact: Lazy iteration Difficulty: Hard (requires state machine transformation)
// Syntax
function* generator() {
yield value1
yield value2
}
// Example
function* fibonacci() {
local a = 0
local b = 1
loop(true) {
yield a
local temp = a
a = b
b = temp + b
}
}
// Desugars to:
box FibonacciGenerator from IteratorBox {
a: IntegerBox
b: IntegerBox
birth() {
me.a = 0
me.b = 1
}
next() {
local current = me.a
local temp = me.a
me.a = me.b
me.b = temp + me.b
return current
}
}
22. Tail Call Optimization (Automatic)
Impact: Enable recursive functional programming Difficulty: Hard (MIR-level transformation)
// Automatically detect tail calls and convert to loops
// Example
factorial(n, acc = 1) {
if n <= 1 {
return acc
}
return factorial(n - 1, n * acc) // Tail call
}
// Desugars to:
factorial(n, acc = 1) {
loop(true) {
if n <= 1 {
return acc
}
local __temp_n = n - 1
local __temp_acc = n * acc
n = __temp_n
acc = __temp_acc
}
}
🎯 Implementation Priority Recommendation
Week 1-2: Quick wins
- List comprehension
- String interpolation
- Null coalescing assignment
- Range operator
Week 3-4: High-value ergonomics
- Null-safe operator
- Arrow functions
- Multiple return values
- Default parameters
Week 5-6: Medium-value features
- Pattern matching in let
- Destructuring
- Spread operator
- Guard clauses
Week 7+: Advanced features
- Partial application
- Enhanced pipeline
- Generator functions (if needed)
- Tail call optimization (LLVM backend only)
📈 Expected Outcomes
Code reduction: 60-70% in typical cases Ergonomics: Python-level comfort with Rust-level power Learning curve: Gentle (all sugar desugars to familiar Box operations) Migration path: All existing code continues to work
✅ Validation Criteria
Each sugar syntax must:
- ✅ Desugar to existing MIR 16-instruction set
- ✅ Follow "Everything is Box" principle
- ✅ Have clear error messages
- ✅ Be documented with examples
- ✅ Have comprehensive tests
- ✅ Not introduce runtime overhead (except where semantically required)
Next: See macro-system-proposals.md for compile-time code generation proposals.