Un-lazy-fying clojure

I’m finding Clojure has a similar feel to C++ about it – it requires a higher degree of understanding of the underlying implementation than I think is probably optimal. Partly this could be because it’s a new language – but it’s also what makes it interesting.

A common problem I’m having is running out of Java stack due to lazy structures – this is a problem in a game or simulation loop such as Germination X, where if the values are not used by something they are never evaluated (which saves cycles) and hang around (using up memory).

Luckily Clojure comes with (doall) which forces the evaluation of a lazy sequence – however it’s not recursive and *only* works on sequences. This function is recursive, and also calls itself on all the values contained in hash-maps:

; force all sequences and maps to un-lazy
(defn doall-recur [s]
  (cond
   (map? s) (reduce
             (fn [r i]
               (merge {(first i)
                       (doall-recur (second i))} r))
             {} s)
   (seq? s) (doall
             (map doall-recur
                  s))
   :else s))

One thought on “Un-lazy-fying clojure

  1. What about (postwalk identity sequence)?

    (realized? (range 1 10))
    (realized? (doall (range 1 10)))

    (def x
    [(range 1 10) (range 1 10) (range 1 10)])

    ;; returns false
    (realized? (first x))

    ;; returns false
    (realized? (first (doall x)))

    ;; returns true
    (realized? (doall (first x)))

    ;; returns false
    (realized? (second x))

    (require ‘clojure.walk)
    ;; returns true
    (realized? (second (clojure.walk/postwalk identity x)))

    Live coding and bioinformatics! Very cool combination.

Leave a Reply

Your email address will not be published. Required fields are marked *