Download - FSharp in the enterprise
![Page 1: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/1.jpg)
F# IN THE ENTERPRISE
Phillip Trelford@ptrelfordDeveloper South Coast2013
![Page 2: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/2.jpg)
F#UNCTIONAL LONDONERS
570 Members
Founded 2010
Meets every 2 weeks
![Page 3: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/3.jpg)
JOULE TRADING SCREEN
![Page 4: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/4.jpg)
TESTIMONIALS F# in the Enterprise
![Page 5: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/5.jpg)
F# FOR PROFIT
Time to Market
Efficiency
Correctness
Complexity
* applied to Analytic components
![Page 6: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/6.jpg)
TIME TO MARKET
speed development by 50 percent or more,
European IB
order of magnitude increase in productivity,
GameSys
![Page 7: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/7.jpg)
EFFICIENCY
processes that used to require hours now take just minutes, Grange Insurance
performance is 10× better than the C++ that it replaces, Aviva
![Page 8: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/8.jpg)
CORRECTNESS
leads to virtually bug-free code,
Fixed Income
I am still waiting for the first bug to come in,
E-On
![Page 9: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/9.jpg)
COMPLEXITY
everything becomes simple and clear when expressed in F#, Byron Cook
![Page 10: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/10.jpg)
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.
![Page 11: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/11.jpg)
TEST & INTEGRATION F# in the Enterprise
![Page 12: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/12.jpg)
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
![Page 13: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/13.jpg)
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() { // ... }}
![Page 14: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/14.jpg)
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); }}
![Page 15: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/15.jpg)
FSUNIT
[<Test>]let ``2 + 2 should equal 4``() = 2 + 2 |> should equal 4
![Page 16: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/16.jpg)
UNQUOTE
let [<Test>] ``2 + 2 = 4``() = test <@ 2 + 2 = 4 @>
![Page 17: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/17.jpg)
FSCHECK
![Page 18: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/18.jpg)
.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)
![Page 19: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/19.jpg)
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)
![Page 20: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/20.jpg)
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)
![Page 21: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/21.jpg)
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());}
![Page 22: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/22.jpg)
CONTINUOUS BUILD
![Page 23: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/23.jpg)
DSLS F# in the Enterprise
![Page 24: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/24.jpg)
TICKSPEC
![Page 25: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/25.jpg)
TICKSPEC OXO EXAMPLE
![Page 26: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/26.jpg)
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
![Page 27: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/27.jpg)
F# PROJECTS F# in the Enterprise
![Page 28: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/28.jpg)
FILE ORDERING
![Page 29: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/29.jpg)
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
![Page 30: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/30.jpg)
CYCLES
TickSpec (F#) SpecFlow (C#)
![Page 31: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/31.jpg)
C#/F# INTEROP F# in the Enterprise
![Page 32: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/32.jpg)
C#/F# INTEROP
Mostly it just works
Minor friction points
Equality
Explicit interfaces
Tuples & Union Types
Nulls
Tip: Read the F# Component Design Guidelines
![Page 33: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/33.jpg)
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
![Page 34: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/34.jpg)
F# REFERENCE EQUALITY
let (==) a b = obj.ReferenceEquals(a,b)
![Page 35: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/35.jpg)
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);
}
![Page 36: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/36.jpg)
F# -> C# ==
static member op_Equality (a:Order,b:Order) =
a = b
static member op_Inequality (a:Order,b:Order) =
a <> b
![Page 37: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/37.jpg)
OPERATORS F# in the Enterprise
![Page 38: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/38.jpg)
OPERATORS
Brackets
List.reduce (+)
(List.map abs
[-9..+9])
Pipes
[-9..+9]
|> List.map abs
|> List.reduce (+)
![Page 39: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/39.jpg)
SCALA: PIMP MY LIBRARY
![Page 40: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/40.jpg)
F# GUIDELINES
http://fsharp.org/about/files/guidelines.pdf
![Page 41: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/41.jpg)
CONCURRENCY F# in the Enterprise
![Page 42: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/42.jpg)
IMMUTABILITY BY DEFAULT
Types
Tuples
Records
Discriminated Unions
Data structures
List
Map
Set
![Page 43: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/43.jpg)
ASYNC WORKFLOWS
async {
do! control.MouseLeftButtonDown // First class events
|> Async.AwaitEvent
}
![Page 44: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/44.jpg)
TYPE PROVIDERS F# in the Enterprise
![Page 45: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/45.jpg)
TYPE PROVIDERS
![Page 46: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/46.jpg)
![Page 47: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/47.jpg)
WEB
![Page 48: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/48.jpg)
B-MOVIE MADNESS
![Page 49: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/49.jpg)
FUNSCRIPT
![Page 50: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/50.jpg)
TRY F#: HTTP://TRYFSHARP.ORG
![Page 51: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/51.jpg)
LEARN ME AN F# FOR GREAT GOOD
F# in the Enterprise
![Page 52: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/52.jpg)
LEARNING F#
Hands on:
F# Koans
Katas/Project Euler
Reading:
F# for Fun and Profit
Podcasts:
.Net Rocks
![Page 53: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/53.jpg)
F# BOOKS
![Page 54: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/54.jpg)
SHOW ME THE MONEY!
![Page 55: FSharp in the enterprise](https://reader031.vdocuments.mx/reader031/viewer/2022013100/55491123b4c9056b458be5af/html5/thumbnails/55.jpg)
QUESTIONS?
Twitter:
@ptrelford
Blog: http://trelford.com/blog
Foundation: http://fsharp.org