Archive

Archive for July, 2011

Scalafication of an Equity Quote Application Part 3

July 26th, 2011 Comments off

This is the final part in a series of article about porting an existing Java application to Scala. The application calls the Yahoo! Financial web service and retrieve stock quotes for the user, storing them in a local repository. The original Java project was described in the part one.

In the part two of this series, we looked at the unit test, and in particular the behaviour driven development (BDD) styles in the ScalaTest framework.

We will look at the Scala implementation of this business application. The easiest task is to simply convert the exceptions. Here are the Exceptions.scala file:

 

package uk.co.xenonique.stockquoteapp_scala

class ConnectionException( msg: String, root: Exception ) 
extends RuntimeException( msg, root ) {
   def this( msg: String ) = this( msg, null )
}

class DataRetrievalException( msg: String, root: Exception ) 
extends RuntimeException( msg, root ) {
   def this( msg: String ) = this( msg, null )
}

class UnknownStockSymbolException( msg: String, root: Exception ) 
extends RuntimeException( msg, root ) {
   def this( msg: String ) = this( msg, null )
}

 

We have more than one public class in a single source file. It is sort of allow Scala to look like a dynamic scripting language like Python or Ruby.

Next, we port the quote repository over to Scala. We remove the semi-colons, reverse the declarations of the variable types on the way. We take advantage of Scala support for Option types, we retrieve the stock quote by symbol name. The Scala library has two types of collections: immutable and mutable. By default, immutable collections are those that imported into the compiler as a predefinition. The QuoteRepositoryKeyValueStore imports a mutable Map collection for storing symbol associated with stock quotes. 

Here is the QuoteRepository.scala file:

 

package uk.co.xenonique.stockquoteapp_scala

import scala.collection.mutable.Map

trait QuoteRepository {
  def isEmpty(): Boolean
  def size(): Int
  def clear(): Unit
  def store( quote: StockQuote  ): Unit
  def get( symbol: String ): Option[StockQuote] 
  def contains( symbol: String ): Boolean
  def getSymbols(): List[String]
}

class QuoteRepositoryKeyValueStore extends QuoteRepository {

  private var store: Map[String, StockQuote] = Map()

  def clear(): Unit = { store.clear() }

  def contains(symbol: String): Boolean = store.contains(symbol)

  def get(symbol: String ): Option[StockQuote] = store.get(symbol)

  def isEmpty(): Boolean = store.isEmpty
	
  def size(): Int = store.size

  def store(quote: StockQuote ): Unit = {
    store.put(quote.symbol, quote)
  }

  def getSymbols(): List[String] = {
    // We use a tuple to iterate through the map, which return mutable list
    // then we use "toList" to convert to an immutable list.
    ( for ( (key,value ) <- store ) yield (key)  ).toList
  }

}

 

In above implementation class, we can write, in Scala, methods such as size() as one-liner methods.

We can convert the Java stock quotes to a case class and get the benefits of an implicit equalsTo(), hashCode() and toString() methods; and even get a handy copy() method too. Note: That we override the definition of the toString() class specifically for better formatting and, of course, debugging, but we did not need to do this for a case class.

Here is the StockQuote.scala file:

 

package uk.co.xenonique.stockquoteapp_scala

import java.math.RoundingMode
import java.math.BigDecimal

case class StockQuote( symbol: String, askPrice: BigDecimal, bidPrice: BigDecimal ) {

  // Auxiliary (convenience) constructor
  def this( symbol: String, askPriceStr: String, bidPriceStr: String ) =
    this ( symbol, new BigDecimal(askPriceStr).setScale(2, RoundingMode.DOWN ), new BigDecimal(bidPriceStr).setScale(2, RoundingMode.DOWN ) )

  // Auxiliary (copy) constructor
  def this( ref: StockQuote ) = this ( ref.symbol, ref.askPrice, ref.bidPrice )

  def meanPrice: BigDecimal = bidPrice.add( askPrice.subtract(bidPrice).divide( StockQuote.TWO ).setScale(2, RoundingMode.DOWN ) )

  override def toString(): String = {
    return "StockQuote [ symbol=" + symbol +", askPrice=" + askPrice +
      ", bidPrice=" + bidPrice + ", meanPrice="+meanPrice+"]";
  }
}

object StockQuote {
  def TWO = new BigDecimal("2.0")
}

 

The real hard part of the quote retriever service is get information from the Internet, by calling the web service. Luckily calling the Yahoo! Finance service is a simple REST GET request in comparison to other more complicated SOAP or REST web services.

Here is the QuoteRetriever.scala file:

 

package uk.co.xenonique.stockquoteapp_scala

import java.lang.NumberFormatException
import java.io._
import java.net._

trait QuoteRetriever {
  def getStockQuote( symbol: String ): StockQuote
}

object QuoteRetrieverYahooImpl {
   val TOKEN_SYMBOL="@SYMBOL@"
   val DEFAULT_URL_FRAGMENT="http://finance.yahoo.com/d/quotes.csv?s="+TOKEN_SYMBOL+"&f=sb2b3"

}

class QuoteRetrieverYahooImpl( var urlFragment: String = QuoteRetrieverYahooImpl.DEFAULT_URL_FRAGMENT ) 
extends QuoteRetriever {
  
  def getStockQuote( symbol: String ): StockQuote = {

    val queryUrl: String = urlFragment.replace(QuoteRetrieverYahooImpl .TOKEN_SYMBOL, symbol)

    try {
      val url: URL = new URL( queryUrl )
      val connection: HttpURLConnection  = url.openConnection().asInstanceOf[HttpURLConnection]
      connection.setRequestMethod("GET")
      connection.connect()

      val is: InputStream = connection.getInputStream()
      val reader: BufferedReader = new BufferedReader( new InputStreamReader(is) )

      try {
        val line = reader.readLine()
        if ( line != null ) {
          val tokens = line.split(",").toList
          if ( tokens.length < 3 ) {
            throw new DataRetrievalException(
              "Data service at URL=["+queryUrl+"] does not supply enough fields (3 != "+tokens.length+")")
          }
          var stockSymbol = tokens(0)
          if ( stockSymbol.length() > 0 &&
              stockSymbol.charAt(0) == '"' && stockSymbol.charAt(stockSymbol.length()-1) == '"') {
            stockSymbol = stockSymbol.substring(1, stockSymbol.length()-1 )
          }
          val askPrice = tokens(1)
          if ( "N/A".equals(askPrice)) {
            throw new UnknownStockSymbolException(
              "Unknown stock quote symbol ["+stockSymbol+"] price not available")
          }
          val bidPrice = tokens(2)
          if ( "N/A".equals(bidPrice)) {
            throw new UnknownStockSymbolException(
              "Unknown stock quote symbol ["+stockSymbol+"] price not available")
          }

          try {
            return new StockQuote(stockSymbol, askPrice, bidPrice)
          }
          catch {
            case e:NumberFormatException =>
              throw new DataRetrievalException(
                "Unable to read numerical data from quote service URL=["+queryUrl+"]", e)
          }
        }
        else {
          throw new DataRetrievalException(
            "Data unavailable from quote service URL=["+queryUrl+"]")
        }
      }
      finally  {
        if ( reader != null) {
          try {
            reader.close()
          }
          catch  {
            case e: IOException => null
          }
        }
        if ( is != null) {
          try {
            is.close()
          } 
          catch {
            case e: IOException => null
          }
        }
      }
    }
    catch {
      case e: MalformedURLException  =>
        throw new ConnectionException("unable to connect to the remote quote service URL=["+queryUrl+"]", e)

      case e: IOException =>
        throw new ConnectionException("I/O failure reading service URL=["+queryUrl+"]", e)
    }
  }
}

 

