Phillip Trelford's Array

POKE 36879,255

RadioHead

I’ve heard a few times that I have a great face for radio ;). Here’s 3 recordings from this year where I get my radio head on and talk about F#.

HanselminutesWhy F#? with Richard Minerich and Phillip Trelford

Interview with Scott Hanselman (March 2012)

 

InfoQ

Phil Trelford on Functional Architectures, F#

Interview with Werner Schuster (May 2012)

 

dotnetocksPhil Trelford Codes in F# 3.0

Interview with Carl Franklin & Richard Campbell (August 2012)

 

My next gig is Strangeloop later this month, hope to see you there:

strange_loop

F# for Trading (September 24th 2012)

GOTO Copenhagen 2012 Conference

This week I had the please of attending GOTO Copenhagen - a 3 day developer conference covering a diverse range of topics.

Day 1

I started the day on the excellent Beyond the Microsoft Echo Chamber track taking in:

kmm-74127_green_prince_of_wales_front_largeMark demonstrated his open source project AutoFixture aimed at writing maintainable unit tests faster. Tobias described how Credit Suisse have been using F# to migrate large computations over from Excel, and created a minimal implementation live on stage. Glenn, a trilby hat fan, gave a flavour of Node.js, showing pre-built code running on Windows, Azure and Cloud9; socket.io looked particularly interesting.

Then I switched over to the Lean and Kanban case studies track for Jesper Boeg’s talk about Launching Kanban teams, and received a free Kanban book a the end, thanks!

Monday’s keynote was from Kasper Lund on the Dart programming language which I’d sum up as a programming language that runs in Chrome with “an unsurprising and familiar syntax” for Java and JavaScript programmers.

Day 2

The day started with a functional orientated keynote from Rich Hickey, author of Clojure, on The Value of Values.

CH20-BLK, 12/9/99, 12:48 PM,  8C, 1018x648 (1124+1536),  25%, better push6,  1/15, R705, G520, B595,

I managed to catch the first 30 minutes of Simon Brown’s very interesting presentation Master-builder; the original generalising specialist? But had to nip out to do a video interview with fellow bowler hat wearer Werner Schuster on F# and FP which should be available on InfoQ in around a month or so.

 

After lunch I caught a great talk on dandelions Master-builders have rich conceptual models of software design from George Fairbanks.

Then it was my chance to talk about Functional Architecture:

Code samples:

Day 3

Another day, another Rich Hickey talk, this time on Writing Datomic in Clojure.

However most of my day was spent on the Programming with the Stars track which involved solving a minimal Minesweeper Kata in Java, functional Java, F# and C. Interestingly only the F# and C pairs were able to complete the task in the allotted hour.

I paired with Mark Seeman on the F# session. We were able to complete the computational version of the task with 15 minutes to spare, so even had time to start building a UI.

 1: let compute (board : string) =
 2:     let options = System.StringSplitOptions.RemoveEmptyEntries
 3:     let board = board.Split([| "\n" |], options)
 4:     let count (x, y) =      
 5:         [-1, -1; 0, -1;  1, -1;
 6:          -1,  0;         1,  0;
 7:          -1,  1; 0,  1;  1,  1]
 8:          |> List.map (fun (x', y') -> x + x', y + y')
 9:          |> List.filter (fun (x, y) -> 
10:             x >= 0 && x < board.[y].Length && 
11:             y >= 0 && y < board.Length
12:          )
13:          |> List.sumBy (fun (x, y) ->
14:             if board.[y].[x] = '*'
15:             then 1 else 0
16:          )
17:     board |> Array.mapi (fun y line ->
18:         line.ToCharArray() |> Array.mapi (fun x c ->
19:             match c with
20:             | '*' -> '*'
21:             | '.' -> '0' + char (count(x, y))
22:             | _ -> invalidArg "c" "Boo hiss!"
23:         )
24:     )
25:     |> Array.map (fun chars -> System.String(chars))
26:     |> Array.reduce (+)
27: 
28: let input = "*...
29: ....
30: .*..
31: ...."
val compute : string -> System.String

Full name: Snippet.compute
val board : string

  type: string
  implements: System.IComparable
  implements: System.ICloneable
  implements: System.IConvertible
  implements: System.IComparable<string>
  implements: seq<char>
  implements: System.Collections.IEnumerable
  implements: System.IEquatable<string>
Multiple items
val string : 'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------

type string = System.String

Full name: Microsoft.FSharp.Core.string

  type: string
  implements: System.IComparable
  implements: System.ICloneable
  implements: System.IConvertible
  implements: System.IComparable<string>
  implements: seq<char>
  implements: System.Collections.IEnumerable
  implements: System.IEquatable<string>
val options : System.StringSplitOptions

  type: System.StringSplitOptions
  inherits: System.Enum
  inherits: System.ValueType
