FSharp in the enterprise

Post on 06-May-2015

2422 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

FSharp talk at Developer South Coast meetup July 2013

Transcript

F# IN THE ENTERPRISE

Phillip Trelford@ptrelfordDeveloper South Coast2013

F#UNCTIONAL LONDONERS

570 Members

Founded 2010

Meets every 2 weeks

JOULE TRADING SCREEN

TESTIMONIALS F# in the Enterprise

F# FOR PROFIT

Time to Market

Efficiency

Correctness

Complexity

* applied to Analytic components

TIME TO MARKET

speed development by 50 percent or more,

European IB

order of magnitude increase in productivity,

GameSys

EFFICIENCY

processes that used to require hours now take just minutes, Grange Insurance

performance is 10× better than the C++ that it replaces, Aviva

CORRECTNESS

leads to virtually bug-free code,

Fixed Income

I am still waiting for the first bug to come in,

E-On

COMPLEXITY

everything becomes simple and clear when expressed in F#, Byron Cook

C# & F# BEST FRIENDS FOREVER Kaggle Testimonial

The fact that F# targets the CLR was also critical - even though we have a large existing code base in C#, getting started with F# was an easy decision because we knew we could use new modules right away.

TEST & INTEGRATION F# in the Enterprise

DEFECT RATE

I am both a C# dev and an F# dev. I can only offer subjective anecdotal evidence based on my experience of delivering projects in both languages (I am too busy delivering software to do anything else).

That said, the one stat in the summary that I find most compelling is the defect rate. I have now delivered three business critical projects written in F#. I am still waiting for the first bug to come in.

Simon Cousins, Power Company

DEPENDENCY INJECTION

F#

type VerySimpleStockTraderImpl

(analysisService:IStockAnalysisService,

brokerageService:IOnlineBrokerageService) =

interface IAutomatedStockTrader with

member this.ExecuteTrades() =

() // ...

C#

