Skip to content

Aether 30.0 — comprehensions grow up: pattern generators, let-qualifiers & range literals#673

Merged
github-actions[bot] merged 1 commit into
mainfrom
claude/hopeful-keller-96sfig
Jul 24, 2026
Merged

Aether 30.0 — comprehensions grow up: pattern generators, let-qualifiers & range literals#673
github-actions[bot] merged 1 commit into
mainfrom
claude/hopeful-keller-96sfig

Conversation

@kkd16

@kkd16 kkd16 commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Improves the existing aether-lang-c3d8 project (a from-scratch ML-family language toolchain that runs entirely in the browser). This is a single-project PR — every changed file lives under projects/aether-lang-c3d8/.

What changed

Aether had list comprehensions, but only the thinnest slice: a generator bound a plain name and a qualifier was a boolean guard — and there were no range literals at all. 30.0 closes that gap the way the language is proud of — as pure front-end sugar, desugared in the parser into the existing core (concat/map/if/let/match). The type checker, the optimizing middle-end and all three backends (bytecode VM · JavaScript · WebAssembly) never see a comprehension or a range, so the release is strictly additive — an old program takes the exact pre-30.0 path.

  • Range literals[a .. b] (inclusive) and [a, s .. b] (stepped, ascending or descending; a zero step terminates as []). Backed by two new prelude functions enumFromTo / enumFromThenTo, written in Aether itself. A new .. lexer token uses longest-match, so 1..10 splits cleanly while r.field field access and floats like 1.5 are untouched.
  • Pattern generators — a generator's binder can be any pattern: (a, b) <- ps, Som x <- opts, h :: _ <- rows. An irrefutable binder keeps the clean bare-map desugaring; any other pattern maps a match … | _ -> [] whose wildcard arm drops the non-matching elements (the list-monad fail).
  • let-qualifiers[ e | x <- xs, let y = f x, y > 0 ], scoped over the qualifiers to their right.

Verification

  • New 200-program differential fuzzer (comprehensionFuzz.ts): each random comprehension — nested generators, inclusive/stepped ranges, guards, let-qualifiers and tuple/Som/cons pattern generators — is proved sound two ways: the compiled program's VM result equals an independent TypeScript reference (the comprehension re-evaluated by nested iteration, never touching the desugaring) and that value re-appears on the JavaScript backend (VM ≡ JS). Holds at 200/200, and across 7 seeds × 300 runs (2,100 programs) with zero failures. Stable badge on the Tests page.
  • New 19-case in-app comprehensions battery (VM + JS ≡ VM): suite grows 147 → 166, all green; the headless harness also re-runs each on WASM (150/150).
  • No regression: existing in-app suite 166/166, WASM ≡ VM 150/150, semantics 19/19, and the optimizer / SpecConstr / SROA fuzzers all still pass.
  • Full CI gate (scripts/verify-project.mjs: scope + conformance + lint + tsc + build) is green locally.

Four new gallery examples: a comprehensions tour, two-line quicksort, a prime sieve, and a turtle "comprehension garden" driven by a stepped range. JOURNAL.md carries the plan and a session-log entry.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BSXUJbL86qsEW8zJqvUppq


Generated by Claude Code

…ers & range literals

List comprehensions previously bound only a plain name and filtered with boolean
guards, and there were no range literals. This release adds, as pure parser sugar
desugared into the existing core (so the type checker and all three backends see
only ordinary map/filter/concat/match):

- range literals `[a .. b]` (inclusive) and `[a, s .. b]` (stepped), backed by
  two new prelude functions `enumFromTo` / `enumFromThenTo`;
- pattern generators `(a,b) <- ps`, `Som x <- opts`, `h :: _ <- rows`, where a
  refutable pattern drops the non-matching elements (the list-monad fail);
- `let`-qualifiers `let y = f x`, scoped over the qualifiers to their right.

Verification: a new 200-program differential fuzzer (comprehensionFuzz.ts) checks
each random comprehension against an independent TypeScript reference evaluator and
the JavaScript backend (VM ≡ reference ≡ JS); a new 19-case in-app `comprehensions`
battery (suite 147 → 166); four gallery examples incl. a turtle "comprehension
garden"; About/parser-note and stdlib updates. No regression to existing suites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BSXUJbL86qsEW8zJqvUppq

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Scope + lint + build passed.

@github-actions
github-actions Bot merged commit 038c476 into main Jul 24, 2026
2 checks passed
@github-actions
github-actions Bot deleted the claude/hopeful-keller-96sfig branch July 24, 2026 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants