Hi Everyone,
I'm looking for some feedback on a small get-your-feet wet program I
wrote in clojure (my first). In particular, I hope to get feedback on
how to better make use of clojure's data structures and functional
programming in general.

Below is the toy program and the sample output. It reads in words from
the OS X dictionary file, catalogs the anagrams, and then prints out
the top ten by frequency. Although performance is not my primary
concern here, it is a bit slow. It takes about 15s on my mac book
pro.

As an example, is this the "proper" way to update multiple fields at
once in a nested hash-map:

(update-in (update-in anagrams [akey :count] inc) [akey :words] conj
word)))

I understand this as returning an copy of an updated copy of an
updated copy.

Any feedback would be appreciated. Thanks,
Damon

## begin
(defn f-to-seq[file]
  (with-open [rdr (java.io.BufferedReader.
                    (java.io.FileReader. file))]
    (doall (line-seq rdr))))

(defn str-sort[str]
  (if (nil? str)
    str
  (String. (into-array (. Character TYPE) (sort str)))))

(defn str-to-lower[str]
  (if (nil? str)
    str
    (.toLowerCase str)))


(defn anagram-add[anagrams akey word]
  (if (empty? (get anagrams akey))
    (assoc anagrams akey (hash-map :count 1, :words (list word)))
    (update-in (update-in anagrams [akey :count] inc) [akey :words]
conj word)))

(defn word[seq] (first seq))

(defn build-anagrams[seq]
  (loop [seq seq
         akey (str-sort (str-to-lower (word seq)))
         anagrams {}]
    (if (empty? seq)
      anagrams
      (recur (rest seq)
             (str-sort (str-to-lower (word (rest seq))))
             (anagram-add anagrams akey (word seq))))))


(defn print-anagram[v]
  (println (str (:count (first (rest v))) " " (first v) ": " (:words
(first (rest v))))))

(defn print-anagrams[ana]
  (doseq [v ana]
    (print-anagram v)))

(defn anagram-key[elem] (:count (first (rest elem))))

(def *words* (f-to-seq "/usr/share/dict/web2"))
(def *anagrams* (sort-by anagram-key (build-anagrams *words*)))
(print-anagrams (take 10 (reverse *anagrams*)))

## output
11 agnor: ("Ronga" "rogan" "organ" "orang" "Orang" "nagor" "groan"
"grano" "goran" "argon" "angor")
10 aelps: ("speal" "spale" "slape" "sepal" "saple" "salep" "Pales"
"Lepas" "lapse" "Elaps")
9 eerst: ("tsere" "terse" "stree" "stere" "steer" "reset" "reest"
"estre" "ester")
9 aeerst: ("teaser" "staree" "seater" "saeter" "reseat" "Eastre"
"easter" "Easter" "asteer")
9 aacinr: ("narica" "crania" "Crania" "carina" "Carian" "canari"
"Canari" "arnica" "acinar")
9 acert: ("trace" "recta" "react" "creta" "creat" "crate" "cater"
"carte" "caret")
8 ailr: ("rial" "rail" "lira" "liar" "lari" "Lari" "lair" "aril")
8 aelpt: ("tepal" "pleat" "plate" "petal" "pelta" "patel" "palet"
"leapt")
8 airst: ("Trias" "tisar" "tarsi" "stria" "stair" "sitar" "astir"
"arist")
8 aemrt: ("Trema" "trame" "terma" "tamer" "ramet" "metra" "mater"
"armet")

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to