I've incorporated everyone's suggestions and thought I would post the resulting smaller code. I refactored init-cells away and just pass in an init or new function to calc-state to reuse the for loop. I made determine-next-state a little more verbose than technically necessary to make conway's rules more obvious to me. The refs "cells" and "running" don't feel very functional but I don't know how to get rid of them.
(import '(javax.swing JFrame JPanel JButton) '(java.awt BorderLayout Dimension Color) '(java.awt.event ActionListener)) (def cells (ref {})) (def running (ref false)) (defn determine-initial-state [x y] (= 0 (rand-int 5))) (defn determine-new-state [x y] (let [neighbor-count (count (for [dx [-1 0 1] dy [-1 0 1] :when (and (not (= 0 dx dy)) (cells [(+ x dx) (+ y dy)]))] :alive))] (if (cells [x y]) (< 1 neighbor-count 4) (= neighbor-count 3)))) (defn calc-state [cell-state] (dosync (ref-set cells (reduce conj {} (for [x (range 32) y (range 48)] [[x y] (cell-state x y)]))))) (defn paint-cells [graphics] (doseq [[[x, y] state] @cells] (doto graphics (. setColor (if state Color/RED Color/WHITE)) (. fillRect (* 10 x) (* 10 y) 10 10)))) (defn toggle-thread [panel button] (if @running (do (dosync (ref-set running false)) (. button (setText "Start"))) (do (dosync (ref-set running true)) (. button (setText "Stop")) (. (Thread. #(loop [] (calc-state determine-new-state) (. panel repaint) (Thread/sleep 100) (if @running (recur)))) start)))) (defn main[] (calc-state determine-initial-state) (let [f (JFrame.) b (JButton. "Start") panel (proxy [JPanel] [] (paint [graphics] (paint-cells graphics)))] (doto f (. setLayout (BorderLayout.)) (. setLocation 100 100) (. setPreferredSize (Dimension. 320 540)) (. add b BorderLayout/SOUTH) (. add panel BorderLayout/CENTER) (. setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) (. pack) (. setVisible true)) (. b addActionListener (proxy [ActionListener] [] (actionPerformed [evt] (toggle-thread panel b)))))) (main) Thanks for everyone. Very good learning experience. Larry http://lpsherrill.blogspot.com --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---