Clojure: Language as thought shaper
I recently read an interesting article by Tom Van Cutsem where he describes some of the goals that influence the design of programming languages and one which stood out to me is that of viewing ‘language as a thought shaper’:
The goal of a thought shaper language is to change the way a programmer thinks about structuring his or her program.
I’ve been rewriting part of the current system that I’m working on in Clojure in my spare time to see how the design would differ and it’s interesting to see that it’s quite different.
The part of the system I’m working on needs to extract a bunch of XML files from ZIP files and then import those into the database.
From a high level the problem can be described as follows:
Clojure encourages a design based around processing lists and this problem seems to fit that paradigm very neatly.
We can make use of the -» macro to chain together a bunch of functions originally acting on the specified directory to allow us to achieve this.
At the moment this is what the entry point of the code looks like:
(defn parse-directory [dir] (->> (all-files-in dir) (filter #(.. (canonical-path %1) (endsWith ".zip"))) (mapcat (fn [file] (extract file))) (filter (fn [entry] (. (entry :name) (endsWith ".xml")))) (map #(categorise %))))
The design of the Scala code is a bit different even though the language constructs exist to make a similar design possible.
The following are some of the classes involved:
It was interesting to me that when I read the Scala code the problem appeared quite complicated whereas in Clojure it’s easier to see the outline of what the program does.
I think is because we’re trying to shoe horn a pipes and filters problems into objects which leaves us with a design that feels quite unnatural.
I originally learnt this design style while playing around with F# a couple of years ago and it seems to work reasonably well in most functional languages.