Invited to nitpicking by Jacek Laskowski in his latest post titled Processing in Clojure, I decided to write my own version of his flower-drawing application. I find it an interesting challenge and illustration for my previous post about functional thinking and the use of language and decomposition.
Full source code is below, but let’s start with what I did not like and decided to rewrite.
I find Jacek’s code rather structural and hard to comprehend. Everything happens in one big function and it takes quite a while to understand what it does and how. It’s hard to see why angle
is an angle, and variables called a
and value
don’t make it any easier.
Thus my first two improvements are: Break it down into smaller pieces and use more informative names. For instance, value
is in fact scale
. I extracted drawing flower to a separate function with clear distinction to drawing petals and the central piece. I also paid more attention to variable names and hid the more complex concepts behind simple, well-named functions.
The second type of improvements is use of functional features. After a while of careful inspection I observed that angle
is a simple linear sequence, and scale
is result of a simple function on this sequence. I decided to replace it with a dedicated infinite sequence.
In the end, this code is longer and has more levels of abstraction, but I think it’s more functional and comprehensible. Functions are much shorter. Details no longer obscure the view, but are hidden behind more descriptive names. Now you can actually see that the applet’s draw
draws a flower which consists of petals and the central piece. The central piece is a simple circle, while petals are several circles of random size and color around the center. Then only if you want you can delve into details of how their color and size are generated.
Like I mentioned in the first paragraph, I find it a nice illustration of what Paul Graham describes as building a language for the solution.
I would like to add that if you want to let the whole application exit when the user closes the window you can add the following line to the last doto.
(.setDefaultCloseOperation (javax.swing.JFrame/EXIT_ON_CLOSE))