Touch the firehose of ds106, the most recent flow of content from all of the blogs syndicated into ds106. As of right now, there have been 92731 posts brought in here going back to December 2010. If you want to be part of the flow, first learn more about ds106. Then, if you are truly ready and up to the task of creating web art, sign up and start doing it.

Dare to Compare

Posted by
|

So I decided to take a look at some of the old homework problems and see how they would size up in clojure vs. ML in simplicity and usability, all the while considering things such as typing, polymorphism, etc.

Ex 1:  Ch 9 – square sum problem.  Take a list, square the members, and sum them all up as one

ML:  fun sqsum l = foldr (op +) 0 (map (fn x => x * x) l)
Clojure:  (defn sqsum [l] (reduce + (map #(* % %) l))
Clojure v 2:   (defn sqsum [l] (reduce + (map (fn [x] (* x x)) l))
Clojure v 3:  (defn sqsum [l] (apply + (map #(* % %) l))

This example shows remarkable similarities between these two functional languages.  foldr and reduce operate in the same order; but there is no clojure-equivalent to foldl.  Both utilize anonymous functions to complete the problem at hand, but in Clojure, we have two ways to write these functions.  The standard method is listed above as Clojure v 2, and as we can see, this is very similar to the ML version.  The # before a parenthetical block denotes an anonymous function to be written in short-hand form.  The % character used in an anonymous function maps the % to a list member in order to apply the function.  So # (* % %) multiplies each list member by itself.  This shorthand, I feel, saves time and effort in programming while still preserving readability (so long as someone has learned a bit about the language).  I also feel the reduce in Clojure is slightly more convenient than that of foldr/l in ML, as ML requires an additional parameter (a starting value) where Clojure’s reduce does not.  It could potentially be more efficient as well; if no values are being bound to a var x for each part of the map, we may be saving some computing space.  There are so many ways to do the problem in clojure!

Ex 2:  pattern matching
ML:  fun third (one::two::three::list) = three;
Clojure:  (defn third [[_ _ x]] = x)

Clojure has a way of pattern matching called destructuring, which allows one to take a list and break it down into component parts.  This makes it pretty easy to find the third element in a list (underscore is a wildcard char, so [_ _ x] makes x the third element) Clojure is more resilient in its returns in this situation – if the input list  is less than 3 members in length, then it will return nil, whereas the ML function will return an error due to the fact that the definition above is non-exhaustive (no case for 0 to 2 elements).  Clojure seems to handle the exhaustion process for the programmer.

I’ll add more examples later, haven’t had time to find good problems to work on.

Add a comment

ds106 in[SPIRE]