Phillip Trelford's Array

POKE 36879,255

NDC Oslo 2015 Experience Report

Last week my son Sean and I popped over to Norway for NDC Oslo, billed as one of the world’s largest independent software conferences.

Venue

The venue, the Oslo Spektrum in the centre of the city was huge, with a large lower floor for vendors and refreshments surrounded by 9 rooms for talks. There were nearly 2000 delegates and nearly 200 speakers at the event, enjoying a veritable binge festival of hour long talks, and even a room where you could watch all the talks simultaneously on a series of big screens.

Invitation

My 8yo Sean had been invited to do a lightning talk, and according to one NDC conference organizer they were then stuck with inviting me along too, apparently something they wouldn’t have done otherwise, or so he felt compelled to tell me on our first meeting. The other organizers seemed happier to see me or perhaps were more able to exercise tact. Regardless, it was great to meet up with many friends old and new and from far and wide.


Travel

NDC were kind enough to arrange flights and accommodation for me, but I had to pay for Sean’s travel myself. The hotel was close to the venue, unfortunately when we arrived late on Wednesday night it was over-booked and the room we were initially sent to was already occupied, where the phrase what is seen cannot be unseen is probably quite fitting. Thankfully we were eventually rehoused in another hotel nearby. The next day we were asked to pay 4500Kr (450GBP) to remain in the hotel. After some assistance from organizer Charlotte Lyng we were relieved to be given an unoccupied room at the original hotel for the following nights.

Lightning talk

Sean’s lightning talk was after lunch on the Thursday, the room was standing room only with over 100 attending, and he had a great reception. He started with a short rendition of Pink Floyd’s Wish You Were Here while I set up the laptop (thanks to Carl Franklin of .Net Rocks for the loan of the guitar). Followed by the main content, a live coding session on Composing 3D Objects in OpenGL with F#.

There was a lot of reaction on Twitter, here's a few of the many tweets:






Thanks for all the supportive comments, this was only Sean's third public speaking engagement and he really enjoyed speaking at and attending the conference.

You can try composing your own 3D scenes in the browser with F# and WebGL at Fun3D.net


F# for C# developers

My talk was an introduction to the F# programming language from a C# developer's perspective and also seemed to be well received, although in terms of Twitter I was rightly eclipsed by my son Sean's efforts. In fact from now on I think I might be more commonly known as Sean's dad.



I also appear to have made the NDC Oslo speaker leaderboard, in the 100-200 audience category, thanks for all the greens votes! :)


Other talks

We saw some fantastic talks including Phil Nash on his C++ unit testing framework Catch, Gojko Azdic's thoughts on Continuous Delivery, Grey Young's new project PrivateEye, Tomas Petricek's live coded F# web programming session, Gary Short's Troll Hunting talk and many more. It was also great to see F# feature so heavily both on and off the functional programming track, and attendance on the FP track doubling since last year!

Summary

Both Sean and I really enjoyed the conference, there were a vast array of speakers to learn from, huge numbers of passionate developers to mingle with during the breaks and a very child friendly vendor floor. The floor was complete with a surfboard simulator, and Sean was very happy to win a Raspberry Pi for his efforts on it, along with enjoying an endless supply of ice cream! Also, look out for Sean's interview on Herding Code which should be out in a month or so.

For a Few Dollars More

This is a follow up to my last post A Fistful of Dollars, where I looked at test-driven approaches to implementing a money type based on the example running through Kent Beck’s Test-Driven Development by Example book:

Test-Driven Development By Example

In this run I decided as an exercise to skip formal unit testing altogether and just script the functionality for the multi-currency report that Kent is working towards over 100 pages or so of his book:

Money Example

Unsurprisingly It ended up being relatively quick and easy to implement.

Money type

First off we need a money type with an amount and a currency and support for multiplication and addition:

type Money = private { Amount:decimal; Currency:Currency } 
   with   
   static member ( * ) (lhs:Money,rhs:decimal) = 
      { lhs with Amount=lhs.Amount * rhs }
   static member ( + ) (lhs:Money,rhs:Money) =
      if lhs.Currency <> rhs.Currency then invalidOp "Currency mismatch"
      { lhs with Amount=lhs.Amount + rhs.Amount}
   override money.ToString() = sprintf "%M%s" money.Amount money.Currency
and  Currency = string

In the code above I’ve used an F# record type with operator overloads for multiplication and addition.

Exchange rates

Next we need to be able to do currency conversion based on a rate table:

type RateTable = { To:Currency; From:Map<Currency,decimal> }

let exchangeRate (rates:RateTable) cy =   
   if rates.To = cy then 1.0M else rates.From.[cy]

let convertCurrency (rates:RateTable) money =
   let rate = exchangeRate rates money.Currency
   { Amount=money.Amount / rate; Currency=rates.To }

Here I’ve used a record type for the table and simple functions to look up a rate and perform the conversion.

Report model

Now we need a representation for the input and output, i.e. the user’s positions and the report respectively:

type Report = { Rows:Row list; Total:Money }
and  Row = { Position:Position; Total:Money }
and  Position = { Instrument:string; Shares:int; Price:Money }

Again this is easily described using F# record types

Report generation

Here we need a function that takes the rates and positions and returns a report instance:

let generateReport rates positions =
   let rows =
      [for position in positions ->        
         let total = position.Price * decimal position.Shares
         { Position=position; Total=total } ]
   let total =
      rows
      |> Seq.map (fun row -> convertCurrency rates row.Total)   
      |> Seq.reduce (+)
   { Rows=rows; Total=total }

For the report generation I’ve used a simple projection to generate the rows followed by a map/reduce block to compute the total in the target currency.

Report view