namespace System
type StringSplitOptions =
  | None = 0
  | RemoveEmptyEntries = 1

Full name: System.StringSplitOptions

  type: System.StringSplitOptions
  inherits: System.Enum
  inherits: System.ValueType
field System.StringSplitOptions.RemoveEmptyEntries = 1
val board : string []

  type: string []
  implements: System.ICloneable
  implements: System.Collections.IList
  implements: System.Collections.ICollection
  implements: System.Collections.IStructuralComparable
  implements: System.Collections.IStructuralEquatable
  implements: System.Collections.Generic.IList<string>
  implements: System.Collections.Generic.ICollection<string>
  implements: seq<string>
  implements: System.Collections.IEnumerable
  inherits: System.Array
val count : (int * int -> int)
val x : int

  type: int
  implements: System.IComparable
  implements: System.IFormattable
  implements: System.IConvertible
  implements: System.IComparable<int>
  implements: System.IEquatable<int>
  inherits: System.ValueType
val y : int

  type: int
  implements: System.IComparable
  implements: System.IFormattable
  implements: System.IConvertible
  implements: System.IComparable<int>
  implements: System.IEquatable<int>
  inherits: System.ValueType
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------

type List<'T> =
  | ( [] )
  | ( :: ) of 'T * 'T list
  with
    interface System.Collections.IEnumerable
    interface System.Collections.Generic.IEnumerable<'T>
    member Head : 'T
    member IsEmpty : bool
    member Item : index:int -> 'T with get
    member Length : int
    member Tail : 'T list
    static member Cons : head:'T * tail:'T list -> 'T list
    static member Empty : 'T list
  end

Full name: Microsoft.FSharp.Collections.List<_>

  type: List<'T>
  implements: System.Collections.IStructuralEquatable
  implements: System.IComparable<List<'T>>
  implements: System.IComparable
  implements: System.Collections.IStructuralComparable
  implements: System.Collections.Generic.IEnumerable<'T>
  implements: System.Collections.IEnumerable
val map : ('T -> 'U) -> 'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val x' : int

  type: int
  implements: System.IComparable
  implements: System.IFormattable
  implements: System.IConvertible
  implements: System.IComparable<int>
  implements: System.IEquatable<int>
  inherits: System.ValueType
val y' : int

  type: int
  implements: System.IComparable
  implements: System.IFormattable
  implements: System.IConvertible
  implements: System.IComparable<int>
  implements: System.IEquatable<int>
  inherits: System.ValueType
