feat(language): a where selects several labels at once with 'in' - #283
FabianHofmann wants to merge 4 commits into
Conversation
Documentation build overview
7 files changed ·
|
…l and its quoted flag
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P5CbcWjp4KCK5RcCEy7RZ3
FBumann
left a comment
There was a problem hiding this comment.
See stacked PR. Add some tests
…e-program test(lowering): a where atom reaches the program as the file wrote it
|
Same here. SOrry for the churn. But I made the where parser fully internal. This should also make this easier or at least more obvious to implement! |
|
@FabianHofmann I would tend to close this unmerged. This feature doesnt fit the agreement about #121 Whats your take? |
|
@FBumann I tend to agree that we close it unmerged. I can see it coming back to hurt us later as users get annoyed by not being able to define values directly in math. What I would like is to have some dimensions/parameters defining an |
|
Note The following content was generated by AI. Closed unmerged, on the decision in this thread: a literal list writes label The follow-up named here — an Generated by Claude Code |
Note
The following content was generated by AI.
Closes #254. A
wherecan now select several labels at once:where: "carrier in ['ccgt', 'ocgt']"parses to a node of its own, resolves per left-hand kind, and prints ascarrier ∈ {ccgt, ocgt}in all three formats.What this changes
name in [l1, l2, …]. The left-hand side is the same three kinds a comparison takes (parameter, dimension, lookup); a variable is refused with the existing message.isinfilter rather than an OR chain._typed_literala scalar comparison runs — its core is refactored to(name, value, quoted, dtype, …)so the scalar and per-element paths share one home.where: "False"; a duplicate says drop it; a declared name among the elements points to#258or aboolparameter.inoperator plus set-braces in the format protocol (\in \{…\}/in {…}).NOTstays generic — no∉case.NOT; there is nonot inspelling. Float left-hand sides are allowed (the OR chain already permits exact float equality).Syntax
Now accepted — the left-hand side is a parameter, a dimension, or a lookup:
Both quote characters, escapes, and negative numbers carry over per element unchanged, and a single-element list is fine.
Out of scope — refused at load, each message naming the rewrite:
Also not in this PR: membership over an expression or a lookup pair (only a bare name on the left).
Why
The design was settled in the issue thread. It sits inside the existing first admissibility row in
ceiling.md(relational ∩ local, anisinfilter), so this is not a ceiling move — flagging that reading here rather than editing the page.Breaking change (free, alpha stream):
inis now reserved between a name and the rest of an atom. A model that usedinas a bare token there no longer parses.Verification, decisions, and departures
Gate:
pixi run ciin full — lint clean,865 passed, docs built--strict, 27 TeX documents compiled.Built and reviewed by agents: one implementer followed the plan end to end; three review lenses (correctness/exhaustiveness, typesetting/generated artifacts, tests/messages) then checked the diff and each returned "sound as it stands". Four minor findings were addressed:
T00:00andT00:00:00, collide) and renders numbers via:g(0, not0.0), matching the rest of the where path. A reviewer's illustration using'2030-01-01'vs'2030-01-01T00:00'was set aside: in Python adatedoes not equal adatetimeat midnight, so those are genuinely different values, not a duplicate. Two new tests pin the real cases.Departure from the plan (Part 2 asks this be named): the docs atoms table folds the three per-kind rows into one row spanning parameter/dimension/lookup, with the refusals in following prose. The plan said "a row per kind"; the fold is the DRY choice and the content (EBNF production,
#258pointer, extended float-equality note) is complete.Generated files: schema is untouched (a
whereis a string — confirmed by the drift test). The golden fixture gained aninmask exercising all three kinds; the.outfiles were regenerated, not hand-edited, and their diff read as the review.Delete-the-guard: each of the three refusals is load-bearing and has a test that fails without it; the removal-and-watch was reasoned, not mechanically performed for every guard.