public class VerySimpleStockTraderImpl : IAutomatedStockTrader{ private readonly IStockAnalysisService analysisService; private readonly IOnlineBrokerageService brokerageService;

public VerySimpleStockTraderImpl( IStockAnalysisService analysisService, IOnlineBrokerageService brokerageService) { this.analysisService = analysisService; this.brokerageService = brokerageService; }

public void ExecuteTrades() { // ... }}

NUNIT

F# NUnit

module MathTest

open NUnit.Framework

let [<Test>] ``2 + 2 should equal 4``() = Assert.AreEqual(2 + 2, 4)

C# NUnit

using NUnit.Framework;

[TestFixture]public class MathTest{ [Test] public void TwoPlusTwoShouldEqualFour() { Assert.AreEqual(2 + 2, 4); }}

FSUNIT

[<Test>]let ``2 + 2 should equal 4``() = 2 + 2 |> should equal 4

UNQUOTE

let [<Test>] ``2 + 2 = 4``() = test <@ 2 + 2 = 4 @>

FSCHECK

.NET MOCKING LIBRARY

type ITime = abstract GetHour : unit -> int

type ImageCalculator (time:ITime) = member this.GetImageForTimeOfDay() = let hour = time.GetHour() if hour > 6 && hour < 21 then "sun.jpg" else "moon.jpg"

let [<Test>] `` at 01:00 the moon image should show `` () = let time = Mock().Setup(fun (x:ITime) -> x.GetHour()).Returns(1) let calculator = ImageCalculator(time.Create()) let image = calculator.GetImageForTimeOfDay() Assert.AreEqual("moon.jpg", image)

F# OBJECT EXPRESSION

type ITime = abstract GetHour : unit -> int

type ImageCalculator (time:ITime) = member this.GetImageForTimeOfDay() = let hour = time.GetHour() if hour > 6 && hour < 21 then "sun.jpg" else "moon.jpg“

let [<Test>] ``at 01:00 the moon image should show`` () = let time = { new ITime with member mock.GetHour() = 01 } let calculator = ImageCalculator(time) let image = calculator.GetImageForTimeOfDay() Assert.AreEqual("moon.jpg", image)

HIGHER-ORDER FUNCTION

let imageCalculator getHour = fun () -> let hour = getHour() if hour > 6 && hour < 21 then "sun.jpg" else "moon.jpg"

let [<Test>] ``at 01:00 the moon image should show`` () = let getHour () = 01 let getImageForHourOfDay = imageCalculator getHour let image = getImageForHourOfDay () Assert.AreEqual("moon.jpg", image)

MOCKING

F# Foq

let ``order sends mail if unfilled``() = // setup data let order = Order("TALISKER", 51) let mailer = mock() order.SetMailer(mailer) // exercise order.Fill(mock()) // verify verify <@ mailer.Send(any()) @> once

C# Moq

public void OrderSendsMailIfUnfilled(){ // setup data var order = new Order("TALISKER", 51); var mailer = new Mock<MailService>(); order.SetMailer(mailer.Object); // exercise order.Fill(Mock.Of<Warehouse>()); // verify mailer.Verify(mock => mock.Send(It.IsAny<string>()), Times.Once());}

CONTINUOUS BUILD

DSLS F# in the Enterprise

TICKSPEC

TICKSPEC OXO EXAMPLE

CELLZtype formula =

| Neg of formula

| Exp of formula * formula

| ArithmeticOp of

formula * arithmetic * formula

| LogicalOp of

formula * logical * formula

| Num of UnitValue

| Ref of int * int

| Range of int * int * int * int

| Fun of string * formula list

F# PROJECTS F# in the Enterprise

FILE ORDERING

MUTUAL RECURSION

type Folder(path:string) =

let files = Directory.GetFiles(path)

member folder.Files =

[|for file in files -> File(file,folder)|]

and File(filename: string, folder: Folder) =

member file.Name = filename

member file.Folder = folder

CYCLES

TickSpec (F#) SpecFlow (C#)

C#/F# INTEROP F# in the Enterprise

C#/F# INTEROP

Mostly it just works

Minor friction points

Equality

Explicit interfaces

Tuples & Union Types

Nulls

Tip: Read the F# Component Design Guidelines

EQUALITY: POP QUIZ

C# F#

var a =

new Order(Side.Bid, 99.9M, 5);

var b =

new Order(Side.Bid, 99.9M, 5);

return a == b;

let a = Order(Bid, 99.9M, 5)

let b = Order(Bid, 99.9M, 5)

a = b

F# REFERENCE EQUALITY

let (==) a b = obj.ReferenceEquals(a,b)

C# ==

public static bool operator == (Order a, Order b)

{

return a.Equals(b);

}

public static bool operator != (Person a, Person b)

{

return !a.Equals(b);

}

F# -> C# ==

static member op_Equality (a:Order,b:Order) =

a = b

static member op_Inequality (a:Order,b:Order) =

a <> b

OPERATORS F# in the Enterprise

OPERATORS

Brackets

List.reduce (+)

(List.map abs

[-9..+9])

Pipes

[-9..+9]

|> List.map abs

|> List.reduce (+)

SCALA: PIMP MY LIBRARY

F# GUIDELINES

http://fsharp.org/about/files/guidelines.pdf

CONCURRENCY F# in the Enterprise

IMMUTABILITY BY DEFAULT

Types

Tuples

Records

Discriminated Unions

Data structures

List

Map

Set

ASYNC WORKFLOWS

async {

do! control.MouseLeftButtonDown // First class events

|> Async.AwaitEvent

}

TYPE PROVIDERS F# in the Enterprise

TYPE PROVIDERS

WEB

B-MOVIE MADNESS

FUNSCRIPT

TRY F#: HTTP://TRYFSHARP.ORG

LEARN ME AN F# FOR GREAT GOOD

F# in the Enterprise

LEARNING F#

Hands on:

F# Koans

Katas/Project Euler

Reading:

F# for Fun and Profit

Podcasts:

.Net Rocks

F# BOOKS

SHOW ME THE MONEY!

QUESTIONS?

Twitter:

@ptrelford

Blog: http://trelford.com/blog

Foundation: http://fsharp.org

top related