Last post I talked about implementing the Genetic Algorithm equivalent of "Hello World" in Python. Since I was learning Clojure around the same time, I decided to implement the algorithm the newer language as well.
Already having the iterative Python program written, it was strange to move to the functional Clojure. I made a point not to write a port of my previous program; I used the knowledge and experience from writing the algorithm in Python, but made sure to "think" in Clojure while I was writing.
In Python, my script's main logic was contained in one large function with a while loop.
In Clojure, this became a small recursive function which called started a chain of calls to other small functions.
While the Python script could have been written with more helper functions like the ones used in Clojure, the language does not push you in that direction the same way you get with functional languages (obviously). Therefore, the large function with the while loop seems natural in Python, just like how lots of small functions seems completely natural in Clojure.
One of the major benefits I've realized while playing with Clojure is how easy unit testing becomes when the language pushes you to write small functions with no side effects. Every function has a suite of obvious tests. This concept mostly failed for this particular project however, since the reliance on using random selection in many functions made unit testing mostly impossible for them. I tested every function when it seemed natural to do so, but my experiments on testing functions with regular but randomized output were too convoluted to actually use.
There is one problem I have with my Clojure solution that I have been unable to solve. It runs much slower than the equivalent Python version. I have hooked it up to Java's VisualVM to do some profiling, but I was unable to get helpful results. It showed (I think) that most of my time was spent sorting the solution set. While this does make sense, the algorithm is much cleaner with the sort- and in any case, the Python version has the same sort in the same spot. I plan to look in to this issue more (following these suggestions) once I have more experience with Clojure.
The full source is available on github. It includes a README to help you get started playing around, and explains more about the algorithm.