Hi, the other day I was at a conference in London and learned Scala.

As my first program I translated a favourite fractal tree program
(which I stole from: http://marblemice.com/2009/04/26/clojure-fractal-tree/).
The programs are almost exactly the same in the two languages.

The Scala version seems quite a lot faster than the Clojure one. I
added type hints for the Graphics objects, but there's also a
reflection warning from the JPanel proxy, which I think is
unimportant, but which I can't see how to get rid of.

Is the reason the Clojure version is slow that recursive calls to draw-
tree are boxing and unboxing primitive types? If so is there anything
that can be done? Did I just pick a particularly bad example program?

Or am I just missing something silly? Is there an easy way to examine
the byte-code?
Is it human-readable? Can it be done from a REPL like disassemble in
Lisp?

------------------------------------------- clojure version


(import '(javax.swing JFrame JPanel )
        '(java.awt Color Graphics Graphics2D))

(defn draw-tree [ #^Graphics g2d angle x y length branch-angle 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)
                    (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)


----------------------------------------------- scala version



import scala.swing._
import java.awt._
import javax.swing._

object ScalaFractalTree {
       def main(args: Array[String]){
                      val frame=new JFrame("Scala Fractal Tree")
                      val panel=new MyPanel()
                      frame add panel
                      frame setSize (640, 400)
                      frame setVisible true

                }

       }

class MyPanel extends JPanel{
  override def paintComponent(g:Graphics):Unit = {
    super.paintComponent(g)
    render(g, getWidth(), this.getHeight())

  }
  def render(g:Graphics, w:Int, h:Int){
      g.setColor (Color.BLACK)
      g.fillRect( 0, 0, w, h)
      g.setColor (Color.GREEN)
      val initlength=if (w<h) w/5 else h/5
      val branchangle=10*w/h
      val maxdepth=12
      drawtree( g, 0.0, w/2.0, h ,initlength, branchangle, maxdepth)
      }

  def drawtree(g:Graphics, angle:Double, x:Double, y:Double,
length:Double,
                             branchangle:Double, depth:Double){
     if (depth>0){
        val newx= x-length*(Math.sin(Math.toRadians( angle)))
        val newy= y-length*(Math.cos(Math.toRadians( angle)))
        val newlength1 = length*(0.75+0.1*Math.random)
        val newlength2 = length*(0.75+0.1*Math.random)
        val newangle1  = angle+branchangle*(0.75+Math.random)
        val newangle2  = angle-branchangle*(0.75+Math.random)
        g.drawLine(x.toInt, y.toInt, newx.toInt, newy.toInt)
        drawtree(g, newangle1, newx, newy, newlength1, branchangle,
depth-1)
        drawtree(g, newangle2, newx, newy, newlength2, branchangle,
depth-1)
        }
  }
}

-- 
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