docs: bring the prose up to 0.5.0, and give CI something to run - #65
Merged
Conversation
The 0.5.0 features reached every machine-readable surface (parser, TextMate
grammar, all four tree-sitter query sets) and only one prose one, so the
documents disagreed with the compiler and with each other. `option {}` is the
fourth built-in computation expression; DESIGN.md said "exactly three, no more"
in its guardrails while saying four in §8.1, and RATIONALE, the README and the
Marketplace-facing extension README each said three.
Corrected against the source rather than against each other:
- DESIGN.md §11 now states the closing rule (one per short-circuit type, one per
Python control-flow form) instead of a count, and drops the user-defined-CE
deferral, which shipped. §8.1's claim that Pyfun has no offside rule was
contradicted by the lexer it cited.
- INTERNALS.md's crate layout named a `desugar/` directory, a `types/units/`
subdirectory, a `cli/` built on clap, and a `prelude/` — none of which exist.
The tour's build order repeated it.
- The internals tour quoted `CeItem::LetBang { name, .. }`, which carries a
`Pattern` since destructuring `let` landed, and a `build_call` excerpt from
before partially applied lambdas beta-reduced.
- The interop cookbook still described the extern import-prefix heuristic as
guessing wrong; it refuses and names the `extern import` to add.
- editors/README.md sent Emacs users to hand-roll a mode we ship, and called the
JetBrains plugin aspirational two paragraphs after saying it exists.
- The VS Code grammar highlighted `in`, which is not a keyword, and not
`import`/`try`/`as`, which are. JetBrains inherits that grammar.
RELEASING.md said "all four files" over three bullets, and claimed the
`Assisted-by:` header MELPA asked for was already in pyfun-mode.el. It was not,
which would have blocked the resubmission that reopens mid-August; it is now,
in MELPA's documented `AGENT:MODEL` form.
The CI gap is the reason a release could ship with all of this: nothing ran
`cargo test`, `cargo clippy` or `cargo fmt --check` on a PR — the only cargo
call in any workflow was a build inside the kernel job. ci.yml runs the three
commands CLAUDE.md names, plus the lesson verifier, which is executable
documentation. That verifier hardcoded an absolute Windows path and would
silently validate against a stale binary, so it now resolves its own repo and
refuses a compiler older than Cargo.toml.
A quoted diagnostic containing an em dash compared unequal on Windows: the compiler writes UTF-8, and subprocess text mode decodes with the locale encoding, so the real message came back mojibaked while the lesson had it right. Every check the verifier does on an `error:` line was exposed to it.
The new CI gate failed on its first run, on Linux only: `math.cbrt(27.0)` is 3.0 on Windows and macOS and 3.0000000000000004 on the ubuntu runner, and `e2e_unit_aware_cbrt` asserted the printed string. A libm may return the nearest representable result rather than the exact one, and which one it does is a property of the platform. These tests are about which computation is emitted, not about the last bit of the answer, so `run_and_check` now accepts a relative difference of 1e-12 when both sides parse as floats. Non-numeric output still compares exactly.
Neither is a documentation problem, so neither belongs in the prose fixes. `let Some x = Some 1` type-checks: a bare constructor name in binding position is read as the function name of `let f x = …`, so the program defines a function called `Some` and the irrefutability rule never sees the pattern. Lesson 8 quotes the parenthesized spelling because of it. And the typed-hole shortlist truncates at six after an alphabetical tiebreak, which now drops `String.upper` from a `string -> string` hole while keeping `String.trimStart`. That cost lesson 9 its worked example, and the fix is a ranking question rather than a cap question.
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.
The 0.5.0 features reached every machine-readable surface (parser, TextMate grammar, all four tree-sitter query sets) and only one prose one, so the documents disagreed with the compiler and with each other.
Prose currency
option {}is the fourth built-in computation expression.DESIGN.mdsaid "exactly three, no more" in its §11 guardrails while saying four in §8.1;RATIONALE.md,README.mdand the Marketplace-facingeditors/vscode/README.mdeach said three. §11 now states the closing rule (one per built-in short-circuit type, one per Python control-flow form) rather than a count, and drops the user-defined-CE deferral, which shipped.Everything below was checked against
src/, not against another document:DESIGN.md§8.1: "whitespace-insensitive (no offside rule at all —lexer/mod.rs)"src/lexer/mod.rs:3documents the offside rule it implementsINTERNALS.md:desugar/,types/units/,cli/(clap),prelude/Cargo.toml[dependencies]is empty, so there is no clap and nofmtsubcommand.src/project/,src/repl.rs,src/kernel.rsand the threelowering/sub-passes were missingCeItem::LetBang { name, name_span, value }Patternsince #57build_callpartial applicationbeta_reduceruns first since #52, so(+) 2islambda b: 2 + bexamples/interop/README.md: the extern import prefix "mis-reads a lowercase class as a submodule"extern importto addeditors/README.mdeditors/vscode/DEVELOPMENT.mdvsce publish, the pathRELEASING.mdand the ROADMAP both record as brokenThe VS Code TextMate grammar highlighted
in, which is not inTok::keyword, and did not highlightimport,tryoras, which are. JetBrains ships that same grammar.editors/nvim/syntax/pyfun.vimhad the same two errors, andeditors/emacs/pyfun-mode.elhad no CE-builder highlighting at all.RELEASING.mdsaid "all four files" over three bullets, and claimed theAssisted-by:header MELPA asked for was already inpyfun-mode.el. It was not — that would have blocked the resubmission that reopens mid-August. It is now, in MELPA's documentedAGENT_NAME:MODEL_VERSIONform. The doc also claimed every versioned artifact tracks the compiler; two are deliberately independent, so it now names the tracked set instead.The CI gap
Nothing ran
cargo test,cargo clippyorcargo fmt --checkon a PR or onmain— the only cargo call in any workflow was abuild --releaseinside the kernel job. That is why a release could ship with the drift above.ci.ymladds the three commandsCLAUDE.mdnames (tests on all three OSes, since the e2e suite shells out to Python; lint once), plus the lesson verifier, which is executable documentation: every lesson solution runs and its output is compared against what the lesson prints.docs/verify_lessons.pycould not have run in CI — it hardcodedC:\git\Pyfun— and worse, it silently validated against whatever binary happened to be intarget/debug. In this working tree that was a 0.4.0 build, so it reported all 23 lessons green against the wrong compiler. It now resolves its own repo, honoursPYFUN_BIN(the conventionkernel.ymlalready uses), and refuses a compiler older thanCargo.toml.Also
examples/hello.pyfunis the showcase file and had nooption {}block; it does now.pages.ymlwas two majors behind onactions/checkout. The tree-sitter README documentedtree-sitter parsebut not the corpus goldens that are the actual gate.Verification
cargo test(all suites),cargo clippy --all-targets -- -D warnings,cargo fmt --check,python docs/verify_lessons.py(23/23), andpyfun run examples/hello.pyfunall pass locally.