val filter : ('T -> bool) -> 'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.filter
property System.Array.Length: int
val sumBy : ('T -> 'U) -> 'T list -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sumBy
module Array

from Microsoft.FSharp.Collections
val mapi : (int -> 'T -> 'U) -> 'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.mapi
val line : string

  type: string
  implements: System.IComparable
  implements: System.ICloneable
  implements: System.IConvertible
  implements: System.IComparable<string>
  implements: seq<char>
  implements: System.Collections.IEnumerable
  implements: System.IEquatable<string>
Multiple overloads
System.String.ToCharArray() : char []
System.String.ToCharArray(startIndex: int, length: int) : char []
val c : char

  type: char
  implements: System.IComparable
  implements: System.IConvertible
  implements: System.IComparable<char>
  implements: System.IEquatable<char>
  inherits: System.ValueType
Multiple items
val char : 'T -> char (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.char

--------------------

type char = System.Char

Full name: Microsoft.FSharp.Core.char

  type: char
  implements: System.IComparable
  implements: System.IConvertible
  implements: System.IComparable<char>
  implements: System.IEquatable<char>
  inherits: System.ValueType
val invalidArg : string -> string -> 'T

Full name: Microsoft.FSharp.Core.Operators.invalidArg
val map : ('T -> 'U) -> 'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
val chars : char []

  type: char []
  implements: System.ICloneable
  implements: System.Collections.IList
  implements: System.Collections.ICollection
  implements: System.Collections.IStructuralComparable
  implements: System.Collections.IStructuralEquatable
  implements: System.Collections.Generic.IList<char>
  implements: System.Collections.Generic.ICollection<char>
  implements: seq<char>
  implements: System.Collections.IEnumerable
  inherits: System.Array
type String =
  class
    new : char -> string
    new : char * int * int -> string
    new : System.SByte -> string
    new : System.SByte * int * int -> string
    new : System.SByte * int * int * System.Text.Encoding -> string
    new : char [] * int * int -> string
    new : char [] -> string
    new : char * int -> string
    member Chars : int -> char
    member Clone : unit -> obj
    member CompareTo : obj -> int
    member CompareTo : string -> int
    member Contains : string -> bool
    member CopyTo : int * char [] * int * int -> unit
    member EndsWith : string -> bool
    member EndsWith : string * System.StringComparison -> bool
    member EndsWith : string * bool * System.Globalization.CultureInfo -> bool
    member Equals : obj -> bool
    member Equals : string -> bool
    member Equals : string * System.StringComparison -> bool
    member GetEnumerator : unit -> System.CharEnumerator
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> System.TypeCode
    member IndexOf : char -> int
    member IndexOf : string -> int
    member IndexOf : char * int -> int
    member IndexOf : string * int -> int
    member IndexOf : string * System.StringComparison -> int
    member IndexOf : char * int * int -> int
    member IndexOf : string * int * int -> int
    member IndexOf : string * int * System.StringComparison -> int
    member IndexOf : string * int * int * System.StringComparison -> int
    member IndexOfAny : char [] -> int
    member IndexOfAny : char [] * int -> int
    member IndexOfAny : char [] * int * int -> int
    member Insert : int * string -> string
    member IsNormalized : unit -> bool
    member IsNormalized : System.Text.NormalizationForm -> bool
    member LastIndexOf : char -> int
    member LastIndexOf : string -> int
    member LastIndexOf : char * int -> int
    member LastIndexOf : string * int -> int
    member LastIndexOf : string * System.StringComparison -> int
    member LastIndexOf : char * int * int -> int
    member LastIndexOf : string * int * int -> int
    member LastIndexOf : string * int * System.StringComparison -> int
    member LastIndexOf : string * int * int * System.StringComparison -> int
    member LastIndexOfAny : char [] -> int
    member LastIndexOfAny : char [] * int -> int
    member LastIndexOfAny : char [] * int * int -> int
    member Length : int
    member Normalize : unit -> string
    member Normalize : System.Text.NormalizationForm -> string
    member PadLeft : int -> string
    member PadLeft : int * char -> string
    member PadRight : int -> string
    member PadRight : int * char -> string
    member Remove : int -> string
    member Remove : int * int -> string
    member Replace : char * char -> string
    member Replace : string * string -> string
    member Split : char [] -> string []
    member Split : char [] * int -> string []
    member Split : char [] * System.StringSplitOptions -> string []
    member Split : string [] * System.StringSplitOptions -> string []
    member Split : char [] * int * System.StringSplitOptions -> string []
    member Split : string [] * int * System.StringSplitOptions -> string []
    member StartsWith : string -> bool
    member StartsWith : string * System.StringComparison -> bool
    member StartsWith : string * bool * System.Globalization.CultureInfo -> bool
    member Substring : int -> string
    member Substring : int * int -> string
    member ToCharArray : unit -> char []
    member ToCharArray : int * int -> char []
    member ToLower : unit -> string
    member ToLower : System.Globalization.CultureInfo -> string
    member ToLowerInvariant : unit -> string
    member ToString : unit -> string
    member ToString : System.IFormatProvider -> string
    member ToUpper : unit -> string
    member ToUpper : System.Globalization.CultureInfo -> string
    member ToUpperInvariant : unit -> string
    member Trim : unit -> string
    member Trim : char [] -> string
    member TrimEnd : char [] -> string
    member TrimStart : char [] -> string
    static val Empty : string
    static member Compare : string * string -> int
    static member Compare : string * string * bool -> int
    static member Compare : string * string * System.StringComparison -> int
    static member Compare : string * string * System.Globalization.CultureInfo * System.Globalization.CompareOptions -> int
    static member Compare : string * string * bool * System.Globalization.CultureInfo -> int
    static member Compare : string * int * string * int * int -> int
    static member Compare : string * int * string * int * int * bool -> int
    static member Compare : string * int * string * int * int * System.StringComparison -> int
    static member Compare : string * int * string * int * int * bool * System.Globalization.CultureInfo -> int
    static member Compare : string * int * string * int * int * System.Globalization.CultureInfo * System.Globalization.CompareOptions -> int
    static member CompareOrdinal : string * string -> int
    static member CompareOrdinal : string * int * string * int * int -> int
    static member Concat : obj -> string
    static member Concat : obj [] -> string
    static member Concat<'T> : System.Collections.Generic.IEnumerable<'T> -> string
    static member Concat : System.Collections.Generic.IEnumerable<string> -> string
    static member Concat : string [] -> string
    static member Concat : obj * obj -> string
    static member Concat : string * string -> string
    static member Concat : obj * obj * obj -> string
    static member Concat : string * string * string -> string
    static member Concat : obj * obj * obj * obj -> string
    static member Concat : string * string * string * string -> string
    static member Copy : string -> string
    static member Equals : string * string -> bool
    static member Equals : string * string * System.StringComparison -> bool
    static member Format : string * obj -> string
    static member Format : string * obj [] -> string
    static member Format : string * obj * obj -> string
    static member Format : System.IFormatProvider * string * obj [] -> string
    static member Format : string * obj * obj * obj -> string
    static member Intern : string -> string
    static member IsInterned : string -> string
    static member IsNullOrEmpty : string -> bool
    static member IsNullOrWhiteSpace : string -> bool
    static member Join : string * string [] -> string
    static member Join : string * obj [] -> string
    static member Join<'T> : string * System.Collections.Generic.IEnumerable<'T> -> string
    static member Join : string * System.Collections.Generic.IEnumerable<string> -> string
    static member Join : string * string [] * int * int -> string
  end

Full name: System.String

  type: System.String
  implements: System.IComparable
  implements: System.ICloneable
  implements: System.IConvertible
  implements: System.IComparable<string>
  implements: seq<char>
  implements: System.Collections.IEnumerable
  implements: System.IEquatable<string>
val reduce : ('T -> 'T -> 'T) -> 'T [] -> 'T

Full name: Microsoft.FSharp.Collections.Array.reduce
val input : string

Full name: Snippet.input

  type: string
  implements: System.IComparable
  implements: System.ICloneable
  implements: System.IConvertible
  implements: System.IComparable<string>
  implements: seq<char>
  implements: System.Collections.IEnumerable
  implements: System.IEquatable<string>

No surprises then that according to the ICFP:

F# is the programming language of choice for discriminating hackers

untitled

For the C session I paired with John Nolan. Again we were able to complete the computational task, this time with only 30 seconds to spare, and it certainly wasn’t pretty, but still a lot of fun!

Since the conference I’ve knocked up an Erlang version: http://pastebin.com/s9mChuPp

 

Plus another F# version that fits nicely in a Tweet (140 characters): http://fssnip.net/ce

s|>Array2D.mapi(fun x y->function '*'->'*'|_->'0'+char([for i in 0..8->i%3-1,i/3-1].Count(fun(x,y)->x>=0&&x=0&&y<m&&s.[x,y]='*')))

MinesweeperInTryFSharp

End of day 3

The last talk of the day for me was Nat Pryce’s excellent Stop Refactoring! talk on the Iconoclasts track:

An iconoclast is someone who performs iconoclasm — destruction of religious symbols, or, by extension, established dogma or conventions.

Nat retold his observations of refactoring ping-pong:

Refactor one way, then another. then back again

The main message was that “code doesn’t need to be perfect only habitable” and::

The imperfection of our code is really motion blur, as the state of the code is simply a snapshot as it evolves

Day after

I really enjoyed the conference, saw some inspiring talks, and met some really interesting people, and would recommend Goto Copenhagen to anyone interested in software development. Read more about the conference and more specifically Concurrent Programming using the Disruptor over on Trisha’s blog.

Finally it appears to me that people are not wearing enough hats.

Performance-Driven Development

The growth of Agile and associated techniques like TDD and BDD has put a significant focus on delivering functional requirements via stories and automated tests. This is in part a side effect of the productivity of teams often being measured in terms of story points, bug counts and test coverage.

Unfortunately this can leave non-functional requirements like performance as secondary concerns. Clearly premature optimization is the root of all evil (actually I find micro-optimization a better euphemism); that said ignoring your non-functional requirements isn’t going to make them go away. As Simon Brown puts it in his Frustrated Architect article:

“Non-functional requirements" not sounding cool isn't a reason to neglect them.

Q: How can we make this palatable to “Agile” teams?

A: Provide a simple methodology for making a system’s key performance indicators (KPIs)  visible and give it a shiny new “x-driven development” name to make it sound vaguely hip.

The article Stuff that works – Performance Driven Development outlines the key points:

  • PDD is a common sense iterative development approach
  • Developers have to create Key performance Indicator dashboards. (KPIs)
  • These KPIs are created and updated continually throughout development. Not as an afterthought.
  • These KPI dashboards are always available in real-time

Borders

Max Headroom

Back in the 80s and 90s CRT screens were prevalent running at 50Hz or 60Hz. Action video games would typically attempt to update at a constant rate. Game developers would change the border colour of the CRT to visually measure how much time different parts of a program used. This gave immediate feedback on the performance impact of changes to the code. Unfortunately LCDs don’t have borders.

Similar psychedelic effects can be achieved in Silverlight using the EnableRedrawRegions property and the frame rate monitored with the EnableFrameRateCounter property.

Counters

Performance can be equally important for server side components. Predetermined performance data can published as counters and viewed in tools like Perfmon.

For some components I’ve implemented a simple Telnet server as a way to query a running component with specific parameters.

Another slightly more accessible option is to expose KPIs via a lightweight web framework like Nancy or Sinatra, and so make them easily visible on a web page.

Conclusion

Identifying key performance indicators for your system and having them visible early on in the project should help make it more likely that to your application’s performance is in sync with requirements. The good news is that there are plenty of fairly lightweight mechanisms to make this feasible. Now go read: