Compulsion to Code

In software development there are no silver bullets, but I am always looking out for the next bronze one.

Friday, July 1, 2011

An Akka actor from the cutting room floor

    This is an example of hot-swapping actor behavior in Akka using the become method. This demo was not part of my "Akka: Scaling Up and Out with Actors"(http://java.ociweb.com/javasig/knowledgebase/2011-06/index.html) talk given at the St. Louis JavaSIG on June 9th, 2011. It was left out due to time constraints on the presentation.

     Inspired by a post on Dale Schumaker's "The Computational Actor's Guild" site (http://dalnefre.net/drupal/node/23), this demonstrates an actor that builds a ring of of actors of a specified size that then passes a message around the ring a given number of times. What's interesting about this implementation is that the actor uses become to change the behavior of a Actor from one that helps construct the ring to one that handles the message by passing to the next actor in the ring.

object RingBecomeDemo {

  class NodeActor(id:Int, start:Long) extends Actor {

    def receive = {
      case n:Int => self ! (self, n)
      case (top:ActorRef, n:Int) => {
        if (id == 0) {
          become {
            case np:Int => if (np == 0) {
                self.stop
                printf("Time %d ms\r\n", System.currentTimeMillis - start)
              } else {
                printf("decrementing from %d\r\n", np)
                top ! (np - 1)
              }
          }
          top ! n
        } else {
          val next = Actor.actorOf(new NodeActor(id-1, start)).start
          next ! (top, n)
          become {
            case np:Int => {
              next ! np
              if (np == 0) {
                self.stop
              }
            }
          }
        }
      }
    }
  }

  def main(args:Array[String]) {
    val ring = Actor.actorOf(new NodeActor(1000000, System.currentTimeMillis)).start
    ring ! 10
  }
}

    This implementation creates a million nodes and times how long it takes to construct the ring and pass an integer around 10 times.

    Here (http://sites.google.com/site/compulsiontocode/blog/ring-become.zip) is a file containing code above. Gradle is required to run it. To execute, unzip and enter 'gradle RingBecomeDemo' within the 'ring-become' directory.

One million node requires a significant heap size. To reduce the number nodes, change the first parameter passed to the NodeActor constructor. The heap size can be changed by editing the RingBecomeDemo task in the build.gradle file:

task RingBecomeDemo(type:JavaExec, dependsOn: classes) {
  jvmArgs = System.getProperty("sun.arch.data.model").equals("64") ? ["-Xms2048m", "-Xmx2048m"] : ["-Xms1024m", "-Xmx1024m", "-server"]
  classpath = sourceSets.main.runtimeClasspath
  main = "tfd.ringbecome.RingBecomeDemo"
}

A follow-up post is planned compare this implementation to one in Erlang including performance.

Friday, May 20, 2011

Fixing Gradle compileScala to not depend on compileJava

One problem encountered using the Scala plugin for Gradle is that the 'compileScala' task is dependent on the 'compileJava' task (as of Gradle 0.9.2). If a project has both Java and Scala sources and there are Java classes that depend on Scala ones, the build will fail. Consider two mutually dependent classes in a the same project:

Bar.java

public class Bar {
    public void doFoo(Foo foo) { ... }
}

Foo.scala

class Foo {
  def doBar(bar:Bar) { ... }
}

Gradle can't build this because Bar depends on Foo which hasn't been compiled yet. However, the Scala compiler can handle cross compilation with Java sources, so the solution is simply let the Scala compile occur first.

To override the compileScala task dependency and reverse the order of the tasks add the following to the 'build.gradle' file:

compileScala.taskDependencies.values = compileScala.taskDependencies.values - 'compileJava'
compileJava.dependsOn compileScala

The first line removes the task dependency on the compileJava task from the compileScala task. The second line makes the compileJava task depend on compileScala.

For the Java source to be available for cross compilation the directory needs to in a "sourceSet" for the Gradle Scala plugin. For example, if the Java class is in 'src/main/java' then the following will need to be included in build.gradle:

sourceSets {
    main {
        scala {
            srcDir 'src/main/java'
        }
    }
}

Using this arrangement a project with mutual dependencies like the example above should be buildable with Gradle.

Wednesday, May 18, 2011

Enable a Scala compiler plugin using Gradle

Having recently switched a Scala project to Gradle for building, I was faced with the difficulty of figuring out how to enable the Scala continuation plugin during the compileScala task. Below is a general solution I came up with. Hopefully it will be helpful for others and save someone some time.

 

apply plugin: 'scala'
...
configurations {
  scalaCompilerPlugins { transitive = false }
}

dependencies {
...
    scalaCompilerPlugins 'org.scala-lang.plugins:continuations:2.9.0' 
}

def scalacXPlugins() {
     return ((configurations.scalaCompilerPlugins.files.collect { "\"-Xplugin:${it.path}\"" }))
}

compileScala.scalaCompileOptions.additionalParameters = scalacXPlugins() + ['-P:continuations:enable']

    Note:
  • The "transitive = false" in the configurations block prevents dependencies of the plugin as being treated as plugins themselves. Namely, the Scala compiler and library.

Friday, October 29, 2010

Code Kata for Parallel Programming

    One of the keynote presentations at the Strange Loop 2010 conference in St. Louis was
Guy Steele's "How to Think about Parallel Programming: Not!."


    One of the examples in the presentation was counting words in a presumably large text file. He showed example code in Fortress of how one could go about taking a "divide-and-conquer" approach to the problem. This approach would divide the work into chunks that could be processed in parallel and then the outputs would be aggregated to form the solution.


    Noticing some of the syntactic similarities between Fortress and Scala, I had the impulse to implement a solution in Scala. During Dean Wampler's "Scalable Concurrent Applications with Akka and Scala" talk, I got the idea that that would make a good code kata to use and learn Akka.


    My final idea for the kata modifies the problem from counting words to finding sequences of digits where the last digit is the sum of its immediately preceding digits of any length. The input would be stream of non-zero digits. For example, the content below contains sequences "1326", "415", "246" and "617".


8745648184845171326578518184151512461752149647129746915414816354846454

    Such "sum sequences" should be listed only once in the solution and in the order they are found in the input. Limiting the input to non-zero digits simplifies the problem a little bit since many consecutive zeros would produce a solution that will grow exponentially.


    My initial implementations for this will use Scala and Akka including one using remote actors. Over the coming months, I hope to have time to implement solutions in other languages, such as F#, Clojure and Erlang, using their various parallel programming / concurrency libraries. Hopefully others will find this problem compelling and implement such solutions as well.

Tuesday, June 9, 2009

A Refactoring in Scala

    One pet project I have going is a little Logo interpreter done using Scala parser combinators with a Swing GUI where code can be edited and executed with results being rendered on a canvas. Being a good little Agile developer, I wrote automated tests for it

    I've had experience on a previous Swing project using the Netbeans Jemmy library for driving the GUI tests in Java. I was curious of what Scala can wrap around such testing libraries like Jemmy. Initially, the test code was more Java style than Scala since I've only used Jemmy with Java previously. I found that interesting refactorings can be applied as the code takes on the more functional style of Scala.

    Experienced Scala developers are probably familiar with these concepts, so the intended audience is developers who are relatively new to Scala and insights into why Scala code is the way it is.

    As I was developing the tests, I needed to programatically find buttons on a toolbar that do such things as "New", "Save", "Load", and "Execute". These buttons don't have text, so I am using the tooltip to distinguish them. A Java-style Scala function to do this would look like this:



def findJButton(container:Container, toolTipText:String) = {
val button = JButtonOperator.findJButton(container,
new ComponentChooser() {
override def checkComponent(component:Component) =
if (component.getClass.isAssignableFrom(classOf[JButton])) {
component.asInstanceOf[JButton].getToolTipText == toolTipText
} else {
false
}
override def getDescription() = "JButton Finder using toolTipText"
}
)
if (button == null) {
fail("cannot find JButton with tooltip = '" + toolTipText + "'")
}
new JButtonOperator(button)
}

Client code:



val newButtonOper = findJButton(frmOper.getContentPane, "Start new Logo program" )
val runButtonOper = findJButton(frmOper.getContentPane, "Run Logo program")

    The "*Operator" classes in Jemmy wraps corresponding Swing components so that can be programatically manipulated in the same way an actual user would. The frmOper object is a Jemmy JFrameOperator that wraps the main frame of the application.

    Now in Java, one can refactor the inner class into a regular class and leverage generics so that it can match any JComponent subtype since that is where getToolTipText is first implemented. In Scala, we will do something like that and make it so that a higher order function can be passed in the do the comparison provided the component is the correct type:



class LoanChooser[A <: java.awt.Component](clazz: Class[A], filter: A => Boolean)
extends ComponentChooser
{
override def checkComponent(component:Component) =
if (component.getClass.isAssignableFrom(clazz)) {
filter(component.asInstanceOf[A])
} else {
false
}
override def getDescription() = "Generic Finder using Loan Pattern"
}

def findJButton(container:Container, filter: JButton => Boolean) = {
val button = JButtonOperator.findJButton(container,
new LoanChooser(classOf[JButton], filter))
if (button == null) {
fail("cannot find JButton with matching criteria")
}
new JButtonOperator(button)
}

Client code:



val newButtonOper = findJButton(frmOper.getContentPane, btn => btn.getToolTipText == "Start new Logo program" )
val runButtonOper = findJButton(frmOper.getContentPane, btn => btn.getToolTipText == "Run Logo program")

    The code above uses the "Loan Pattern" in Scala (http://scala.sygneca.com/patterns/loan). The client code is loaned the the JButton instance so it can be tested to see if it matches the criteria.

    Knowing the Scala implements functions as objects, I know that two identical anonymous function classes are going be created in the form "JButton => Boolean", so I create a common function that can be curried (or partially applied) with the toolTipText as the first parameter:


def toolTipTextEquals(toolTipText:String)(component:JComponent) = component.getToolTipText == toolTipText


val newButtonOper = findJButton(frmOper.getContentPane, toolTipTextEquals("Start new Logo program"))
val runButtonOper = findJButton(frmOper.getContentPane, toolTipTextEquals("Run Logo program"))

    Now is getting pretty obvious what the code is trying to accomplish. There are some repeated code patterns that can be refactored out. At this point, it probably more at matter of taste in that some will want to refactor more and others might see it an an exercise in of "Scala Golf" (http://codegolf.com/). First we can get rid of the repeated "frmOper.getContentPane" by the traditional means of temporary local variable:


val contentPane = frmOper.getContentPane
val newButtonOper = findJButton(contentPane, toolTipTextEquals("Start new Logo program"))
val runButtonOper = findJButton(contentPane, toolTipTextEquals("Run Logo program"))

Or use an implicit conversion:



implicit def jFrameOperator2Container(frmOper:JFrameOperator) = frmOper.getContentPane

val newButtonOper = findJButton(frmOper, toolTipTextEquals("Start new Logo program"))
val runButtonOper = findJButton(frmOper, toolTipTextEquals("Run Logo program"))

    The implicit conversion is invoked since the findJButton function it expecting a Container as the first param, but is provided a JFrameOperator. Since there is an implicit function in scope in the form "JFrameOperator => Container", it is used to perform the conversion implicitly.

    My Logo application currently has four buttons on a toolbar that will need to be tested and I'll need JButtonOperators for all of them:


val newButtonOper = findJButton(frmOper, toolTipTextEquals("Start new Logo program"))
val openButtonOper = findJButton(frmOper, toolTipTextEquals("Open existing .logo file"))
val saveButtonOper = findJButton(frmOper, toolTipTextEquals("Save current logo code to file"))
val runButtonOper = findJButton(frmOper, toolTipTextEquals("Run Logo program"))

Once can utilize Scala's ability to deconstruct on patterns during declarations and do this:


val List(newButtonOper, openButtonOper, saveButtonOper, runButtonOper) =
List("Start new Logo program",
"Open existing .logo file",
"Save current logo code to file",
"Run Logo program").map(toolTipText => findJButton(frmOper, toolTipTextEquals(toolTipText)))

    It is a matter of taste whether four buttons warrant such refactoring, but if the code started to look unwieldy and I didn't want to keep them in some kind of collection, I would definitely consider this approach.


    I felt this recent experience refactoring Scala code was interesting enough to blog about it and hope that readers gain some insight from this and want to use Scala more. I feel that Scala or at least a language with many of its features (like some kind of "Scala--") will play a big role on the JVM platform going forward.


Sidebar: Whither SQUIB

    I haven't done much with the SQUIB project recently. I am seeing too many drawbacks to its approach:


  • Property resolution done at runtime - If the property is misspelled or uses an invalid type the best thing to do is fail fast and throw an exception. It would be nice if such issues could be detected at compile time at least.

  • Lack of IDE support - It would be nice if a framework uses actual methods that an IDE could then provide auto-completion and the like.

  • It's just a little heavyweight: I've found that very useful things can be done in Scala with minimal code.

Tuesday, March 10, 2009

Bowling in Yet Another Language (F#)

Another day, another blog posting involving bowling and a functional programming language. This one is in F#, which is very interesting language for the .NET platform. Code:

#light

module Bowling

open System;;

let scoreToInt x =
match x with
Some y -> y
| None -> -1;;

let rec tallyScores accum x =
match x with
[] -> []
| x::rest -> let score = scoreToInt x in
if (score >= 0) then
let total = (accum + score) in total :: tallyScores total rest;
else
[];;

let rec take n l =
if (n > 0) then
match l with
x::rest -> let newn = n-1 in x :: take newn rest
| [] -> []
else
[];;

let rec reduce f ys =
if ys <> [] then
let (x, ys') = f ys in x::reduce f ys'
else [];;

let scoreFrame rolls =
match rolls with
x1::x2::x3::rest -> if (x1 = 10) then (Some (x1+x2+x3), x2::x3::rest)
else if (x1 + x2 = 10) then
(Some (x1+x2+x3), x3::rest)
else (Some(x1+x2), x3::rest)
| x1::x2::[] -> if (x1 + x2 < 10) then
(Some(x1 + x2), [])
else (None, []);
| _ -> (None, []);;

let scoreTenFrames rolls =
take 10 (reduce scoreFrame rolls);;

let tallyGame rolls =
tallyScores 0 (scoreTenFrames rolls);;

let printGame rolls =
List.iter (fun x -> Console.Write(int x); Console.Write " ") (tallyGame rolls);
Console.Write "\n";;

let assertTrue expression =
if (expression = false) then
failwith "Assertion Not True";;

assertTrue ([30;60;90;120;150;180;210;240;270;300] = tallyGame[10;10;10;10;10;10;10;10;10;10;10;10]);;
assertTrue ([30;60;90;120;150;180;210;240;270;299] = tallyGame[10;10;10;10;10;10;10;10;10;10;10;9]);;
assertTrue ([30;60;90;120;150;180;210;240;270;290] = tallyGame[10;10;10;10;10;10;10;10;10;10;10;0]);;
assertTrue ([20;50;80;110;140;170;200;230;260;290] = tallyGame[9;1;10;10;10;10;10;10;10;10;10;10;10]);;
assertTrue ([30;60;90;120;150;180;210;240;269;289] = tallyGame[10;10;10;10;10;10;10;10;10;10;9;1]);;
assertTrue ([30;60;90;120;150;180;210;240;269;288] = tallyGame[10;10;10;10;10;10;10;10;10;10;9;0]);;
assertTrue ([30;60;90;120;150;180;210;240;260;280] = tallyGame[10;10;10;10;10;10;10;10;10;10;0;10]);;
assertTrue ([20;40;70;100;130;160;190;220;250;280] = tallyGame[10;9;1;10;10;10;10;10;10;10;10;10;10]);;
assertTrue ([30;60;90;120;150;180;210;239;259;279] = tallyGame[10;10;10;10;10;10;10;10;10;9;1;10]);;
assertTrue ([30;60;90;120;150;180;210;240;260;270] = tallyGame[10;10;10;10;10;10;10;10;10;10;0;0]);;
assertTrue ([20;40;60;80;100;120;140;160;180;200] = tallyGame[10;9;1;10;9;1;10;9;1;10;9;1;10;9;1;10]);;
assertTrue ([19;38;57;76;95;114;133;152;171;190] = tallyGame[9;1;9;1;9;1;9;1;9;1;9;1;9;1;9;1;9;1;9;1;9]);;
assertTrue ([19;38;57;76;95;114;133;152;171;180] = tallyGame[9;1;9;1;9;1;9;1;9;1;9;1;9;1;9;1;9;1;9;0]);;
// Partial games
assertTrue ([] = tallyGame[]);;
assertTrue ([] = tallyGame[0]);;
assertTrue ([] = tallyGame[9]);;
assertTrue ([] = tallyGame[10]);;
assertTrue ([] = tallyGame[9;1]);;
assertTrue ([] = tallyGame[10; 9]);;
assertTrue ([] = tallyGame[10; 10]);;
assertTrue ([0] = tallyGame[0; 0]);;
assertTrue ([1] = tallyGame[0; 1]);;
assertTrue ([9] = tallyGame[8; 1]);;
assertTrue ([9] = tallyGame[9; 0]);;
assertTrue ([19] = tallyGame[9; 1; 9]);;
assertTrue ([19; 28] = tallyGame[10; 9; 0]);;
assertTrue ([19; 28] = tallyGame[9; 1; 9; 0]);;
assertTrue ([20] = tallyGame[10; 9; 1]);;
assertTrue ([30] = tallyGame[10; 10; 10]);;
assertTrue ([30; 59] = tallyGame[10; 10; 10; 9]);;
assertTrue ([30; 59; 78; 87] = tallyGame[10; 10; 10; 9; 0]);;

Note that I've included a quick and dirty assertTrue method to validate the functions.


The above example can be used via the interactive shell (fsi) like below:



C:\DotNET\src>fsi

Microsoft F# Interactive, (c) Microsoft Corporation, All Rights Reserved
F# Version 1.9.6.2, compiling for .NET Framework Version v2.0.50727

Please send bug reports to fsbugs@microsoft.com
For help type #help;;

> #load "bowling.fs";;
[Loading C:\DotNET\src\bowling.fs]

namespace FSI_0002
val scoreToInt : int option -> int
val tallyScores : int -> int option list -> int list
val take : int -> 'a list -> 'a list
val reduce : ('a list -> 'b * 'a list) -> 'a list -> 'b list
val scoreFrame : int list -> int option * int list
val scoreTenFrames : int list -> int option list
val tallyGame : int list -> int list
val printGame : int list -> unit
val assertTrue : bool -> unit

> Bowling.printGame [10; 10; 10; 10; 10; 10; 10; 10; 10; 10; 10; 10];;
30 60 90 120 150 180 210 240 270 300
val it : unit = ()
> Bowling.printGame [10; 9;1; 10; 9;0; 10; 8;2; 10; 10; 9;1; 9;1; 10];;
20 40 59 68 88 108 137 157 176 196
val it : unit = ()

Each element on the list represents a roll of the ball. The program will figure out which frames the rolls belong to. For example, "[9;1]" represents single frame consisting of a nine count followed by spare of the remaining pin. This implementation assumes valid input and is not designed to handle such things as more than 10 pins in a frame on a negative value for a roll.

Tuesday, February 10, 2009

Bowling with Clojure

Having an interest in function programming languages (notably Scala), I decided to take a look at Clojure. In a nutshell, Clojure is a LISP variant that runs on the Java Virtual Machine and hence enjoys access to all libraries therein.
One of my favorite simple code katas with functional languages is to tally up bowling scores. Previously, I had done this with Erlang and Scala. Here is a Clojure version of the same including some tests:
(defn score-frame [rolls]
(let [[x1 x2 x3] rolls]
(cond
(nil? x1) nil
(nil? x2) nil
(nil? x3) (let [sumx (+ x1 x2)]
(if (< sumx 10) (list sumx))) ; open at end of game
(= x1 10) (cons (+ x1 x2 x3) (rest rolls)) ; strike
(= (+ x1 x2) 10) (cons (+ x1 x2 x3) (nthrest rolls 2)) ; spare
(< (+ x1 x2) 10) (cons (+ x1 x2) (nthrest rolls 2)) ; open
(true) nil
)
)
)

(defn roll-reduce [remaining-rolls]
(if (not (= nil remaining-rolls))
(let [result (score-frame remaining-rolls)]
(if (not (= nil result))
(cons (first result) (roll-reduce (rest result))))))
)

(defn score-ten-frames [rolls]
(take 10 (roll-reduce rolls)))

(defn tally-game [accum scores]
(if (> (count scores) 0) (let [new_accum (+ accum (first scores))] (cons new_accum (tally-game new_accum (rest scores)))))
)

(defn score-game [rolls]
(tally-game 0 (score-ten-frames rolls))
)

(assert (= '(30 60 90 120 150 180 210 240 270 300) (score-game '(10 10 10 10 10 10 10 10 10 10 10 10))))
(assert (= '(30 60 90 120 150 180 210 240 270 299) (score-game '(10 10 10 10 10 10 10 10 10 10 10 9))))
(assert (= '(30 60 90 120 150 180 210 240 270 290) (score-game '(10 10 10 10 10 10 10 10 10 10 10 0))))
(assert (= '(20 50 80 110 140 170 200 230 260 290) (score-game '(9 1 10 10 10 10 10 10 10 10 10 10 10))))
(assert (= '(30 60 90 120 150 180 210 240 269 289) (score-game '(10 10 10 10 10 10 10 10 10 10 9 1))))
(assert (= '(30 60 90 120 150 180 210 240 269 288) (score-game '(10 10 10 10 10 10 10 10 10 10 9 0))))
(assert (= '(30 60 90 120 150 180 210 240 260 280) (score-game '(10 10 10 10 10 10 10 10 10 10 0 10))))
(assert (= '(20 40 70 100 130 160 190 220 250 280) (score-game '(10 9 1 10 10 10 10 10 10 10 10 10 10))))
(assert (= '(30 60 90 120 150 180 210 239 259 279) (score-game '(10 10 10 10 10 10 10 10 10 9 1 10))))
(assert (= '(30 60 90 120 150 180 210 240 260 270) (score-game '(10 10 10 10 10 10 10 10 10 10 0 0))))
(assert (= '(20 40 60 80 100 120 140 160 180 200) (score-game '(10 9 1 10 9 1 10 9 1 10 9 1 10 9 1 10))))
(assert (= '(19 38 57 76 95 114 133 152 171 190) (score-game '(9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 1 9))))
(assert (= '(19 38 57 76 95 114 133 152 171 180) (score-game '(9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 1 9 0))))
(assert (= '(0 0 0 0 0 0 0 0 0 0) (score-ten-frames '(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0))))

