~ / track C / clojure ecosystem

Data-oriented programming

Intermediate

In an object-oriented design, behavior lives with the data: each class defines its own methods, and changing the shape ripples through dozens of files. In data-oriented programming the data is a plain, transparent value — a map or a vector — and functions operate on it from the outside. Anyone can read it, anyone can transform it; nothing is hidden, nothing is private.

The slogan: generic data + generic functions > specialized objects.

Minimal example

Represent a domain value as a plain map. There is no constructor, no class, no DSL — just keys and values:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

The "methods" are ordinary functions. They take the data as a first argument and return a new value:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

Practical example

Because the data is just data, many small functions compose freely. Here a discount pipeline applies independent transforms without any object lifecycle to manage:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

Notice the pipeline: a chain of pure functions, each producing the next version of the order. The original order is untouched.

Where it pays off

  • Logging, serialization, debugging come for free: a value is just a printable map. There is no toString/__repr__ to keep updated.
  • Tests are trivial: build a map literal, call the function, compare to a map literal. No mocks, no fixtures.
  • Tools compose: every function that works on maps in general (assoc, merge, select-keys, walk, spec) works on yours.

The trade-off: there is no compiler-enforced schema. Tools like clojure.spec or Malli cover that gap when you want it.

Check yourself

? quiz

What is the practical implication of representing the `order` as a plain map instead of an `Order` class with methods?

Exercise

Add a :notes field to an order without modifying any existing function. Then write add-note, a pure function that appends a string to :notes (creating the vector if it doesn't exist).

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate
 status: new