includes refuses a field the schema says is a scalar - #74
Merged
Merged
Conversation
`includes` is a list-membership probe, and a non-list operand evaluates
to false at runtime by decision (`test_includes_with_scalar_left_operand
_is_false`). That is right where the type is whatever the value turned
out to be. It is wrong at analysis time when the record schema has
already said the field holds text:
filter the orders where title includes "roof"
validated clean, emptied a two-record list, and reported success.
Reachable only since #72 admitted `includes` after `where`. The refusal
that change replaced was safe and described the wrong problem — "I
couldn't parse the condition after 'where'" — and what replaced it
described nothing and was wrong. A misleading refusal beats a silent
wrong answer, so this is the one I introduced and the one to fix.
The analyzer now answers where the type is known and defers where it is
not. A list-valued field is `unknown` statically, so it still reaches
runtime and nothing that worked before stops working — the list-field
case is tested alongside.
The message says what is absent rather than what is malformed:
"'includes' tests whether a list holds a value, and 'title' is text.
Liminate has no text-contains test." That is the honest answer to a
downstream consumer asking for `contains`, and v27 §56's locked
meta-finding — the era of new verbs is ending — is why the answer is not
to add one.
A corpus case pins it, so the TypeScript port inherits the refusal rather
than the silence. 1748 passed, 2 skipped; grammar projections regenerated.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E6qcDj1e1dEYvc8jLnpGZy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A defect #72 introduced, found while porting.
What happened
includesis a list-membership probe, and a non-list operand evaluates to false at runtime by decision —test_includes_with_scalar_left_operand_is_falsepins it. That is right where the operand's type is whatever the value turned out to be.It is wrong at analysis time, where the record schema has already said what the field holds:
validated clean, emptied a two-record list, and reported success.
Reachable only since #72 admitted
includesafterwhere. The refusal that change replaced was safe and described the wrong problem — "I couldn't parse the condition after 'where'" — and what replaced it described nothing and was wrong. A misleading refusal beats a silent wrong answer, so this is mine and this is the fix.The rule
Answer where the type is known; defer where it is not.
string/number/date→ refusedunknown→ runtime, unchangedA list-valued field is
unknownstatically, sofilter the orders where tags includes "urgent"— the case #72 exists for — still works, and is tested alongside.The message names what is absent
That is the honest answer to a downstream consumer asking for
contains, and it is the answer rather than a new word because v27 §56's locked meta-finding says so: the era of new verbs is ending; the era of new positions is beginning.between— the structurally identical case — was put on the operator-extensibility pack frontier by the same ruling, and packs today extend verbs and nouns only.Verified
🤖 Generated with Claude Code
https://claude.ai/code/session_01E6qcDj1e1dEYvc8jLnpGZy