Wednesday, June 15, 2011

List processing functions push, pop, shift, unshift

In Clojure most funtions are purely functional, and side effects occur by applying pure functions to objects. So instead of the shift and pop functions, we have rest and butlast:

(swap! coll rest)
(swap! coll butlast)

We can also take a slice over the collection by mapping over a range:

(swap! coll map (range 0 2))

Adding new elements to the collection like with unshift and push is a bit more complicated. You can use conj to add new elements to a list depending on rather it is a list or a vector, however, that is not neccessarily the same thing as push and unshift, so instead we should use concat:

(swap! coll concat [1 2 3])

Unshift is the hardest to implement yet:

(defn unshift 
  "Add the elements of the first collections behind the later ones." 
  [& colls]

  (apply concat (reverse colls)))

(swap! coll ushift [1 2 3])

Now we can do these familiar array operations in Clojure. I think this shows that the application of pure functions - which is the fundemental basis of Clojure's effect system - is a legitimate and powerful model of computation.

Due to the advantages of purity, we should limit our impure functions to a minimum. What few impure functions we do have should be distinguished with an exclamation mark, like the swap! function.

No comments:

Post a Comment