Effectively, we could have left the QuoteRetriever as a simple Java interface, because we gained nothing. If however we wanted to define a default implementation in a Scala trait we could do so, where it would be not possible with the current version of Java 6 / 7.

We make use of the companion object QuoteRetrieverYahooImpl to define Scala constants. Essentially this would be same as declaring a Java variable as public final static String.

Inside the QuoteRetrieverYahooImpl class, let us look at the implementation method getStockQuote(). We chucked away Java standard library StringTokenizer and replaced it with the nicer Scala equivalent. We split a String into Array[String] of fragments using the split method, and then convert the array into a list collection by calling toList. Since Scala 2.8, these methods toList(), toSet() and toArray() are ubiquitous across the Scala collections.

There is probably a more object functional way of building the temporary variables using functions and closures, however for intermediate Java developer this is easier to follow. The rest of the code is just boiler plate to tackle the exception handling of the Java I/O library. See the last part of this article for an improvement.

Last, but not least is the main application class in the StockQuoteApp.scala file.

 

package uk.co.xenonique.stockquoteapp_scala

import java.lang.System

class StockQuoteApp( retriever: QuoteRetriever, repo: QuoteRepository ) {
  

  def this() = this( new QuoteRetrieverYahooImpl(), new QuoteRepositoryKeyValueStore() )

  def doInteractive(): Unit = {

    println("=======================================================")
    println("   Welcome Peter Pilgrim's Stock Quote Application")
    println("=======================================================")

    var quit = false
    while ( !quit) {
      println("Type in a stock symbol or `:repo' to list the repository or `:quit' to quit")
      println("or `:clear' to clear the repository")
      var line = readLine("$ ")
      if ( line != "" ) {
        line = line.trim()
        if ( line.startsWith(":r") || line.startsWith(":p")) {
          val symbols  = repo.getSymbols()
          printf("%10s  %9s %9s %9s\n", "SYMBOL", "MEAN", "ASK", "BID")
          printf("%10s  %9s %9s %9s\n", "--------", "------", "-----", "-----")
          for ( symbol <- symbols ) {
            val quote = repo.get(symbol).get
            printf("%10s: %9.2f %9.2f %9.2f\n", quote.symbol, quote.meanPrice, quote.askPrice, quote.bidPrice )
          }
        }
        else if ( line.startsWith(":c")) {
          repo.clear()
          println("Repository cleared.")
        }
        else if ( line.startsWith(":q")) {
          quit = true
        }
        else {
          if ( line.length() > 0 ) {
            try {
              val quote = findAndUpdateStockQuote(line)
              printf("%s: %7.2f\n", quote.symbol, quote.meanPrice)
            }
            catch {
              case e:ConnectionException =>
                System.err.println("CONNECTION ERROR : "+e.getMessage())

              case e: UnknownStockSymbolException =>
                System.err.println("STOCK SYMBOL NOT FOUND : "+e.getMessage())
            }
          }
        }
      }
    }

    // Prints name and age to the console
    println("Goodbye.")
  }


  def  findAndUpdateStockQuote(symbol: String): StockQuote = {
    val quote = retriever.getStockQuote(symbol)
    repo.store(quote)
    quote
  }

}

object StockQuoteApp {
  val CONNECTION_PROPERTIES_FILENAME: String = "connection.properties"

  def main( args: Array[String] ): Unit = {
    println("Hello world. This is the Scala application!")
    new StockQuoteApp().doInteractive
  }
}

 

It should be fairly self-explanatory that this program is interactive one. It reads a symbol at the command line and invokes the quote retriever to find the stock quote for the symbol.

There is one other improvement to QuoteRetrieverYahooImpl we could make use of. Scala supports function objects; functions calling other functions and returning a different (or the same input) function. Scala methods on class or object types can have more than one parameter list in order to support currying of parameters. Scala language has the feature of partial functions that enable this facility.

Here is a class called TryResource, which closes an InputStream resource.

 

package uk.co.xenonique.stockquoteapp_scala

import java.io.InputStream
import java.io.FileInputStream
import java.io.InputStreamReader
import java.io.BufferedReader
import java.io.IOException
import java.lang.System

// Needs to be generic
class TryResource[T <: InputStream]( inputStream: T ) {

  private val is: T = inputStream

  def execute( body: ( InputStream => Unit ) ): Unit = {
    try {
      body(is)
    }
    finally {
      if ( is != null ) {
        try {
          is.close()
        }
        catch {
          case e:IOException => System.err.println(e)
        }
      }
    }
  }
}

object TryResource {

  def tryResource[T <: InputStream]( inputStream: T )( body: ( InputStream => Unit ) ) {
    val construct = new TryResource( inputStream)
    construct.execute( body )
  }

  def demo1() {
    val construct = new TryResource( new FileInputStream("pom.xml") )
    construct.execute( (is: InputStream ) => {
      val reader = new BufferedReader( new InputStreamReader(is))
      var count = 1
      var line: String = null
      do {
          line = reader.readLine()
          if ( line != null ) {
            printf("demo1 %5d %s\n", count, line)
            count = count + 1
          }
      }
      while ( line != null  )
    } )
    println("==== Done it ====")
  }

  def demo2() {
    tryResource ( new FileInputStream("pom.xml") ) ( ( is: InputStream ) =>  {
      val reader = new BufferedReader( new InputStreamReader(is))
      var count = 1
      var line: String = null
      do {
          line = reader.readLine()
          if ( line != null ) {
            printf("demo2 %5d %s\n", count, line)
            count = count + 1
          }
      }
      while ( line != null  )
    } )
    println("==== Done it ====")
  }

  def main( args: Array[String]): Unit = {
    demo2()
  }
}

 

