This is the third post in a series about my current Clojure workflow.
Having discussed Emacs setup for Clojure, I now present a sort of idealized workflow, in which I supplement traditional TDD with literate programming and REPL experimentation.
First, some questions:
The answer to (a) is, of course, by having good tests; and the best way I know of to maintain good tests is by writing test code along with, and slightly ahead of, the production code (test-driven development, a.k.a. TDD). However, my experience with TDD is that it doesn’t always help much with the other points on the list (though it helps a bit with (b), (c) and (e)). In particular, Rich Hickey points out that TDD is not a substitute for thinking about the problem at hand.
As an aid for thinking, I find writing to be invaluable, so a minimal sort of literate programming has become a part of my workflow, at least for hard problems.
Now for the workflow proper. Given the following tools:
then my workflow, in its Platonic Form, is:
“Writing” in each case above refers to updating comments and docstrings, as described in a subsequent post on Literate Programming.
Here are the above steps as a flow chart:
The workflow presented above is a somewhat idealized version of what I actually manage to pull off during any given coding session. It is essentially the red-green-refactor of traditional test-driven development, with the explicit addition of REPL experimentation (“REPL-driven development,” or RDD) and continuous writing of documentation (“documentation-driven development,” or DDD) as a way of steering the effort and clarifying the approach.
The utility of the REPL needs no elaboration to Clojure enthusiasts and I won’t belabor the point here. Furthermore, a lot has been written about test-first development and its advantages or drawbacks. At the moment, the practice seems to be particularly controversial in the Rails community. I don’t want to go too deep into the pros and cons of TDD other than to say once again that the practice has saved my bacon so many times that I try to minimize the amount of code I write that doesn’t begin life as a response to a failing test.
What I want to emphasize here is how writing and the use of the REPL complement TDD. These three ingredients cover all the bases (a)-(e), above. While I’ve been combining unit tests and the REPL for some time, the emphasis on writing is new to me, and I am excited about it. Much more than coding by itself, I find that writing things down and building small narratives of code and prose together forces me to do the thinking I need in order to write the best code I can.
While I don’t always follow each of the above steps to the letter, the harder the problem, the more closely I will tend to follow this plan, with one further modification: I am willing to wipe the slate clean and begin again if new understanding shows that the current path is unworkable, or leads to unneeded complexity.
The next few posts attack specifics about testing and writing, presenting what I personally have found most effective (so far), and elaborating on helpful aspects of each.
© 2016 John Jacobsen. Created with unmark. CSS by Tufte-CSS.