S7 Design Notes
Meaningful Values, Explicit Contracts, and Composable Operations in R
Preface
These are working notes on designing object systems with S7 in R and on the larger programming ideas that determine whether such systems clarify a domain or merely add ceremony. They ask one recurring question:
What knowledge can the model carry so that the rest of the program no longer has to rediscover it?
The answer is a style of design, not an S7 API catalog. Define what a meaningful thing is, establish the contracts that can be established at its boundary, and then build the program from those things and operations that preserve or deliberately transform their meaning. The contrast is practical: without a domain model, each consumer receives loose data and must rediscover whether a string is an identifier, whether two endpoints are ordered, whether an omitted field differs from null, and whether a failure should stop or accumulate. With a good model, those decisions have names and homes.
S7 contributes nominal classes, properties, validation, and generic dispatch, but the larger subject is how to make domain concepts, admissible states, relationships, and operations explicit. The notes therefore move repeatedly between mechanics and consequences: not only what S7 permits, but what a choice lets downstream code stop doing.
The intended outcome is practical. A reader should be able to identify concepts worth naming, place each rule at the boundary that can enforce it, choose between a reusable property and an independent class, distinguish an editable value from a or a , design nouns and verbs together, and show which checks and branches disappear from downstream code. The goal is not maximum typing. It is a representation whose extra structure pays for itself in simpler consumers.
Evidence and register
The prose moves among four kinds of claim. A documented mechanism is behavior promised by official documentation. A version-verified mechanic has also been exercised against the stated R and package versions; it is a fact about those versions and should be rechecked after relevant upgrades. A published example is a design observed in public package source, documentation, or tests. Recurrence across independent packages strengthens the example, but neither recurrence nor popularity turns a pattern into a law. A recommendation is the editorial conclusion drawn from mechanisms, examples, and trade-offs. Imperative language states a strong default that may be overruled for a stated reason, not an exceptionless command.
This distinction matters because the chapters intentionally braid API facts, empirical observations, and design judgment. A validator running after replacement is a mechanic; choosing a class validator as the home of a particular relationship is a design decision. Readers should be able to tell which kind of claim they are being asked to trust.
The inquiry ledger records version-sensitive claims, unresolved tensions, and the evidence that would change a recommendation. Public sources are collected in the sources appendix. Examples and provenance in the published notes are limited to public source, documentation, tests, specifications, talks, and literature. Private code, local notes, and chat transcripts are not evidence here.
How to read
The chapters form an argument, but they can also be entered by problem. The overview states the whole position in miniature. The first three chapters establish the foundation. Object Systems explains why R’s message-passing and generic-function traditions lead to different designs and why S7 asks for a vocabulary of verbs as well as nouns. Values and State separates editable values, , and , then follows the consequences into aliasing, process boundaries, MVU, and grouped replacement. Types and Meaning is the conceptual center: it connects , , presence and defaults, wire representations, and the co-design of domain nouns and verbs.
The next three chapters ask where laws and variation belong. Parse, Don’t Validate places checks at the smallest boundary with enough information and explains what construction can and cannot certify. Composition and Dispatch separates unions, variant families, inheritance, interfaces, and failure protocols. Documents, Schemas, and Languages treats documents as compiler input: representations that must preserve, normalize, and sometimes defer to external authority.
The ecosystem field guide then tests these ideas against public packages. The doctrine compresses the argument into reviewable defaults, the playbooks organize common opening situations, and the middlegame compares plausible representations once real constraints begin to interact. The glossary collects the recurring design vocabulary, while the inquiry ledger keeps unsettled or version-sensitive claims visible rather than smoothing them into doctrine.
If you read only two chapters, read the overview and Types and Meaning. If you are beginning a design, use the playbooks alongside them. If you are debugging a modeling decision, begin with the chapter whose boundary is in question: lifecycle, contract placement, alternatives, or wire projection.
Editorial policy
These notes are deliberately opinionated, but they are also revisable. A counterexample belongs in the inquiry ledger before it silently weakens a recommendation. A pattern seen once remains an example; repeated independent public sightings can strengthen it. Version-verified mechanics remain tied to their version until rerun. New playbooks should correspond to genuinely new design situations, not merely new packages wearing familiar shapes.
Most importantly, corrections are additive when the evidence allows it. A qualification should narrow an overclaim without erasing the useful reasoning that made the claim memorable. “S7 objects are immutable,” for example, is too strong; the better account distinguishes replacement-based editable values, read-only API policy, and reference-valued payloads while retaining the local reasoning that value-oriented design buys. The same standard governs the book: preserve the mechanism, restore the argument, and state the boundary.
Corrections and counterexamples are welcome through the issue tracker.