Clojure Gazette 180: “How do you structure your apps?”
Eric Normand · Published July 4, 2016
“How do you structure your apps?”
Issue 180 – July 04, 2016
I want to run a Clojure training in your area. See the message at the end of the letter.
Do you ever get stumped repeatedly by the same question? One of the most common questions I get asked is “how do I structure a functional program?”. And it stumps me every time. I never have an answer because I can’t figure out what they mean. It’s become a kind of puzzle for me that I come back to now and then.
I’ve started seeing this question as an opportunity to learn more about the puzzle. “What do you mean structure?” is now my canned riposte. I really want to know what they’re getting at. So far, it’s only revealed that they don’t know well what they’re asking.
But there must be something there! So many experienced programmers have asked me the same question. I’ve tried many times to write up an article called “How to Structure Functional Programs”. But I get nowhere each time. I just get trapped by the same puzzle. “What do you mean by structure?”.
Do they mean a design pattern, like MVC? Maybe they want a guiding pattern to help them separate concerns in their app. I actually think MVC does really well for web apps in any paradigm, not just OO. I will suggest doing that, but it doesn’t satisfy the question when I do.
It could mean “organize your code”. Object Oriented languages have an automatic unit of code organization that FP doesn’t have. A method belongs to a class, and typically a class belongs to a file. Perhaps they’re looking for this basic sorting device that just isn’t there. In that case, they should just get used to imposing their own organization using namespaces or modules.
In Clojure, I literally don’t think about organizing my code until it gets longer than 100 lines. At that point, I start looking for logical ways to divide it in two. In an OO language, I often see people doing this organization up-front. To me, organizing code is no more interesting than organizing a sock drawer. You don’t really need to organize socks until you get a lot of them. But this answer does not satisfy them either.
When I get really deep in thought over this, I think maybe they want a process for writing their code. There’s kind of a strawman, oversimplified process for making classes in OO. You take a natural language description of the problem. Then you underline all of the nouns–those become your classes. Then you underline all of the verbs–those are your methods. This doesn’t really work, but it sounds good and could actually be a starting point for learning to model a problem in OO. But it’s like paint-by-numbers. Paint-by-numbers gets rid of all of the hard work of painting, which is all about seeing the world, and turns it into a mechanical act of applying paint to a canvas. This OO process turns modeling into a mechanical act of making classes with methods and references. It’s like UML diagramming in code. It could be good practice for writing code, but it rarely leads to good models. And it always leads to a proliferation of useless classes.
One day recently in the shower, I realized the answer. And it’s so simple. How do you structure a functional program? With the same structure as the problem. This principle applies to any paradigm, but it’s obscured by OO languages.
People often talk about how nice functional programming is because you can get right to the point and deal with the problem you’re trying to solve instead of setting up object graphs and coordinating message cascades. If FP, you’re not initializing objects, setting their fields, performing a sequence of operations to get them to do your work. I daresay that classes and methods are not the best way to model most problems. They lead to a focus on design patterns and other distractions from the problem itself.
The universal process for structuring software to solve a problem: first, understand the problem to some degree, which includes concepts and their relationships. Second, map those concepts and relationships to constructs in the language. Third, write a solution using those constructs, which will deepen your understanding. Then repeat all the steps as many times as needed.
And this process could be the scariest thing about functional programming. The process is so sparse. You’re confronted by your lack of understanding in the very first step. It takes work to understand the problem and the constructs of the language well enough to start mapping between them.
Of course, that’s okay because you don’t have to understand it that well to get started. It’s an iterative process. But it also has a clarity to it that functional programmers can appreciate. Proficiency is determined by how well you understand the constructs of the language. To me it’s a ray of hope: master a handful of composable parts and you can program anything. There’s little need to study esoteric books about design patterns or keep up to date on the latest framework. It’s just you and the code.
As a teacher, I benefit so much from live, in-person trainings. It helps me refine my material and get essential information about what people need to learn. So, I’d love to do a training in your area, if there are enough people to fill it up. Imagine two days of intensive Clojure! You’ll learn so much. Let me know where you’d like the training by filling out this easy survey. I need to fill the trainings to justify the cost of travel, so get your friends to complete the survey, too!