Skip to content

Document the reference implementation as an engine - #26

Draft
Jim Garrison (garrison) wants to merge 3 commits into
mainfrom
reference-as-engine-docs
Draft

Jim Garrison (garrison) wants to merge 3 commits into
mainfrom
reference-as-engine-docs

Conversation

@garrison

Copy link
Copy Markdown
Member

Documentation for #25, which makes a domain's own implementations addressable as an engine named "reference". Split out so the prose reviews on its own.

Branched from main rather than from #25, so this diff is prose only. The consequence is that the docs build renders the active_engine cross-reference as plain text instead of a link, because that function does not exist on main yet. It resolves when #25 merges. (Sphinx does not fail on it because this project does not enable nitpicky mode, so the -W build still passes.)

The vocabulary needed less revision than expected

The overview already defines an engine by what is substituted — a coherent unit of behavior, state, and invariants, chosen as a whole — rather than by who wrote it or how fast it is. The reference implementation fits that definition unchanged, so most of this makes an existing idea explicit rather than redefining anything.

Two new FAQ entries

"Is the reference implementation an engine?" gives the structural argument: materialize() builds the class every engine inherits from, and dispatch does not branch on the two cases. It also says why "reference" rather than "default" — default describes only what happens when nobody chooses, while reference describes what the implementation is, which stays true when it is selected deliberately. The HPC sense (reference BLAS, reference LAPACK) is the precedent.

"Why can the reference implementation be enabled explicitly?" explains the case silence cannot cover: an environment variable overrides a default but must not override an explicit choice.

The one-way contract needed the most care

"Enable the reference implementation" can read as a disable or a reset, which the contract forbids. It is neither — it is a transition forward into a settled state that rules out the other engines, in exactly the way enabling any engine rules out the rest. Both the overview and the FAQ now say so, and the contract is phrased in terms of transitions rather than of which engine is chosen.

Other changes

  • The overview's three-party model notes the parties are roles, not necessarily three packages, since the domain now fills the engine role for its own reference implementation.
  • The user guide's "Query the available engines" section said a mechanism was expected in the future. available_engines() exists, so it documents that instead, including that the list is never empty — checking it for emptiness is the plausible thing for a reader to try.

"default" audit

Existing prose using "default" was audited and split by what the word is doing. Where it named the implementation, it now says "reference": the class materialize() builds, the representation a program might mix with an accelerated one, and the counterpart to "accelerated" in a contrast. Where it meant what happens absent a choice, it stays "default": the behavior a user keeps by not opting in, the candidate defaults materialize() locks in before any engine exists, and the implementation used when nothing is enabled.

The distinction is that "reference" names which implementation it is, while "default" describes how it came to be selected. One consequence worth a look during review: overview.rst now says "lock in the defaults" and "the class that is the domain's reference implementation" a few lines apart. I believe that is correct rather than inconsistent, since the first is about candidate defaults and the second about the resulting class, but it is a judgment call.


This pull request was generated by Claude Opus 5 under my guidance.

Follows the API change that makes a domain's own implementations addressable as
an engine named "reference".  The vocabulary needed less revision than expected:
the overview already defines an engine by *what is substituted* -- a coherent
unit of behavior, state, and invariants, chosen as a whole -- rather than by who
wrote it or how fast it is, and the reference implementation fits that
definition unchanged.  So this mostly makes an existing idea explicit.

Two new FAQ entries:

- "Is the reference implementation an engine?" gives the structural argument
  (materialize() builds the class every engine inherits from, and dispatch does
  not branch on the two cases), and says why "reference" rather than "default":
  default describes only what happens when nobody chooses, while reference
  describes what the implementation is, which stays true when it is selected
  deliberately.
- "Why can the reference implementation be enabled explicitly?" explains the
  case that silence cannot cover, since an environment variable overrides a
  default but must not override an explicit choice.

The one-way activation contract needed the most care, in both the overview and
the FAQ.  "Enable the reference implementation" can read as a disable or a
reset, which the contract forbids.  It is neither: it is a transition forward
into a settled state that rules out the other engines, in exactly the way
enabling any engine rules out the rest.  Both places now say so, and the
contract is phrased in terms of transitions rather than of which engine is
chosen.

The overview's three-party model says the parties are roles rather than
necessarily three packages, since the domain now fills the engine role for its
own reference implementation.

The user guide's "Query the available engines" section promised a mechanism in
the future; available_engines() exists, so it documents that instead.  It also
warns that the list is never empty, because checking it for emptiness is the
plausible thing for a reader to try.

Existing prose saying "default" was audited.  Where it named the implementation
it now says "reference": the class materialize() builds, the representation a
program might mix with an accelerated one, and the counterpart to "accelerated"
in a contrast.  Where it instead meant what happens absent a choice, it stays
"default" -- the behavior a user keeps by not opting in, the candidate defaults
materialize() locks in before any engine exists, and the implementation used
when nothing is enabled.  The distinction is that "reference" names which
implementation it is while "default" describes how it came to be selected.

Assisted-by: Claude Opus 5
@coveralls

Coveralls (coveralls) commented Oct 2, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 37349101361

Coverage remained the same at 86.047%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 215
Covered Lines: 185
Line Coverage: 86.05%
Coverage Strength: 0.86 hits per line

💛 - Coveralls

@garrison Jim Garrison (garrison) changed the title Document the reference implementation as an engine Add available_engines() and active_engine() introspection functions; document the reference implementation as an engine Oct 2, 2026
@garrison Jim Garrison (garrison) changed the title Add available_engines() and active_engine() introspection functions; document the reference implementation as an engine Document the reference implementation as an engine Oct 2, 2026
@garrison Jim Garrison (garrison) added the documentation Improvements or additions to documentation label Oct 2, 2026
Audits the existing uses of "default" against the vocabulary this branch
introduces.  The two words answer different questions: "reference" says what
the implementation is, while "default" says only that it is what you get when
nobody chooses.  They happen to pick out the same thing today, so most
sentences read correctly either way.

They are not guaranteed to stay that way.  A domain could come to ship an
engine that is used unless something else is enabled, at which point the
default would be that engine while the reference implementation would still be
the reference implementation.  Prose that says "reference" where it means the
implementation stays correct through that change; prose that says "default"
becomes ambiguous, or wrong.

Two sentences were in the second category and are now fixed:

- The user guide said that absent an explicit choice, "the default
  implementation is used".  With a default engine that is simply wrong, and it
  is the sentence a user is most likely to rely on.
- The overview said a user declining the accelerated code "keeps the library's
  default behavior".  Same failure, and naming the reference implementation is
  more precise today regardless, since the bullet is about acceleration being
  optional.

The overview's description of materialize() is also fixed.  It said the call
locks in "the defaults", which is the same ambiguity; what the method actually
does is build the class that is the domain's reference implementation, so it now
says that.  No use of "default" survives in these files outside the FAQ passage
that discusses the word itself.

The FAQ entry explaining the choice of word now gives the future-default-engine
reason, which is a better argument for it than readability alone.

Assisted-by: Claude Opus 5

This branch has not been deployed

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

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants