When we focus our efforts on Formats over Functions, we focus less on implementation and more on standardization. This is the key to longer lasting code.
"Functions" are selfish - they assume all code is written for them and them alone, and as a result the API bleeds all over the place. "Formats" are more generous - they only assume conventions - and the library/framework code lives outside the file so that other libraries/frameworks can write to it as well.
When we write imperative code in Functions, there are a lot of ways we can shoot ourselves in the foot, and it tends to be more verbose. This is why our code tends towards more declarative over time as we better understand our problem space. When we are confident we understand the problem well, we should move this to Formats, which are the ultimate declarative form with no implementation detail involved.
Formats deal mainly in simple values, whereas functions have to be evaluated. Here I am very inspired by Rich Hickey's Value of Values talk. The idea is that values have a transitive property - every nested property of a value is itself a value - therefore it is completely static and reliable and can be statically extracted without evaluation, or copied and modified without side effects.
Here are examples of successful Formats over Functions:
package.json: Multiple tools can read package.json without getting in each others' way. There is no spec for it though, which is occasionally a problem, but there are attempts and unofficial guides.
- Storybook's Component Story Format frees Stories from the prison of Storybook's proprietary functions, enabling it to be consumed by design tools and other tooling.
- xState moves state management out of proprietary library/framework functions into the tried-and-tested SCXML specification.
- Infrastructure as Code replaces human functions in the loop (ClickOps) with code formats - at first proprietary per cloud, and then agnostic across clouds (debatable if multicloud IaC is valuable)
- The success of GraphQL: When Lee Byron and co open sourced GraphQL, they didn't open source the FQL/Ent implementation that was used in Facebook. That wouldn't have been very useful to others who don't use XHP/PHP. They rewrote it from scratch and chose to solidify a GraphQL spec first, and then write a JS reference implementation. This choice helped it stay agnostic of implementation details, and allowed both server and clientside implementations of it to proceed independently, leading to the exponential success of GraphQL as a protocol.
- libc (thanks b0rk) is another example of a command standard/interface. Because everyone speaks libc but doesn't have to use the same libc implementation, you can use DNS and it works the same in every language and platform.
- CPU Instruction Set Architectures - any two CPU's that implement the same ISAs will be able to run the same code, regardless of their underlying implementation.
- Email. Email works everywhere regardless of implementation detail.
- Wikipedia has more standards: in particular, BGP, Barcodes, ISBNs, QR codes, Uniform resource locators, vCards
More examples of ongoing movement:
- React Components -> Redwood Cells
- Blockchain development moving from Protocols > Platforms https://medium.com/@lightcoin/from-platforms-to-protocols-c5fe0bdd0fc7
- Twitter is looking at becoming a decentralized format (actual success to be seen)
- Epistemic status: This is a general idea I've increasingly been referring to as a programming principle/design pattern - but I don't pretend to have good definitions and examples locked down yet. But I'm pretty sure the thesis is right - I just have to scope it down to the boldest correct form of the argument.
- Epistemic effort: I've had a stub post on this since October but I figure I better flesh it out a bit - but be warned I know it is a little vague still.