|Fractal Tree of the Gods|
So the first thing I tried with this new version of Clojure, which is supposed to cure such difficulties, was the fractal tree. I had to add the new ^:static declaration to the recursive function, and then type-hint the function's arguments. And now look at it go! It redraws the tree in about 25ms, or 50 frames/second, which means that as you resize the window, the tree rustles cheerfully!
An extraordinary difference. Try it yourself, a pom.xml for the new clojure is here, and very simple full instructions for setting up the full clojure 1.2/emacs/swank/slime are here. All that you need to change to try the new version is the pom.xml file.
And the thing that impressed me most about it the first time, the ability to fiddle with draw-tree in emacs, press M-C-x to redefine the function in the running image, and then see the changes as soon as the window is redrawn, is still true. I think graphics programming in Clojure is about to become wonderful fun. The speed of compiled java combined with the experimental, exploratory qualities of LISP.
Since this alpha release is likely to turn into the next version of clojure, and I've been quite interested in the speed of things recently, I'm going to change over to 1.3-alpha now, and all further posts will be based on it. No point learning to optimize the current version when the new one will obviously require different tricks.
Here's the new source code for fractal-tree.clj:
(import '(javax.swing JFrame JPanel ) '(java.awt Color Graphics Graphics2D)) (defn ^:static draw-tree [ #^Graphics g2d ^double angle ^double x ^double y ^double length ^double branch-angle ^long depth] (if (> depth 0) (let [new-x (- x (* length (Math/sin (Math/toRadians angle)))) new-y (- y (* length (Math/cos (Math/toRadians angle)))) new-length (fn  (* length (+ 0.75 (rand 0.1)))) new-angle (fn [op] (op angle (* branch-angle (+ 0.75 (rand)))))] (. g2d drawLine x y new-x new-y) (draw-tree g2d (new-angle +) new-x new-y (new-length) branch-angle (- depth 1)) (draw-tree g2d (new-angle -) new-x new-y (new-length) branch-angle (- depth 1))))) (defn render [ #^Graphics g w h ] (doto g (.setColor (Color/BLACK)) (.fillRect 0 0 w h) (.setColor (Color/GREEN))) (let [init-length ( / (min w h) 5), branch-angle (* 10 (/ w h)), max-depth 12] (#'draw-tree g 0.0 (/ w 2) h init-length branch-angle max-depth))) (defn create-panel  "Create a panel with a customised render" (proxy [JPanel]  (paintComponent [g] (proxy-super paintComponent g) (time (render g (. this getWidth) (. this getHeight)))))) (defn run  (let [frame (JFrame. "Clojure Fractal Tree") panel (create-panel)] (doto frame (.add panel) (.setSize 640 400) (.setVisible true)))) (run)