Stop telling the model list.zip exists, then linting it for using it - #49
Merged
Conversation
Benchmark findings from local runs, rescued from an uncommitted working copy
and rebased onto main. Two of them are corrections, not additions:
1. The prompt's stdlib index advertised `zip` as a std.list function. It does
not exist — `list.zip(...)` is `unknown_field` on 0.10.6. We were the source
of the hallucination the linter then flagged. The row also omitted six
functions that DO exist, two of which the prompt's own examples use
(`list.cons`, `list.range`), and one the new zip hint recommends
(`list.enumerate`) — so a model told "use enumerate" had no confirmation it
was real. Every one of the fourteen functions the row now claims was probed
against 0.10.6 individually.
2. The `&&` linter hint said "use nested if: `if a { b } else { false }`".
Lex has `and`. The hint now says `a and b`, and `||` gets the same treatment.
The old advice was not just verbose, it was wrong about the language.
Plus targeted fix: hints for the two APIs models reach for most and that do not
exist — `list.zip` (→ enumerate, or compare via str.join) and `str.to_str`
(→ int.to_str). Both verified absent on 0.10.6 before writing the hint.
Verified: CI's own loop over all 76 tracked src/*.lex exits 0; the examples
check passes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CI's fmt --check step caught this — I had run the type-check loop locally but missed the fmt step when reading the workflow. The prompt file has no inner comments, so lex-lang#716 costs nothing here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Benchmark findings that had been sitting uncommitted in a local working copy (3 weeks stale, 8 commits behind). Rescued and rebased onto current main — the 3-way apply was clean.
Two of the four changes are corrections to things we had wrong, not new features.
1. We were the source of the
list.ziphallucinationThe prompt's stdlib index advertised
zipas astd.listfunction:list.zipdoes not exist:We told the model it was real, then added a linter rule scolding it for reaching for it. The row also omitted six functions that do exist — including
list.consandlist.range, which the prompt's own code examples use, andlist.enumerate, which the new zip hint tells the model to use instead. A model told "use enumerate" had no confirmation enumerate was real.Every one of the fourteen functions the row now claims was probed against 0.10.6 individually:
The
strrow was checked too — it's an incomplete subset, but claims nothing false, so it's left alone.2. The
&&hint was wrong about the languageLex has
and/or. The old hint pushed models into needless nesting to avoid an operator that has a perfectly good keyword equivalent.||gets the same fix.3. Targeted hints for the two most-hallucinated APIs
list.zip→list.enumerate, or compare viastr.join(a, ",") == str.join(b, ",").str.to_str→int.to_strfromstd.int.Both verified absent on 0.10.6 before the hint was written — the linter should never assert an API doesn't exist without that being checked.
Verification
CI's own loop, run locally on 0.10.6:
Note
The fix to the index matters more than the lint rule: the rule catches the symptom, the index was the cause. The rule stays as a safety net for models that reach for
zipout of habit from other languages.🤖 Generated with Claude Code