In the last Clojure Developers Barcelona meetup, we started to use re-frame to animate in the browser the code to evolve cellular automata that we wrote some weeks ago.
We managed to make a rough version but we didn't have time to test it and make it nice.
When I got home I redid the exercise from scratch using a mix of TDD and REPL Driven Development.
First, I coded a couple of evolution rules. These are their tests:
and this is their code:
Next, I coded the cellular automata evolution, these are its tests:
and the resulting code:
Once I had the evolution working, I started to work on the view, using Figwheel and a hard-coded list of cellular automaton states on the db. This way I focused only on rendering the list of cellular automaton states.
With that working, I played on the REPL to create a subscriber that reacted to changes on the cellular automaton states making the view render.
This is the resulting code of the view:
the code of the subscriber:
and the default db:
Then, I used TDD to write the event handlers.
The use of effects keeps re-frame handlers pure. They allow us to avoid making side effects. We just have to describe as data the computation that will be made instead of doing it. re-frame takes care of that part.
These are the handlers tests:
these are the handlers:
Notice, how in order to dispatch to another handler (a side effect) we just have to add a key-value pair to the map of effects returned by the handler. In this case, I used the :dispatch and :dispatch-later effects which are part of re-frame's built-in effects. You can also create and register your own effects (I will talk about it in some future post).
To see the whole picture this is the code that registers the handlers:
I think that effects and coeffects (I'll talk about them in a future post) are just great!
They make testing handlers logic very easy (since handlers keep being pure functions) and avoid having to use test doubles.
Finally, everything is put together in the core namespace:
You can see the cellular automaton evolving in this video (I used garden library to add some CSS to make it look nicer):
You can find the code on this GitHub repository.
In this post I've tried to, somehow, describe the process I followed to write this code, but the previous gists just reflect the final version of the code. If you want to follow how the code evolved, have a look to all the commits on Github.
I really love using ClojureScript and re-frame with Figwheel.