Smart Objects, Dumb Code — Through the Yoneda Lens
In software design, there’s an old maxim: “smart objects, dumb code.” Push logic inside the objects. Keep the calling code thin, declarative, and boring.
From an object-oriented perspective, this is about encapsulation and cohesion — give your objects the authority to manage their own invariants. From a functional or category-theoretic perspective, it’s the Yoneda Lemma in action:
An object is completely determined by how it behaves in all contexts.
The Yoneda Connection
The Yoneda Lemma tells us that an object’s identity is entirely expressed by its morphisms — the ways it can interact with the rest of the world. In programming terms:
- If you can describe every way an object can be used (its API),
- You’ve captured everything you need to know about it.
This is exactly what “smart objects” aim for: Their interface is the whole truth. You don’t need to dig inside, copy data, or reimplement logic. Just compose behaviors.
In Petri-Net Terms
A Petri net is the smart object. It knows:
- Which transitions are enabled,
- What tokens will move,
- Which states are reachable.
The calling code is “dumb”: it just asks the net to fire transitions. It doesn’t recalculate reachability or second-guess invariants — it trusts the model.
The Guideline
Design your systems so that:
Objects are fully knowable by their interactions. (Yoneda)
External code never duplicates internal rules. (Encapsulation)
Composition happens outside, computation happens inside. (Cohesion)
That’s how you get maintainable, composable systems — whether you’re building a banking backend, a game engine, or a blockchain module on gno.land.