There’s a number of different ways to view a generate the report. At first I looked at WinForms and WPF, which provide built-in data grids, but unfortunately I couldn’t find anything “simple” for showing summary rows.

In the end I plumped for a static HTML view with an embedded table:

let toHtml (report:Report) =
   html [
      head [ title %"Multi-currency report" ]      
      body [
         table [
            "border"%="1"
            "style"%="border-collapse:collapse;"
            "cellpadding"%="8"
            thead [
               tr [th %"Instrument"; th %"Shares"; th %"Price"; th %"Total"] 
            ]
            tbody [
               for row in report.Rows ->
                  let p = row.Position
                  tr [td %p.Instrument; td %p.Shares; td %p.Price; td %row.Total]
            ]
            tfoot [
               tr [td ("colspan"%="3"::"align"%="right"::[strong %"Total"])
                   td %report.Total]
            ]
         ]
      ]
   ]

For the HTML generation I wrote a small internal DSL for defining a page.

If you’re something a little more polished I found these static HTML DSLs on my travels:

Report data

Finally I can define the inputs and generate the report:

let USD amount = { Amount=amount; Currency="USD" }
let CHF amount = { Amount=amount; Currency="CHF" }

let positions =
   [{Instrument="IBM";      Shares=1000; Price=USD( 25M)}
    {Instrument="Novartis"; Shares= 400; Price=CHF(150M)}]

let inUSD = { To="USD"; From=Map.ofList ["CHF",1.5M] }

let positionsInUSD = generateReport inUSD positions

let report = positionsInUSD |> toHtml |> Html.toString

Which I think is pretty self-explanatory.

Report table

The resultant HTML appears to match the table from the book pretty well:

Instrument Shares Price Total
IBM 1000 25USD 25000USD
Novartis 400 150CHF 60000CHF
Total 65000USD

 

Summary

I was able to implement the report in small steps using F# interactive to get quick feedback and test out scenarios, with the final result being as expected on first time of running.

Overall I’m pretty happy with the brevity of the implementation. F# made light work of generating the report, and statically generated HTML produced a nice result with minimal effort, a technique I’ll be tempted to repeat in the future.

The full script is available as an F# Snippet.

A Fistful of Dollars

Just over a week ago I took the Eurostar over to Paris for NCrafts, a conference bringing together over 300 software craftsmen and craftswomen:

The event was held in a crypt and featured a good number of F# sessions:

Mathias Brandewinder gave an excellent closing talk on The T in TDD : tests, types, tales.

 NCrafts 2015 - May 2015

In this live coding session, Mathias took the multi-currency money example from Kent Beck’s seminal Test-Driven Development by Example book. First implementing a dollars class in C# driven by a unit test for quick feedback and then contrasting it with a similar implementation in F# using the REPL for immediate feedback.

Unit Test

The system needs to be able to multiply a price in dollars by a number of shares, so that 5 USD * 2 = 10 USD:

public class Tests
{
   [Test]
   public void five_dollars_times_two_should_equal_ten_dollars()
   {
      // arrange
      var five = new Dollars(5);
      // act
      var result = five.Times(2);
      // assert
      Assert.AreEqual(new Dollars(10), result);
   }
}

C# Dollars

Based on the test an immutable dollars class can be implemented:

public class Dollars
{
   private readonly decimal _amount;

   public Dollars(decimal value)
   {
      _amount = value;
   }

   public decimal Amount
   {
      get { return _amount; }  
   }

   public Dollars Times(decimal multiplier)
   {
      return new Dollars(this._amount * multiplier);
   }
}

The code now compiles, but the test fails!

C# Equality

The test fails because in C# class types use reference equality, so we must override Equals:

public class Dollars
{
   private readonly decimal _amount;

   public Dollars(decimal value)
   {
      _amount = value;
   }

   public decimal Amount
   {
      get { return _amount; }  
   }

   public Dollars Times(decimal multiplier)
   {
      return new Dollars(this._amount * multiplier);
   }

   public override bool Equals(object obj)
   {
      var that = obj as Dollars;
      return
         that != null
         ? this.Amount == that.Amount
         : false;
   }
}

Note: at this point FXCop will also recommend that we implement GetHashCode as we’ve implemented Equals.

F# Dollars

In F#, the simplest thing that could possibly work is a measure type which gives compile time type safety:

[<Measure>] type usd

5.0M<usd> * 2.0M = 10.0M<usd>

We can also test it immediately in F# Interactive as above, or alternatively write a unit test as below:

let [<Test>] ``5 USD * 2 = 10 USD`` () =
   Assert.AreEqual(10M<usd>, 5M<usd> * 2M)

Note: F# units of measure are erased at compile time meaning there’s no runtime performance penalty.

F# Money

For a report we’d probably want to encode money dynamically with a currency component. Below I’ve chosen an F# record type:

type Money = { Amount:decimal; Currency:string } with
   member this.Times(multiplier) = { this with Amount = this.Amount * multiplier }

let USD amount = { Amount=amount; Currency="USD" }

USD 10M = (USD 5M).Times(2M)

This succeeds immediately as F# implements equality (and GetHashCode) by default for us on record types.

Unquote

As an aside, I find assertions over numerical types are more natural using the Unquote library which lets you assert equality using the equals operator, i.e.

let [<Test>] ``5 USD * 2 = 10 USD`` () =
   test <@ (USD 5M).Times(2M) = USD 10M @>

Summary

When writing code we may seek quick feedback on our first implementations. In C# we’d typically write reflection based unit tests to get early feedback, in F# we may use F# interactive first for immediate feedback and later promote useful tests to reflection based tests that run as part of our continuous build and may help find regressions.

Also in this scenario implementing types in F# required a lot less boilerplate than the equivalent C# code.