or learn more

On Lisp -> Clojure (Chapter 3)

Sep 30, 2008

; As always, I will post when the code is “complete”, but my progress can be followed on Github.

Posts in this series: ch. 2, ch. 2 redux, ch. 3, ch. 4, ch. 5

; Chapter 3 was a relatively short chapter (code-wise). It dealt mostly with side-effects and the virtues of a more functional style to avoid such evil. Thankfully, Clojure eliminates many of the problems outlined by Graham in the way that it prefers immutability and minimizes the functions causing side-effects.

; pg. 29

; Graham provides an intentionally bad implementation of a reverse function that modifies a list in place. To do this in Clojure would require some gymnastics and therefore is probably not worth the effort.

; pg. 30


(defn good-reverse [lst]
  (defn rev [lst acc]
    (if (nil? lst)
      (rev (rest lst) (cons (first lst) acc))))
  (rev lst nil))


; pg. 32

; Clojure doesn’t provide multiple value bindings in the same way that Lisp does. Instead, you can construct a vector of values and then deconstruct them easily on the return within a let)


(defn mytrunc [num]
  [(int num) (- num (int num))])

(let [[int_part frac_part] (mytrunc 26.21875)]
  (str int_part " and " frac_part))


; -m

One Comment, Comment or Ping

  1. Brian

    A version of good-reverse that does not grow stack and works on seq.

    (defn good-reverse [lst] (loop [l lst, acc nil] (if (seq l) (recur (rest l) (cons (first l) acc)) acc)))

Reply to “On Lisp -> Clojure (Chapter 3)”