; Partial games
(assert (= nil (score-game nil)))
(assert (= nil (score-game '(0))))
(assert (= nil (score-game '(9))))
(assert (= nil (score-game '(10))))
(assert (= nil (score-game '(9 1))))
(assert (= nil (score-game '(10 10))))
(assert (= '(0) (score-game '(0 0))))
(assert (= '(1) (score-game '(0 1))))
(assert (= '(9) (score-game '(8 1))))
(assert (= '(9) (score-game '(9 0))))
(assert (= '(19) (score-game '(9 1 9))))
(assert (= '(19 28) (score-game '(10 9 0))))
(assert (= '(19 28) (score-game '(9 1 9 0))))
(assert (= '(20) (score-game '(10 9 1))))
(assert (= '(30) (score-game '(10 10 10))))
(assert (= '(30 59) (score-game '(10 10 10 9))))
(assert (= '(30 59 78 87) (score-game '(10 10 10 9 0))))


Note this code has been updated since initial posting to incorporate changes based on feedback in a comment from Mark Volkmann below. Mark has published an excellent overview of Clojure here, http://www.ociweb.com/jnb/jnbMar2009.html


Link to code


Example:
C:\lang\clojure>java -jar clojure.jar bowling.clj
Clojure
user=> (score-game '(10 10 10 10 10 10 10 10 10 10 10 10))
(30 60 90 120 150 180 210 240 270 300)
user=> (score-game '(10 10 10 10 10 10 10 10 10 10 10 9))
(30 60 90 120 150 180 210 240 270 299)
user=> (score-game '(10 10 10 10 10 10 10 10 10 10 9 1))
(30 60 90 120 150 180 210 240 269 289)
user=> (score-game '(10 10 10 10 10 10 10 10 10 9 1 10))
(30 60 90 120 150 180 210 239 259 279)
user=> (score-game '(10 10 10 10 10 10 10 10 10 9 0))
(30 60 90 120 150 180 210 239 258 267)
user=> (score-game '(9 0 10 10 10 10 10 10 10 10 10 10 10))
(9 39 69 99 129 159 189 219 249 279)