The method tryResource takes two parameter lists. The first parameter list is a argument list of one, the input stream resource. The second parameter list is also a argument of one, except it is a so-called called-by-name type, by which the function call is delayed, evaluated after inside the method. In other words, we call tryResource()() by passing a block of code that operates on the InputStream and the library function will automatically close the resource for us, regardless of whether block of code completes with normal or abnormal termination. Java 7 now has a similar acquire-release mechanism as a language feature, whereas in Scala, we implemented this a library feature. Scala is scalable language after all.

It would be straight forward now to use tryResource in the QuoteRetrieverYahooImpl directly. This is an exercise for you, the reader. Hint: You should have a good read about Scala’s structured types!

Good Luck!

The Collective Summer Camp UK Continues

July 26th, 2011 Comments off

 

In the first three weeks of July, I was super-busy, so The Collective Summer Camp UK had to take a backseat while I sorted out stuff. I am still pushing on with this event. I believe definitely that we should have this style of event happening in the UK. We have create the flaming green shoots of recovery somewhere in this land of Great Britain. We have be just the drivers and make sure that as software developers and designers make it happen!

I have no venue yet, but there are plenty of people really interested in taking part in a open-space conference and dojo combined all-dayer. I aiming to get a date of Saturday, 6th August 2011 in central London at the time of writing.

 

CollectiveSummerCampUK_512x384_logo

 

In the last weekend just gone, I created a Google Site Collective Summer Camp UK. The rewards are greater than the sum of parts, it would be great to crowd source some of this effort. Contact me directly please.

Register you interest here on this Google Form. The more people we have the more we can definitely push.

Weeks ago I brushed off my Wacom tablet and set about with the art in Adobe Illustrator. The logo features sun rays beaming through the sky. Notice there are no clouds in the sky to block the energy of Sun or mar our joy. It’s a new day. I believe rather that this symbology is exactly what we need in this world, today. Bloody hell! The least we can do in this life is improve and change the future outlook with education, finding the next direction, and learning new skills.

We are The Collective and we are busting loose, I guarantee it.

 

Collective Summer Camp UK Info (mp3)

Master Java Performance Tuning

July 24th, 2011 Comments off

 

About three weeks ago, I was watching a Film 4 late night with my partner. We stumbled upon on a martial-arts movie, called Ip Man. We thought it was one of the best Kung Fu movies of recent times, up there with Kung Fu Hustle. Donnie Yen who played Ip Man, a semi-biographically account of one of Bruce Lee’s mentors. Ip Man was a discipline, evolutionary innovator and a formidable master of a fighting style called Wing Chun.

 

2129364060_b9e98300c6_o_500x333

 

I thought after watching this amazing award-winning film that Chinese culture teaches us about excellence. Especially, in the movie, at the very beginning other masters of Chinese Kung Fu were attempting to defeat Ip Man is bouts of educational study. In other words these fights were not about making money, popularity contest or even on how to pull. They were simply impressive in the objective to gain further knowledge, to live better healthily and be enlightened. Thus it posed a question in my mind about the concept of masters, disciples and followers.

I have been trying to figure why developers and designers, especially in the financial services, are suddenly tied to a cast iron grate, of fire-fighting the Java Virtual Machine, attempting to make it do things that it was not originally designed for. Sometimes these non-functional requirements have meant a thorough knowledge of the operation JVM, how it manages memory, what sort of byte codes are executed in order to obtain the best performance. People suddenly want a great deal of understanding of the garbage collection mechanism way beyond that was required for Java EE 5 or 6, as they try to service 10 million records from database tables that are joined. Suddenly many more professionals are very interested in “Making it go-faster still”.

Why are developers in certain investment banks so willing to write Java like if it was C or C++? Surely this is wrong way to go? What is it about multiple threads that developers are not willing to use the Java SE 5 Executors or apply Java SE 6 concurrency utilities? Why are they willing rewrite their own Collections API? (Of course that is interesting for me personally for study in terms of the Scala Collections version 2.8 and better)

 

KirkPepperdine_400x517

Master Pepperdine

 

I know a little bit about Java Performance, but I need to understand it in much better than I do now. So like the prodigal masters of Kung Fu in alternate style, I need to understand performance on Java from someone who definitely knows what they are talking. Remember that concept of reputational risk that I mentioned in the JavaOne reviewer blog entry, well that risk is minimised when you sit, learn and study with a master. For me this master is Pepperdine.

Come September 2011, I am off to Crete to study with a master: Java Performance Tuning Training Course from Kirk Pepperdine. These old JAVAWUG videos can provide the reason why?

PS: Photo credit from the artful, talented and impressive Chicago Wuhsu, Illinois, USA, 2011

 

JAVAWUG BOF 38 Concurrency and Performance Part 1 from Peter Pilgrim on Vimeo.

JAVAWUG BOF 38 Concurrency and Performance Part 2 from Peter Pilgrim on Vimeo.


Meet Your JavaOne 2011 Rich Media Track Reviewer

July 24th, 2011 Comments off

In April, 2011, I received one morning an email from Simon Ritter one of Sun Microsystems long standing Java Evangelists and now Oracle. The message was an invitation to be a part of Java SE, Client Side Technologies, and Rich User Experiences track. The track included all JavaFX sessions submitted along with any other UI related sessions. Simon had invited me to be track reviewer for JavaOne 2011. Of course, with hesitation, I said yes!

 

DSCF2721_400x533_bw

 

I submitted myself a couple of papers to JavaOne 2011 in a track that was fiercely competitive. I will be speaking on JavaFX 2.0. There is a lot to be said of the talented people who made it through to the end. I was a little bit surprised by a small number of proposals that were not relevant to Java platform. If you want some advice on submitting a J1 proposal then here is mine:

First rule: Know Your Audience; Do aim for Java relevant content when the organiser and reviewing committee explicitly say they are looking for it. Your proposal has to exploit features of the Java platform, probably in new unexpected and innovative ways.

Second rule: Promise Really Good Know-How and Transferable Content; write a decent abstract that rather aptly declares that you are going to serve the audience. Make sure that the proposal is sufficiently detailed. Remember that first impressions last, therefore check your English for any grammatical errors, hyperbole and nonsensical arguments.

Third rule: Provide Capable Evidence; Much of JavaOne presentation comes from a reputation. Respect is earned from previous behaviours. JavaOne should really not be your very first public speaking situation?! Your reputational risk is usually up against big-draws, including the rockstar developers, who keep coming back every year for another session or two. If you have in the past spoken well at other Java conference then it helps the reviewer make a decision about you.

 

DSCF2729_400x533_bw

 

