►► Audio, Video, and Transcript available: https://lispcast.com/focus-on-composi...
►► Subscribe on iTunes: https://itunes.apple.com/us/podcast/t...
Where should we start when we're designing out data structures--especially the data that we expect to last a long time. The answer is in the composition operations.
Transcript
What is the type of operation that you should focus on first when you're designing an interface? I'm talking before you start doing anything else -- including thinking about the names, or thinking about what kind of data you need to store -- what is the thing that you should be focused on first?
Hi, my name is Eric Normand. These are my thoughts on #functionalprogramming.
We've got these operations in our interface. We've got some entity. We wanted to find the meaning of this entity. By meaning, I simply mean what can you do with it? What information can you get out of it. Those are your accessors, if you want to give that a name. How can I change this thing -- immutably of course -- to returning a changed copy or modified copy?
The operations about how to modify it, how do I make one, the constructors. But then, how do I compose it, right? To me, that is the hardest part of it. How do I compose?
Let's think about an abstraction that has existed for a long time, well before computers existed. It's the abstraction of double-entry bookkeeping. It's a system of accounting that everyone uses now. It was invented in the 14th century. You can credit it with the rise of the modern financial system, because it was that important.
It's a system where it records data. It's a data system -- an information system -- records data about transactions. It has this interesting property to it, which is that it tells you how to add a new transaction.
A naive approach to accounting would be when someone deposits $10, you erase the old amount in their account. You add $10 to and you write that down. In double entry bookkeeping, every account has a book. That was the page in the book.
What you do is you just write down all the information about that transaction. When you boil it down, which they've done over the years, you have an amount. You have the account that is being debited. You have an account that is being credited. There's three pieces of information, and of course, you want the date and stuff like that.
There are three pieces of information that constitute that transaction. The interesting thing to me is, that before you even think about what pieces of data are in that transaction, you have the idea of how you combine transactions.
You have this book, which is a collection of transactions. You have a new transaction. You want to combine onto it. What do you do? You always append it to the end. You never modify anything that's already in there. You just append a new transaction on a new line in the book.
This is the discipline of accounting. Even if there's a mistake, you write a note and you amend a new transaction to correct that mistake. You never go back and change those old things because you want a record of the mistake, too.
What's interesting about this, from a functional programming perspective is that it actually starts with this combined function, this composed function. When you add a transaction to the ledger, the book, you are doing it in a disciplined way. It's append only.
We need to do that when we are designing our data. We need to think how do I combine this? How do I add new data to my system? I'm not saying you have to do append-only, I'm saying you should start with the combinations of data. You should start with the functions, the operations, the calculations. If you will that, take two pieces of data and combine them into a third piece of data.
These are the hardest to design and they're the ones that are going to constrain the representation of that data the most. Notice in a ledger, in an accounting book, it's append-only which implies an order. It implies a place to add new stuff at the end. You're already constrained in what kind of data structure you can use for your ledger.
You're not so constrained in how you represent each transaction. You probably use a map with a debit, a credit and an amount, probably the date. Maybe some metadata on it like who recorded this transaction, stuff like that. In principle, if it's a map you can always add that stuff. Some systems might be interested in and some might not.
It's less constrained. It's obviously less constrained. What is constraining is the operation of adding. It really helps you design because the constrain will help you navigate all the possible options for how you design its data. It'll eliminate so many that don't...It wouldn't make sense for you ledger to be a map. Not just a map. #clojure #functionallanguage