What counts as public API#
A function belongs in the public API, as to_spec and to_latex do, when
both of these are true:
- The same file gives the same answer.
to_spec('spec.yaml')returns the sameSpectoday, tomorrow, and on a machine with no data and no solver. A function whose answer depends on data, a solver, the network or the clock cannot join. - No rule lives only in the code. Every rule the function applies is written on a page of this reference, so somebody could rewrite the function in another language from the pages alone and get the same answer.
Where a feature can be a key in the file, it is one, because a key shows up in a git diff, the typesetter prints it, and an engine in another language reads it.
The operators a spec may use are a separate question, answered by the limits.
Where a name lives#
The top level of the package holds the functions you call. Every other public name is in one of three modules, and how you get the name decides the module:
| You get it | It lives in | Such as |
|---|---|---|
| by calling a function | mathspec |
to_spec, merge, typeset, advice |
from what a Spec holds |
mathspec.spec |
Spec, VariableSpec, BUILTIN_NAMES |
from what a Program holds |
mathspec.program |
Program, Sum, Mask, Advice |
| by catching it | mathspec.errors |
LanguageError, SchemaError |
SymbolTable and FormatName are also at the top level, because you make
them to give them to the typesetter. tests/test_public_surface.py checks
that each module obeys its rule.
Every other module starts with an underscore and is private. Import from the
four modules above: from mathspec import to_latex.
What every function keeps#
- A function keeps no state. It uses no registry, no plugin, and no setting
that changes what a spec means.
symbols=on the typesetter is an allowed option, because it changes howloadprints and nothing about whatloadis. - A function returns a value or raises an error, and nothing between.
to_speceither returns aSpecor raises an error that names the rewrite.advice()is separate: it reports on a file the language accepts, and changes nothing. - A function writes nothing out unless the caller asks. A
piecewise:orsos:entry stays an entry until the caller callsspec.expand().
Each engine decides what a solver or file format can take, how the numbers attach to the names, and which solver runs (what counts as language).