Whilst there are places for brand new unknown speakers, these opportunities tends to be usually very far and between, so if this is your first public speaking situation then you must already better than very good. In fact, I was would expect you to be amazing. My advice is to attempt to hone your speaking skills at a much smaller scale conference. Here is an analogy, learn to play to crowd as a singer/musician at The Jazz Cafe, before you take on the stadium rock of the Tokyo Dome.

The audience is usually large for a popular technical session, and for the most popular talks there are people queuing up outside to get in that room. You can find yourself standing in-front of a 200 – 300 audience member set, easily.  Some JavaOne attendees travel long distances to get to San Francisco, from London, United Kingdom;  from Brisbane, Australia, Sao Paulo in Brazil; Brizzabane, Congo, St. Petersburg in Eastern Europe and Seoul, South Korea  to hear what is new and great about the Java platform. They are the ambassadors for their respective countries, territories and native language locales. As well as people from North America these are the people who are need to be impressed by your proposal, your talk.

Above all, JavaOne is about investment education, finding out what, where, and who are the things that I as a developer, designer or architect should spent my next 365 days studying for, learning about or interacting with.

If your topic is too narrow as a subject matter then, we, as program reviewers, working in the committee team, we have to think why is it so niché? So broad a category, then we have to think your proposal may not possibly cover all of what you promise. I do say promise, with conviction, because at JavaOne you have to perform in order to be a success. It is all about performance and delivery.

 

DSCF2723_400x567_crop_bw

 

I will be seeing you at JavaOne 2011 from 2nd – 6th October. I agree with Oracle it is time to move Java platform along. Thank you Oracle for taking the initiative.

PS: Thanks to the track reviewers in our team including Jim Clarke, Stephen Chin, Dean R Iverson, Simon Ritter, Jim Weaver and Geertjan Wielenga.

Scalafication of an Equity Quote Application Part 2

July 23rd, 2011 2 comments

In Part 1 of this article, we discussed the Java language form of an exercise project. The task was to create an equity quote application that retrieved stock prices from a public web service Yahoo! Finance.

Let me suggest a really good process of adopting Scala inside the organisation: take the unit tests written in Java and port them to Scala. The Java implementation does not change and one can learn Scala principles by applying test first and test driven principle.
In the twenty tens, as a modern software practitioner, you must be familiar with JUnit and also the Hamcrest matchers, which are unit test framework by Kent Beck and fluent assertion matchers respectively. The pun was deliberately intended as you will read in the rest of this article.

Just because you start writing Scala does not mean that now you have to give up unit testing (JUnit or TestNG). You can also use Hamcrest Matchers directly from Scala. For example here a unit test:

import org.junit._
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers._

@Test
class SimpleTest  {
     def shouldVerifyTheEssence() {
           val expected = List( 1,1,2,3,5,8 ) 
           val actual = flatten( List(List(1, 1), 2, List(3, List(5, 8)))) )
           assertThat( actual, is(expected )
     }
}

Notice, that you can use annotations in Scala as well. Of course, the immutable variable references are unnecessary, however the purpose of the unit test should be clear to read. Your pairing partner should be able to understand your intent and can agree with you that it is concise. The method flatten reduces a nest list collection to a single list collection. The Hamcrest matchers are useful for fluent API programming, such that the code almost reads like an English description. For more information on Hamcrest, see the tutorial.

Let me introduce you to Scala Test, which is a fluent API testing framework written by Bill Venners, and it can be called from JUnit and it has support for behaviour driven design (BDD). You can use the assertion API from the JUnit inside a ScalaTest like this:

import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
import org.junit.Assert._
import org.scalatest.junit.JUnitRunner
import org.junit.runner.RunWith

@RunWith(classOf[JUnitRunner])
class FibonacciSeriesSpec extends FlatSpec with ShouldMatchers {

  "A Fibonacci function" should "establish a mathematical series" in {
        val expected = List( 0, 1,1,2,3,5,8,13,21, 34, 55, 89, 144, 233, 377, 610, 987 ];
        expected.foreach( x => assertEquals( x, fibonacci(x) )
  }

}

Behind the scenes of this examples are a few bits of knowledge:

