Build your Core Abstraction
With limited development time, where should you focus your efforts? You should build something timeless at the center of you application to create a strong foundation to build on top of. I call that you Core Abstraction.
Eric Normand: If we have limited development resources, meaning limited time, limited budget, limited number of programmers, where should we invest those resources, if we're looking to improve the stability and the maintainability of our software?
Hello, my name is Eric Normand, and these are my thoughts on functional programming. I have this idea, a concept that I came up with. I'm not sure if it's related to any other ideas. Like a lot of ideas, I've probably read it somewhere. I forgot about it.
It must be similar to some ideas in domain-driven design, where you have a common vocabulary that you use between both the programmers and the business concerns. There's something in there. My idea — I call the core abstraction.
What this is...You can have multiple core abstractions in your software. A core abstraction is something that is central to the operation of your business. It's something core because it's fundamental, it's down right in the middle of everything, in the heart of everything.
That is what you want to get right. All the stuff about the UI and what buttons look like, even what buttons to show, that stuff is not part of your core abstraction. That is just temporary. It'll change with the seasons. There are things in there that are going to be built on layer upon layer upon layer.
You're never going to get back in there and fix them. You want to get those right from the beginning. What is an example of a core abstraction? The example I'd like to use the most is from accounting. The system of accounting that virtually everyone uses nowadays is called double entry bookkeeping.
It has a core abstraction which is the ledger. It's a list of transactions that happen at your bank or at your company. That's it, that's all it is. Everything's about these rules for how you add stuff to the ledger. That's basically it.
This core abstraction of an append-only list of transactions is what powers all of it. All the policies of the bank, the procedures, and the ways the accountants operate on it. They're all based on those simple rules of how you add transactions to the ledger.
It's something that's been in use for hundreds of years. It just works. It's probably never going to change. What we're looking for when we're developing software, is something that gives us high leverage.
This is an advantage you can have by having a high leverage abstraction. Then you solidify it by making it totally well-defined, get rid of the corner cases. Make sure it works in a solid way, no bugs, no corner cases, stuff like that. Then you can build on it.
I worked for a company that did electronic document signing. It's not cryptographic signing of the document. It's signing it like you sign a contract. They would send out PDFs to everybody.
You could go onto the website. You could click a button, or you could sign with your mouse saying, "I read it and I agree." At first, we were using a very typical rest model where it was just like we had some operations for when the user would view the document.
We would make a little note that they viewed it. When they signed it, we would make a note that they signed it. It just felt very loose. It wasn't a very well-abstracted model. It was just let's just start recording a little bit of data.
At some point, I went deep into it and really started investigating. What does it mean to sign a document? I started reading about it. I talked to a lawyer or two about what it meant.
I've read a tiny bit of the history of signing documents and contracts. I really started to understand from a domain point of view, what it was all about. What it was all about was gathering evidence about the agreement, the signature and like initialing the pages, all of that.
It's all about evidence for yourself, and for the other party that this was the same paper that you read five years ago when you signed the contract. If there's ever a dispute, "Yes. You're right. I did sign this. That is my signature." What it really is, is an evidence gathering document. You put more evidence onto this paper. You put your blood on it. [laughs]
You sign it. You initial all the pages. You number the pages so none are missing. All these little artifacts that you gather on the document that are evidence for later if anything goes wrong. We started to reorient the abstractions in our system.
The software to be about evidence gathering, collection, and maintenance for the long term, for the future. Everything we did was just like aggregating more evidence onto it. Any operation that modified the document was appending new evidence onto it.
We developed a very strong model with a very good core abstraction that gave us business leverage. It gave us an advantage, of business advantage over other systems, because the other systems weren't doing that.
The other systems were doing what we were doing at first, which was just willy-nilly saying, the whole agile way of saying, "We need a checkbox that says that they agree." We would just put a checkbox that said they agree.
We would record that in a database. There was no unifying model. There was no nice model of how things should change over time and stuff like that. We really developed this nice core abstraction. Ever since then, it's been something I'm always on the lookout for.
It requires you to understand your domain better than, then you might already understand it. I had to do all this research into what signing a document actually meant. I was glad I did. I learned the ton of stuff.
I developed this abstraction that actually captures the stuff that lawyers are thinking is supposed to be happening. They want evidence later that they can present in court that ever gets there.
The best way to preempt a trial, or a suit is to have more evidence so that you don't even have to get to that point. You are so clear who's going to win. And no one wants to fight. This is my idea — core abstraction.
It's something that you're going to build layers on. Certainly your UI is going to be built on top of it. The possible operations are built out of the operations of your core abstraction.
There's all the other stuff, the logging and all the junk that accumulates in your software for good reasons. It's going to be based directly on that. You could actually log all of the model operations, the core abstraction operations, and make something that happens automatically, because you enumerated them.
They're a small number. You get rid of all the corner cases. It's just going to be this tight little system, that's worth putting more effort into, because everything else is going to be built on top.
You're not going to have some operations that are poorly defined. That are just defined in a use case somewhere, in a user story like we need a checkbox on the front page. You don't really store exactly what the person thought you would store.
Later, they're like, "OK. Now show me all the documents that have a checkbox." And you haven't done that. There's no index. There's no way to get at that information. You just didn't know that that was coming down the pike.
If you have a more robust model, then makes sense to everyone. It's going to be easier to use, and harder to get wrong. All right. My name is Eric Normand. These have been my thoughts on functional programming.
If you like this idea — this core abstraction idea — if you've built something like that, where you had a core abstraction, something deep in the software that really defined and constrained what was possible in your software in a good way, constrained it to the happy path, please let me know.
I'm curious to know if this is something that other people already do, and I just somehow missed the boat, or if this is really truly something that I've come up with, please let me know.