Skip to content

Let a validation rule name a predicate it cannot express - #49

Open
woksin wants to merge 4 commits into
mainfrom
feat/named-predicate-validation-rule
Open

Let a validation rule name a predicate it cannot express#49
woksin wants to merge 4 commits into
mainfrom
feat/named-predicate-validation-rule

Conversation

@woksin

@woksin woksin commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Added

Fixed

woksin added 4 commits July 29, 2026 12:55
The declarative rule kinds are a closed set, so a rule whose logic is an
arbitrary predicate had no shape at all and was left out of the document
entirely.

That does not just lose detail - it makes the document assert something
false. A property with two declarative rules and three predicates reads as a
property with two rules, and a reader cannot tell "nothing further constrains
this" from "the rest could not be written down".

'rule <Name>' states that a constraint exists and what it is called. The name
is a reference into the implementation, not a declared entity - nothing
resolves it - and the rule carries 'message' like any other. A name that is
not an identifier is an error rather than silently accepted.
@woksin woksin added the minor New features, non-breaking additions label Jul 29, 2026
@woksin

woksin commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Reviewer notes — open for review, not merged, since it is a language decision.

Answering the three questions raised in #47:

Should an unnamed predicate be expressible? No — rule with no name is an error, not a silent acceptance. A rule with neither a name nor logic is indistinguishable from noise in the document, and the generator can legitimately report that a lambda has no name to recover. If inline lambdas turn out to dominate in practice, a nameless rule is a strictly additive follow-up.

Does it participate in anything? Purely descriptive, and the docs say so explicitly. The name is a reference into the implementation, not a declared entity — unlike produces / executes / a future reads, nothing resolves it and the compiler does not check that anything by that name exists. Stating that now avoids someone later expecting rule X to resolve.

Does the async variant need distinguishing? No. MustAsync is a detail of how the predicate is evaluated, and per the principle ratified in #40 the document describes meaning, not execution.

Flat, not nested. #47 sketched a nested form (property header, indented rules). I went flat — rule as one more rule kind on the existing line — because nested would make validate a two-level block and force the printer to pick one canonical form for the same tree, churning every existing document's printed output. Flat inherits message, $strings. keys and printer parity unchanged, and composes automatically with the when clause in #45 once that lands, since both are handled on the same line by the same parser. If you would rather have nested, doing it before more rule shapes arrive is cheaper than after — that is the one call I would like from you.

Independent of #45 and #48. Branched from main, no overlap with either.

Verificationdotnet build Debug and Release both 0 errors / 0 warnings (Release treats warnings as errors); dotnet test 593 passing, 0 failing; yarn lint, yarn build, yarn compile clean. Debug carries the one pre-existing IDE0305 warning in for_ScreenplayWriter/when_inspecting_assembly_visibility.cs, untouched here.

@woksin

woksin commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Merge ordering note. This PR and #45 each merge cleanly into main today, but they conflict with each other — both extend the validation rule line, so they collide in four files:

Whichever lands second needs a small manual resolution. The resolution is additive in every case — the two features compose rather than compete, so orgNumber rule BeUnique when isNew == true message "…" is the intended end state. Nothing needs redesigning, it is just four hunks to merge by hand.

#48 conflicts with neither and can land in any order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor New features, non-breaking additions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant