Vocabulary package: publishing your own classifying vocabulary
Area: Vocabulary & packages Teaches: a package can publish its own introducer metatypes, an introducer metarel, upper categories, and a catalog
check— the building blocks a foundational ontology like UFO is made of. None of this is built into the language; it is all ordinarypubsurface. Prerequisites: the meta-calculus introducers (metatype/metarel), see hello. Run:ox build examples/vocab_pkg_v0 && ox check examples/vocab_pkg_v0
This is the author side of the two-package vocabulary journey. vocab_pkg_v0 ships a small UFO-shaped vocabulary; vocab_consumer_v0 (a separate package) depends on it. The point is that Argon has no privileged ontology: a vocabulary is a normal package, and everything that makes UFO “UFO” — the kinds, the categories, the well-formedness checks — lives on this package’s public surface.
What to read in root.ar
Introducer metatypes — declaration keywords for the consumer. A metatype published pub becomes a keyword a downstream package declares its concepts with:
pub metatype category = { };
pub metatype kind = { };
A binary introducer metarel. Same idea, for relations: a published metarel is a keyword for declaring relations downstream:
pub metarel characterization<A, B>(a: A, b: B);
Upper-ontology categories the consumer specializes. These are concepts declared with the package’s own category introducer, forming a small hierarchy the consumer hangs its domain off of:
pub category Endurant;
pub category Substantial <: Endurant;
pub category Detached <: Endurant;
A catalog check the vocabulary ships — and that fires on the consumer’s catalog. This is what makes a vocabulary package real rather than decorative. The check is #[static] and every variable is TypeRef-sorted, so it discharges at ox check/ox build time over the catalog of declared types — not over runtime individuals:
#[static]
pub check OrphanKind(k: TypeRef) :-
meta(k) == kind,
specializes(k, Detached)
=> Diagnostic {
severity: Severity::Warning,
code: "UFO::W001",
message: "a `kind` specializes `Detached` — specialize `Substantial` instead",
};
It reads the reflective intrinsics meta (the metatype a concept was introduced with) and specializes (the declared hierarchy). It flags any kind that specializes Detached. Crucially, the check is written here, in the vocabulary, but it runs against the consumer’s pub kind declarations — imported checks travel with the vocabulary.
Running it
The vocabulary checks clean on its own — it declares no offending kind itself:
$ ox build examples/vocab_pkg_v0
wrote examples/vocab_pkg_v0/target/root.oxbin (7 events, 4334 bytes)
$ ox check examples/vocab_pkg_v0 --codes
ok
To see OrphanKind actually fire, you need a consumer with a catalog that violates it — that is the next example, vocab_consumer_v0.
Honest caveats (what runs today)
- This package declares no
pub queryand no individuals; it is pure vocabulary. Its value is realized at a consumer’sox check—vocab_pkg_v0alone has nothing for the check to fire on.
This example and its consumer are driven through the real ox binary by a pipeline test (oxc-driver/tests/cli_pipeline.rs): the test pins that this package checks clean and that OrphanKind fires on the consumer’s catalog, so the cross-package check can’t drift from the language.