  • This is the short form of running a JUnit test with ScalaTest, because I prefer to use the JUnit Runner and because it avoids writing the companion object. With JUnit (or TestNG) runners the test can be launched from popular Java tools like SBT, Maven or an IDE.
  • The specification is essentially a JRuby (RSpec) syntax in keeping with the BDD style (See Dan North on Introduction BDD)
  • Demonstrates that domain specific language can be written in Scala.
  • A fluent API in Scala can be supported by Scala powerful implicit conversions
  • The unit tests are readable, the expected behaviour of the target can be literally described in the language. Once again, it about Scala’s exceptional ability to allow developers to express their intent in a concise fashion.
  • ScalaTest allows you to reuse traditional style of unit testing too. You can find example of a JUnit 4 style in Scala here.

There is another Scala testing framework for BDD called Specification, which can be found here
http://code.google.com/p/specs. Here is an example for writing an executable specification with this framework very quickly.

import org.specs._

class MySpec extends SpecificationWithJUnit {
  "This wonderful system" should {
    "save the world" in {
      val list = Nil
      list must beEmpty
      println ("Done with the specification")
    }
  }
}

(UPDATED: This framework has been superseded by second version called Specs 2 http://specs2.org/. Thanks to Eric Torreborre for the corrections.)

With both ScalaTest and Specification, it is possible to use a mixture of the fluent and traditional assertion API in the unit tests. The quote retriever examples that I developed used ScalaTest, I prefer to use the BDD style rather than the traditional JUnit style, because it reads easier to a non-coder (or a line manager ;-) .

ScalaTest has a few specification styles that support alternative BDD styles. There are the FeatureSpec, FlatSpec, and my own favourite WordSpec. These styles are mixed into tests as Scala traits. In order to complete the BDD style you normally mix in the ShouldMatchers, and therefore you do not need the Java styled JUnit assertion classes or the Hamcrest Macthers.

This is an example of the FeatureSpec style.

import org.scalatest.Spec
import org.scalatest.matchers.ShouldMatchers
import scala.collection.mutable.Stack

class StackSpec extends Spec with ShouldMatchers {

  describe("A Stack") {

    describe("(when empty)") {

      val stack = new Stack[Int]

      it("should be empty") {
        stack should be ('empty)
      }

      it("should complain when popped") {
        evaluating { stack.pop() } should produce [NoSuchElementException]
      }
    }
  }
}

This is an example of the WordSpec style.

import org.scalatest.WordSpec
import org.scalatest.matchers.ShouldMatchers
import scala.collection.mutable.Stack

class StackSpec extends WordSpec with ShouldMatchers {

  "A Stack" when {
    "empty" should {
      val stack = new Stack[Int]

      "be empty" in {
        stack should be ('empty)
      }

      "add one item and remove one item" in {
          stack.push(1974)
          stack should not be ('empty)
          stack.pop() should be 1974
          stack should be ('empty)
      }

      "complain when popped" in {
        evaluating { stack.pop() } should produce [NoSuchElementException]
      }
    }
  }
}

In the Java world, I discovered years ago, the Mockito framework as a great mocking tool. Did you know that you can use Mockito in a Scala as well, and therefore with ScalaTest? Here is how. Here follows the first the unit test that uses ScalaTest to verify the operation of the stock quote retriever.

package uk.co.xenonique.stockquoteapp_scala

import org.scalatest.WordSpec
import org.scalatest.mock.MockitoSugar
import org.scalatest.junit.JUnitRunner
import org.scalatest.matchers.ShouldMatchers
import org.mockito.Mockito._
import org.junit.runner.RunWith

@RunWith(classOf[JUnitRunner])
class StockQuoteAppTest extends WordSpec with ShouldMatchers with MockitoSugar {

  "The quote retriever" should {
    "get stock quotes" in {
      val repo: QuoteRepository = new QuoteRepositoryKeyValueStore()
      val mockRetriever: QuoteRetriever = mock[ QuoteRetriever ]

      val expected1 = new StockQuote("APPL", "100.24", "100.20")
      when( mockRetriever.getStockQuote( expected1.symbol )).thenReturn(expected1)

      val expected2 = new StockQuote("PILG", "725.96", "721.32")
      when( mockRetriever.getStockQuote( expected2.symbol )).thenReturn(expected2)

      val app = new StockQuoteApp( mockRetriever, repo )

      app.findAndUpdateStockQuote(expected1.symbol)
      repo.get( expected1.symbol).get should be === expected1 

      app.findAndUpdateStockQuote(expected2.symbol)
      repo.get( expected2.symbol).get should be === expected2 

      repo.isEmpty() should be === false 
      repo.size() should be === 2

      verify(mockRetriever).getStockQuote(expected1.symbol)
      verify(mockRetriever).getStockQuote(expected2.symbol)
    }
  }

  "The quote retriever" should {
    "get stock quotes with one changed" in {

      val repo: QuoteRepository = new QuoteRepositoryKeyValueStore()
      val mockRetriever: QuoteRetriever = mock[QuoteRetriever]

      val expected1 = new StockQuote("APPL", "100.24", "100.20")
      when( mockRetriever.getStockQuote( expected1.symbol )).thenReturn(expected1)

      val expected2 = new StockQuote("PILG", "725.96", "721.32")
      when( mockRetriever.getStockQuote( expected2.symbol )).thenReturn(expected2)

      val app = new StockQuoteApp( mockRetriever, repo )

      app.findAndUpdateStockQuote(expected1.symbol)
      repo.get( expected1.symbol).get should be === expected1 

      app.findAndUpdateStockQuote(expected2.symbol)
      repo.get( expected2.symbol).get === expected2 

      repo.isEmpty() should be === false 
      repo.size() should be === 2

      val expected3 = new StockQuote("APPL", "101.50", "101.46")
      when( mockRetriever.getStockQuote( expected3.symbol )).thenReturn(expected3)

      app.findAndUpdateStockQuote(expected3.symbol)
      repo.get( expected3.symbol).get should be === expected3 

      repo.isEmpty() should be === false 
      repo.size() should be === 2

      verify(mockRetriever, times(2) ).getStockQuote(expected1.symbol)
      verify(mockRetriever, times(1) ).getStockQuote(expected2.symbol)
    }
  }

}

Oh yes, I forgot to mention that ScalaTest has a special method called ===. In Scala, identifiers can be mixed characters, and the triple equals serves as an assertion equality operator to compare expected and actual results. This operator aid debugging and when a test fails prints out the expected and actual values and more important where in the stacktrace the failure occured. In my opinion, for the negative cases, ScalaTest needs an associative operator !===.

In the unit test, please note, I have duplicated some assertions with the should matchers and also the equality operator in ordered to prove that the two forms are the same. For mathematical derived testing for finance or science, I think that I would prefer the “===” operator rather the long english form. It will depend on your style of testing, but the fact that ScalaTest allows different art forms, in itself, is great.

      repo.isEmpty() should be === false 

      repo.isEmpty() should be !=== true // Does not exist in ScalaTest 1.3

      assert ( repo.size() === false )

ScalaTest has good documentation on all of the available types of ShouldMatchers here. You will find relational operations like greaterThan or lessThan over there.

Here follows the second unit test that verifies the operation of the quote key value repository.

package uk.co.xenonique.stockquoteapp_scala

import org.scalatest.WordSpec
import org.scalatest.matchers.ShouldMatchers
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner

@RunWith(classOf[JUnitRunner])
class QuoteRepositoryKeyValueTest extends WordSpec with ShouldMatchers {

  "quote repository key value store" should {
    "initialise well" in {
      val store:QuoteRepository = new QuoteRepositoryKeyValueStore()
      assert( store.isEmpty() === true )
      assert( store.size() === 0 )
      store.isEmpty should be === true
      store.size() should be === 0
    }
  }

  "quote repository key value store" should {
    "store and retrieve stock quotes" in {
      val store = new QuoteRepositoryKeyValueStore()
      val expected1 = new StockQuote("PILGRIM", "123.45", "123.12" )

      store.store(new StockQuote(expected1))
      assert( store.isEmpty() === false )
      assert( store.size() === 1 )
      store.isEmpty should be === false
      store.size() should be === 1

      assert( store.get("PILGRIM").get === expected1 )

      val expected2 = new StockQuote("PILGRIM", "555.55", "555.12" )
      store.store(expected2)
      assert( store.isEmpty() === false )
      assert( store.size() === 1 )

      store.get("PILGRIM").get should not be expected1
      store.get("PILGRIM").get should be === expected2
      assert( store.get("PILGRIM").get === expected2 )
    }
  }

  "quote repository key value store" should {
    "store and retrieve multiple stock quotes" in {
      val store = new QuoteRepositoryKeyValueStore()
      assert( store.isEmpty() === true )
      assert( store.size() === 0 )

      val quotes = List(
        new StockQuote( "LYG", "4.020", "4.015" ),
        new StockQuote( "RBS.L", "39.58", "39.48" ),
        new StockQuote( "HSBC.L", "646.65", "646.62" ),
        new StockQuote( "ORCL", "27.75", "27.74" ) )

      for (quote <- quotes) store.store(quote)

      assert( store.size() === quotes.length )
      assert( store.isEmpty() === false)

      for (quote <- quotes) {
        assert( store.contains(quote.symbol ) === true )
        assert( store.get(quote.symbol ).get == quote )
      }

      val symbols = store.getSymbols()
      assert( symbols.size === quotes.size )
      for ( quote <- quotes) {
        assert( symbols.contains(quote.symbol ) === true )
      }

      store.clear()
      assert( store.isEmpty() === true )
      assert( store.size() === 0 )
    }
  }
}

In part 3, we will see the code implementation of quote retriever in Scala.

Learn a new language! Maintenance mode programmers please go elsewhere!

Word.


Scalafication of a Java Equity Quote Application Part 1

July 1st, 2011 1 comment

Here follows in these series of three article is a description of Scala application that ported from Java. I would prefer to call this work a “Scalafication”.

Many people are thinking about Scala Adoption as it gets important interest from the wider community. Did you know that Professor Martin Odersky won the Java Top Ambassador award at the JAX Conference 2011? I think as you might do that Java the programming language is now very mature and that it is getting long in the tooth. However, Java is still very important for open source libraries, because the vast majority of the framework and library landscape, out there, has been very built with Java the programming language. Therefore interoperability is going to be important, and whenever they get around to my favourite [fictional] JSR 555, which will standardise the interoperability between Java and Beyond Java, the holy grail of meta-object protocol, virtual classes, static and dynamic languages and the JVM byte code executor will be a momentous occasion in the history of the Java platform. However, I digress and pat myself down due my excitement.

(Please start your favour MP3 player now on the track: Holst – The Planets – “Jupiter”. You are going need some inspiration.)

Overall Project Summary

The task for this Java project was to retrieve stock quotes from Yahoo Financial Quotes services, store these quotes in a repository, and all prospective users to interrogate the repository for a quotes. If the quote does exist in the repository then the application should go the Yahoo web service and pull down the quote. If it is newer store it in the cache and then return the result to the user.

Project Requirement

The Java application stored the latest quote on a data store (so that, say, a banking risk manager department could compare quotes to some trade that may have been made by the user through some other system). The application displayed the equity stock quote (the average of bid and ask prices) to the user.

The Java application was a prototype. The client envisioned Spring MVC and Hibernate as the web framework solution, which of course meant a relational database. The prototype was a single-user, and build with Apache Maven.

User Stories

For the original Java prototype, there were two user stories:

S1 “A trader wants to see the stock quote for a given ticker symbol so that she can buy and sell the relevant financial instrument at a good market price”.

S1-Acceptance Criteria

A1-1 “Type in a Yahoo ticker symbol and within one second see the current price.  The current price should be approximately equal to that available from a Google search”

A1-2 “Type in an invalid ticker symbol and within one second see an error message”

S2 “A risk analyst wants to view a repository of ticker symbols together with the latest price in each case as last viewed by the stock system’s user so that I can compare these to prices traded by the user on other systems.”

S2-Acceptance Criteria

A2-1 “From an empty data store, use the stock system to view ORCL and then RHT noting their current value.  Then query the data store to ensure those values have been recorded.”

A2-2 “Wait till the Oracle price has changed (a quarter of an hour during NY trading hours 2:30PM to 9:05PM UK time should be sufficient) and then re-query ORCL noting the new price.  Then re-query the data store to ensure that the value had been updated for ORCL and the RHT value is unchanged”.

Original Java Interfaces

In order to port the prototype easy I started the Java interface and the unit tests.

Here is a design-by-contract interface for a quote repository

package uk.co.xenonique.stockquoteapp;

import java.util.List;

/**
 * A contract for a stock quote repository
 * @author Peter
 */
public interface QuoteRepository {

	public boolean isEmpty();
	public int size();
	public void clear();
	public void store( StockQuote quote );
	public StockQuote get( String symbol );
	public boolean contains( String symbol );
	public List<String> getSymbols();
}

Here, with QuoteRepository, the contract is to store and retrieve a stock quote by a symbol. You can check if the repository is empty or not, how many quotes it stores and clear it out. You can enquire also if stock quote is part of the repository by symbols, and finally you can a list collection of stock exchange symbols. By inspection, this interface, looks to be an associative collection, a map type.

Here is an implementation that uses a repository key value storage. Notice that I chose the ConcurrentHashMap to store the key value. Strictly, speaking it could have been a HashMap too, since the prototype was a single-user. Where have you seen a single-user system in existance if ever?

package uk.co.xenonique.stockquoteapp;

import java.util.*;
import java.util.concurrent.*;;

/**
 * A key value store representation of the stock quote repository
 * @author Peter
 */
public class QuoteRepositoryKeyValueStore implements QuoteRepository {

	private Map<String, StockQuote> store = new ConcurrentHashMap<String, StockQuote>();
	
	@Override
	public void clear() {
		store.clear();
	}

	@Override
	public boolean contains(String symbol) {
		return store.containsKey(symbol);
	}

	@Override
	public StockQuote get(String symbol) {
		return store.get(symbol);
	}

	@Override
	public boolean isEmpty() {
		return store.isEmpty();
	}

	@Override
	public int size() {
		return store.size();
	}

	@Override
	public void store(StockQuote quote) {
		store.put(quote.getSymbol(), quote);
	}
	
	@Override
	public List<String> getSymbols() {
		List<String> symbols = new ArrayList<String>();
		symbols.addAll( store.keySet() );
		Collections.sort(symbols);
		return symbols;
	}

}

Here is interface for a quote retriever

package uk.co.xenonique.stockquoteapp;

public interface QuoteRetriever {
	public StockQuote getStockQuote( String symbol );
}

This is a contract to retrieve a stock quote from a system and return it the user.
Here is an implementation of it that talks to the Yahoo web service.

/**
 * 
 */
package uk.co.xenonique.stockquoteapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;

/**
 * Yahoo web site stock retriever
 * @author Peter
 */
public class QuoteRetrieverYahooImpl implements QuoteRetriever {

	public final static String TOKEN_SYMBOL="@SYMBOL@";
//	private final static String URL_FRAGMENT="http://finance.yahoo.com/d/quotes.csv?s=@SYMBOL@&f=sb2b3jk";
	private final static String DEFAULT_URL_FRAGMENT="http://finance.yahoo.com/d/quotes.csv?s="+TOKEN_SYMBOL+"&f=sb2b3";
	
	private String urlFragment = DEFAULT_URL_FRAGMENT; 

	@Override
	public StockQuote getStockQuote(String symbol) {
		String queryUrl = urlFragment.replace(TOKEN_SYMBOL, symbol);
		try {
			URL url = new URL( queryUrl );
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();
			connection.setRequestMethod("GET");
			connection.connect();

			InputStream is = connection.getInputStream();
			BufferedReader reader = new BufferedReader( new InputStreamReader(is) );
			
			try {
				String line = reader.readLine();
				if (  line != null ) {
//					System.out.println("*DEBUG* : line="+line);
					String stockSymbol;
					String askPrice;
					String bidPrice;
					StringTokenizer stk = new StringTokenizer(line, ",");
					int countTokens = stk.countTokens();
					if ( countTokens < 3 ) {
						throw new DataRetrievalException("Data service at URL=["+queryUrl+"] does not supply enough fields (3 != "+countTokens+")");
					}
					stockSymbol = stk.nextToken();
					if ( stockSymbol.length() > 0 &&
							stockSymbol.charAt(0) == '"' && stockSymbol.charAt(stockSymbol.length()-1) == '"') {
						stockSymbol = stockSymbol.substring(1, stockSymbol.length()-1 );
					}
					askPrice = stk.nextToken();
					if ( "N/A".equals(askPrice)) {
						throw new UnknownStockSymbolException("Unknown stock quote symbol ["+stockSymbol+"] price not available");
					}
					bidPrice = stk.nextToken();
					if ( "N/A".equals(bidPrice)) {
						throw new UnknownStockSymbolException("Unknown stock quote symbol ["+stockSymbol+"] price not available");
					}
					
					return new StockQuote(stockSymbol, askPrice, bidPrice);
				}
				else {
					throw new DataRetrievalException("Data unavailable from quote service URL=["+queryUrl+"]");
				}
			} 
			finally  {
				if ( reader != null) {
					try {
						reader.close();
					} catch (Exception e) {
					}
				}
				if ( is != null) {
					try {
						is.close();
					} catch (Exception e) {
					}
				}
			}
		} 
		catch (MalformedURLException e) {
			throw new ConnectionException("unable to connect to the remote quote service URL=["+queryUrl+"]", e);
		}
		catch (IOException e) {
			throw new ConnectionException("I/O failure reading service URL=["+queryUrl+"]", e);
		}
	}

	public String getUrlFragment() {
		return urlFragment;
	}

	public void setUrlFragment(String urlFragment) {
		this.urlFragment = urlFragment;
	}
}

This is all very straight forward Java Networking that you all should know and love by now.

Here is the equity stock quote data class

package uk.co.xenonique.stockquoteapp;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class StockQuote {
	private final String symbol;
	private final BigDecimal askPrice;
	private final BigDecimal bidPrice;
	private final BigDecimal meanPrice;

	private final static BigDecimal TWO= new BigDecimal("2.0");
	
	public StockQuote(String symbol, String askPrice, String bidPrice) {
		this( symbol, new BigDecimal(askPrice), new BigDecimal(bidPrice));
	}

	public StockQuote(String symbol, BigDecimal askPrice, BigDecimal bidPrice) {
		this.symbol = symbol;
		this.askPrice = askPrice.setScale(2);
		this.bidPrice = bidPrice.setScale(2);
		this.meanPrice = calcMeanPrice(askPrice, bidPrice);
	}

	/**
	 * Copy constructor 
	 * @param ref the reference
	 */
	public StockQuote(StockQuote ref) {
		this.symbol = ref.symbol;
		this.askPrice = ref.askPrice.setScale(2);
		this.bidPrice = ref.bidPrice.setScale(2);
		this.meanPrice = bidPrice.add( askPrice.subtract(bidPrice).divide( TWO ) );
	}

	private BigDecimal calcMeanPrice(BigDecimal askPrice, BigDecimal bidPrice) {
		return bidPrice.add( askPrice.subtract(bidPrice).divide( TWO ) ).setScale(2, RoundingMode.DOWN );
	}

	public String getSymbol() {
		return symbol;
	}

	public BigDecimal getAskPrice() {
		return askPrice;
	}

	public BigDecimal getBidPrice() {
		return bidPrice;
	}
	
	public BigDecimal getMeanPrice() {
		return meanPrice;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((askPrice == null) ? 0 : askPrice.hashCode());
		result = prime * result
				+ ((bidPrice == null) ? 0 : bidPrice.hashCode());
		result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		StockQuote other = (StockQuote) obj;
		if (askPrice == null) {
			if (other.askPrice != null)
				return false;
		} else if (!askPrice.equals(other.askPrice))
			return false;
		if (bidPrice == null) {
			if (other.bidPrice != null)
				return false;
		} else if (!bidPrice.equals(other.bidPrice))
			return false;
		if (symbol == null) {
			if (other.symbol != null)
				return false;
		} else if (!symbol.equals(other.symbol))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "StockQuote [ symbol=" + symbol +", askPrice=" + askPrice + 
		", bidPrice=" + bidPrice + ", meanPrice="+meanPrice+"]";
	}
}

I need you to notice that it is an immutable object class. It is a stock quote that aggregates the symbol, ask and bid prices together. It borrows from C++ with a copy constructor, it has the hashCode() and equals() and a toString().

Finally, lets look at a unit test that ties it all together

package uk.co.xenonique.stockquoteapp;

import org.junit.*;
import static org.junit.Assert.*;

public class QuoteRetrieverYahooTest 
{
    @BeforeClass 
    public static void loadProxySettings()
    {
        StockQuoteApp.applyConnectionPropertiesFile();
    }

    @Test
    public void shouldRetrieveStockQuote()
    {
        QuoteRetriever retriever = new QuoteRetrieverYahooImpl();
        StockQuote quote = retriever.getStockQuote("ORCL");
        assertNotNull(quote);
        assertEquals("ORCL", quote.getSymbol());
        assertNotNull( quote.getAskPrice());
        assertNotNull( quote.getBidPrice());
        assertNotNull( quote.getMeanPrice());		
    }

    @Test(expected=UnknownStockSymbolException.class)
    public void shouldRaiseErrorWithUnknownStockSymbol()
    {
        QuoteRetriever retriever = new QuoteRetrieverYahooImpl();
        retriever.getStockQuote("UNKNOWN");
    }

    @Test(expected=ConnectionException.class)
    public void shouldRaiseConnectionFailure()
    {
            QuoteRetrieverYahooImpl retriever = new QuoteRetrieverYahooImpl();
        retriever.setUrlFragment("http://foo.finance.yahoo.com/"+QuoteRetrieverYahooImpl.TOKEN_SYMBOL);
        retriever.getStockQuote("MFST");
    }
}

There is another unit test to verify the operation of the key value repository.

package uk.co.xenonique.stockquoteapp;

import java.util.List;

import org.junit.*;
import static org.junit.Assert.*;

public class QuoteRepositoryKeyValueTest {
	
	@Test
	public void shouldInitialiseWell() {
		QuoteRepository store = new QuoteRepositoryKeyValueStore();
		assertTrue(store.isEmpty());
		assertEquals(0,store.size());
	}

	@Test
	public void shouldStoreAndRetrieve() {
		QuoteRepository store = new QuoteRepositoryKeyValueStore();
		StockQuote expected1 = new StockQuote("PILGRIM", "123.45", "123.12" );
		// Exercise the copy constructor in order to verify the store is not just using object references!
		store.store(new StockQuote(expected1));
		assertFalse(store.isEmpty());
		assertEquals(1,store.size());
		
		assertEquals( expected1, store.get("PILGRIM"));
		// Put an updated stock quote in the repository with same symbol for good measure
		StockQuote expected2 = new StockQuote("PILGRIM", "555.55", "555.12" );
		store.store(expected2);		
		assertFalse(store.isEmpty());
		assertEquals(1,store.size());
		
		// The quote inside the store is not equal to the old stock quote 
		assertNotSame( expected1, store.get("PILGRIM"));
		// The quote inside the store is equal to the new stock quote 
		assertEquals( expected2, store.get("PILGRIM"));
	}
	
	@Test
	public void shouldStoreAndRetrieveMultipleQuotes() {
		QuoteRepository store = new QuoteRepositoryKeyValueStore();
		assertTrue(store.isEmpty());
		assertEquals(0,store.size());
		
		StockQuote quotes[] = new StockQuote[] {
				new StockQuote( "LYG", "4.020", "4.015" ),
				new StockQuote( "RBS.L", "39.58", "39.48" ),
				new StockQuote( "HSBC.L", "646.65", "646.62" ),
				new StockQuote( "ORCL", "27.75", "27.74" ),
		};
		
		for (StockQuote quote: quotes) {
			store.store(quote);
		}
		
		assertEquals( quotes.length, store.size());
		assertFalse(store.isEmpty());

		for (StockQuote quote: quotes) {
			assertTrue( store.contains(quote.getSymbol()));
			assertEquals( quote, store.get(quote.getSymbol()));
		}
		
		List<String> symbols = store.getSymbols();
		assertEquals( quotes.length, symbols.size());
		for (StockQuote quote: quotes) {
			assertTrue( symbols.contains(quote.getSymbol()));
		}
		
		store.clear();		
		assertTrue(store.isEmpty());
		assertEquals(0,store.size());		
	}
}

These were the essential parts of the Stock Quote application written in Java. I have left some notable bits and bobs, such the exceptions, and also the main program. You can treat it as an exercise-for-the-reader to tie it all together. I will publish the Java main program later on.

The static method call StockQuoteApp.applyConnectionPropertiesFile() is a method, that initialised the Java system properties with a configuration that allowed the application to work behind a company Internet proxy. The properties file looks like this:

# File: ``Connection.properties''
# ==========================================
# Uncomment and set the proxy gateway for your environment
#
# Uncomment this line to use a Internet Proxy
http.proxySet=true
# Define the proxy hostmachine e.g. gateway.declan.server1
http.proxyHost=webcacge.proxyhost.mydomain.com
# Define the port number of the proxy e.g. 8080
http.proxyPort=8080
# Define the login name 
http.proxyUser=PILG1472
# Define the password
http.proxyPassword=PILGPASS
# Define the non proxy hosts
http.nonProxyHosts=otcdev57,otcdev1287,otcdev1244
# End

Next time. I will describe how I Scalafied these classes.

The Collective Summer Camp UK

July 1st, 2011 Comments off

 

Hi Everyone!

I am sorry if this has taken longer to announce than when I first tweeted it on Twitter on Sunday 25th August 2011.

I am organising the first Collective Sumer Camp UK, which inspired by my experience of attending the JavaPosse Round Up for three years in a row (2009, 2010, and 2011). The Round-Up is an open space technology conference created by The Java Posse, four experienced Java developers and designers, famous in the community, who have a regular podcast, and also long time technical book author and thinker, Bruce Eckel. The Round-Up is a normally a five day event and takes place in Crested Butte, Colorado. Very recently, the Round-Up expanded to Summer Programming Camp.

I had a lot of fun attending the Round-Ups, as you can see here and here. I thought and asked the question, why can we not doing something similar to the Round-Up here in the UK? Why not? Indeed.

Let us do it, instead of dreaming about it! Here is an audio-boo, which I recorded a few days ago, that has my essential ideas. I apologise here if it is a bit rambling or fast.

Announcing "The Collective Summer Camp UK": Rock Bottom Reached (mp3)

 

START SMALL

Let us go for the low-to-medium risk. We scope the requirements small in order to delivery the best result.

 

BRANDING

I have tentatively called it THE COLLECTIVE for a very good reason. I am personally no longer in the business of organising or running user groups. I am in the business of networking with other people, getting functional programming adopted in the industry, and welcome continuous learning. We are called THE COLLECTIVE of Java platform, who are about pushing it forward.

 

THEMES

The content of the open space conference is up to those who attend. However, I strongly feel that we should be learning and educating ourselves about Functional Java, Scala, Clojure, JRuby and Groovy.

 

SPLIT CONTENT

Because we only a full Saturday. I thought it would be best to split the day into two halves. In the morning we have the open space sessions, then we would break for lunch. In the afternoon, we can have programming exercise for the new JVM language and /or including functional Java. (I went to the London Clojure Dojo on Tuesday night, and it was really well run and a good experience. I should like to model these Dojos for the Saturday afternoon [Experts or advanced coaches / users should apply w/ interest!] ).

 

REGISTRATION AND SURVEY

You will find a Google Form to register your interest in The Collective Summer Camp. Thank you!

 

DATE AND TIME

The day of the Conference will be a Saturday either 30th July, 6th August or 13th August. It will be full day. See the registration and survey form.

 

PAID

The UK is going through the most dire and severe economic recessions at the moment. So I understand many of you, like me, do not have loads of money. The Collective Summer Camp UK ought be low cost. However, we cannot expect every single event to be a free ride. Someone or something has to be paid for their time and effort. Venue and location to be decided. The money goes to the organisation and any thing left over will go to food, pizza and soft drinks, and we can decide what to do with the rest of the money, like donate it charity or something.

HASHTAGS

#CollectiveSummerCampUK and includes #BeyondJava, #ScalaLang, #Clojure, #Groovy, etc .

Please retweet #CollectiveSummerCampUK and self-promote the event.

 

INCENTIVE

I need at least 25 people to register to make the event viable. Please your register interest for the event with the Google Form.

HELP

I need help to organise this event. Please enquire with your ideas today!

 

That is it for now. I am so pleased to come out of stealth-mode. The next bit will be to decide on venue, which most likely looks like most people like central London and that will drive the cost. Stay tuned. +PP+

Twitter: @peter_pilgrim or electronically at peter dot pilgrim at gmail dot com