type Person =
  {Name: string;
   Age: int;}

Full name: index.Person
Person.Name: string
Multiple items
val string : value:'T -> string

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

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
Person.Age: int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val name : string * string

Full name: index.name
val firstName : string

Full name: index.firstName
val secondName : string

Full name: index.secondName
val numbers : int list

Full name: index.numbers
type Direction =
  | North
  | South
  | East
  | West

Full name: index.Direction
union case Direction.North: Direction
union case Direction.South: Direction
union case Direction.East: Direction
union case Direction.West: Direction
type Weather

Full name: index.Weather
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Data
namespace Microsoft.FSharp.Data.UnitSystems
namespace Microsoft.FSharp.Data.UnitSystems.SI
namespace Microsoft.FSharp.Data.UnitSystems.SI.UnitNames
val measurements : (string * 'a) list (requires member ( * ) and member ( * ) and member ( * ))
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member GetSlice : startIndex:int option * endIndex:int option -> 'T list
  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

Full name: Microsoft.FSharp.Collections.List<_>
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sumBy
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
Multiple items
type MeasureAttribute =
  inherit Attribute
  new : unit -> MeasureAttribute

Full name: Microsoft.FSharp.Core.MeasureAttribute

--------------------
new : unit -> MeasureAttribute
val mbPerGb : float
val memoryInMyLaptop : float
val moreMemory : float
val memoryAsMb : float
val evenMoreMemory : float
val add : (int -> int -> int)
val a : int
val b : int
val addFive : (int -> int)
val twelve : int
val timesBy : (int -> int -> int)
Multiple items
val double : (int -> int)

--------------------
type double = System.Double

Full name: Microsoft.FSharp.Core.double
val ten : int

F#

The Pit of Success

Isaac Abraham

Who am I?

This talk...

  • will not teach you everything about F# :-(
  • will give you a flavour of the language and tooling :-)
  • will make you wish you had some of these features in your current language :-)
  • will involve about 15 minutes of presentation + talking :-(
  • ...then about 60-90 minutes of coding and demos :-)
  • ...QA throughout please!

As a junior dev...

alt

Aha!

alt

alt

alt

alt

The changing face of OO

  • Inheritance vs Composition
  • State vs Immutability
  • Identity vs Structural Equality

The changing face of hardware

  • CPU clock speed has reached a peak
  • Single machine computing no longer sufficient for data-intensive problems
  • Systems are becoming more complex

Isn't FP hard?

alt

alt

The .NET / CLR picture

alt

How functional is it?

alt

Three sides to every story...

C# and VB .NET

F#

Mutable by default

Immutable by default

Side-effects and statements

Expressions

Classes

Functions as values

Inheritance

Composition

State

Pure functions

Polymorphism

Abstract Data Types

The future of C#

In C# now

  • making immutability easier
  • better expression support

Coming to C#

  • Tuple support
  • Pattern matching
  • Union types?
  • Non nullable reference types?

Why F#?

  • solve complex problems with simple code
  • define your problem domain with compiler support rather than e.g. unit tests or runtime errors
  • type inference reduces bloat
  • make code easier to reason about

Testimonials

alt

Jet

E-Commerce

Credit Suisse

Investment Banking

Bayard Rock

Anti Money Laundering

Grange

Insurance

Bing

Search

Waagner Biro

Architecture

Code bases (1)

alt

Code bases (2)

alt alt

.NET, MS and Open Source

  • .NET is changing
  • Microsoft are moving to an open source model
  • Microsoft are committed to cross-platform
  • Azure is driving Microsoft strategy

Open Source in .NET

  • F# community is open, pro-active and self-managing
  • Not reliant on Microsoft for tooling etc.
  • Creating lots of open source projects
  • Already has a strong x-platform community
    • Linux + Mac community on Mono
    • Support for multiple code editors
  • C# and VB communities need to follow suit

A Simple DTO

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
class Person {
    private readonly string name;
    private readonly int age;
    public string Name { get { return name; } }
    public string Age { get { return age; } }
    public Person(string name, int age) {
        this.name = name;
        this.age = age;
    }
}

and the same in F# (with structural equality)

1: 
type Person = { Name : string; Age : int }

Common types

1: 
2: 
3: 
4: 
var name = Tuple.Create("isaac", "abraham")
var firstName = name.Item1
var secondName = name.Item2
var numbers = new List<int>(new [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })

and the same in F#

1: 
2: 
3: 
let name = "isaac", "abraham"
let firstName, secondName = name
let numbers = [ 1 .. 10 ]

Domain Modelling

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
type Direction = | North | South | East | West
type Weather =
    | Sunny
    | Raining of rainfall : int<cm/hour>
    | Snowing of snowfall : int<cm/hour>
    | Windy of windspeed : <km/hour> * Direction

// C# equivalent would be a class hierarchy with Weather as base

Pattern Matching

1: 
2: 
3: 
4: 
5: 
6: 
7: 
match weather with
| Sunny -> "It's sunny today!"
| Raining _ -> "Raining!"
| Snowing _ -> "Snowing!"
| Windy (_, South) -> "Southernly wind"
| Windy (speed, _) when speed > 10<km/hour> -> "Really windy!"
| Windy _ -> "A nice breeze" 

Units of Measure

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames

let measurements =
    [   "Lounge", (7.47<meter> * 3.51<meter>)
        "Bedroom 1", (4.11<meter> * 2.74<meter>)
        "Bedroom 2", (4.19<meter> * 2.06<meter>) ]

measurements
|> List.sumBy snd

// val it : float<meter ^ 2> = 46.1125

Custom Units of Measure

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
[<Measure>] type gb
[<Measure>] type mb

let mbPerGb = 1024.<mb/gb>

let memoryInMyLaptop = 16.<gb>

let moreMemory = memoryInMyLaptop + 2. // compiler error
let moreMemory = memoryInMyLaptop + 2.<gb> // 18.<gb>

let memoryAsMb = memoryInMyLaptop * mbPerGb // 16384.0<mb>

let evenMoreMemory = memoryAsMb + 1.<gb> // compiler error

Partial Functions

  • Allows us to compose functions easily
  • Fill in just "some" of the arguments to a function
1: 
2: 
3: 
4: 
5: 
6: 
7: 
let add a b = a + b // add two numbers together
let addFive = add 5 // just supply the first argument to the "add" function
let twelve = addFive 7 // same as 'add 5 7'

let timesBy a b = a * b // times two numbers together
let double = timesBy 2 // times 2 and something else together
let ten = double 5

F# on the Cloud

Think about writing software on...

  • on a single thread?
  • on multiple threads?
  • on multiple machines?
  • foreach loops don't parallelise in many cases
  • Are locks really the answer?
  • Mutability introduces lots of cases to deal with
  • Distributed queues + messaging systems fit well with FP

Also...

  • Native support for asynchronous code (C# async is cut down)
  • In-process Agents / actors
  • Support for non-nullability baked into the language

.NET distributed compute framework

How do we get started?

  • You can start small
  • Write F# projects alongside C# / VB .NET projects
    • "Pure" functions - business logic helpers etc.
    • Data access layers & domain models
    • Ringfenced areas of code
  • Interop with non-CLR languages via Type Providers e.g. R

Find out and learn more...