77
F# AS OUR DAY JOB BY 2016 Oslo/NDC Oslo Tomas Jansson 19/06/2015

F# as our day job by 2016

Embed Size (px)

Citation preview

F# AS OUR DAY JOB BY 2016

Oslo/NDC OsloTomas Jansson19/06/2015

THIS IS ME!

Tomas JanssonManager & Practice Lead .NETBEKK Oslo

@[email protected]/mastojslideshare.net/mastojblog.tomasjansson.com

http://www.eatsleepcoderepeat.de/beitraege_2013_10.htm

Sad & misundersto

od

C#95%

F#5%

Programming at work in 2015

I want to be the hero!

C#50%

F#50%

Programming at work in 2016

Why change?

Time

Awesomeness

TOMAS’ GRAPH OF AWESOMENESS

No change

Time

Awesomeness

TOMAS’ GRAPH OF AWESOMENESS

No change

Change

Time

Awesomeness

TOMAS’ GRAPH OF AWESOMENESS

No change

Change

You can’t improve without change!

Application

With plumbing

Application

Extra complexity

Application

Application

Extra complexity

Why do I like F#?

The facts!

What can you

do?

Why do I like F#?

#1: Good habits

#2: Separation

#2: Separation

"Objects are not data structures. Objects may use data structures; but the manner in which those data structures are used or contained is hidden. This is why data fields are private. From the outside looking in you cannot see any state. All you can see are functions. Therefore Objects are about functions not about state."

Uncle Bob - http://blog.cleancoder.com/uncle-bob/2014/11/24/FPvsOO.html

#2: Separation

"Objects are not data structures. Objects may use data structures; but the manner in which those data structures are used or contained is hidden. This is why data fields are private. From the outside looking in you cannot see any state. All you can see are functions. Therefore Objects are about functions not about state."

Uncle Bob - http://blog.cleancoder.com/uncle-bob/2014/11/24/FPvsOO.html

#3: Null handling

#3: Null handling

Null References: The Billion Dollar Mistake

- Sir Charles Antony Richard Hoare http://tinyurl.com/TheBillionDollarMistake

#3: Null handling

type Order = {OrderId: int; Total: int}

let getOrder orderId = match orderId with | 0 -> None | _ -> Some { OrderId = orderId Total = 23*orderId }

let printOrder order = match order with | Some o -> printfn "Order id: %i, Total: %i« o.OrderId o.Total | None -> printfn "No order"

#3: Null handling

type Order = {OrderId: int; Total: int}

let getOrder orderId = match orderId with | 0 -> None | _ -> Some { OrderId = orderId Total = 23*orderId }

let printOrder order = match order with | Some o -> printfn "Order id: %i, Total: %i« o.OrderId o.Total | None -> printfn "No order"

Returns Order option

#3: Null handling

type Order = {OrderId: int; Total: int}

let getOrder orderId = match orderId with | 0 -> None | _ -> Some { OrderId = orderId Total = 23*orderId }

let printOrder order = match order with | Some o -> printfn "Order id: %i, Total: %i« o.OrderId o.Total | None -> printfn "No order"

Returns Order option

Explicit null

handling!

#3: Null handling

public class Order{ public int OrderId { get; set; } public int Total { get; set; }}

public Order GetOrder(int orderId){ if (orderId == 0) return null; return new Order() { OrderId = orderId, Total = 23*orderId };}

public void PrintOrder(Order order){ Console.WriteLine("Order id: {0}, Total: {1}", order.OrderId, order.Total);}

#3: Null handling

public class Order{ public int OrderId { get; set; } public int Total { get; set; }}

public Order GetOrder(int orderId){ if (orderId == 0) return null; return new Order() { OrderId = orderId, Total = 23*orderId };}

public void PrintOrder(Order order){ Console.WriteLine("Order id: {0}, Total: {1}", order.OrderId, order.Total);}

How do I differ

success from

failure?

#3: Null handling

public class Order{ public int OrderId { get; set; } public int Total { get; set; }}

public Order GetOrder(int orderId){ if (orderId == 0) return null; return new Order() { OrderId = orderId, Total = 23*orderId };}

public void PrintOrder(Order order){ Console.WriteLine("Order id: {0}, Total: {1}", order.OrderId, order.Total);}

How do I differ

success from

failure?

What about null?

#4: Types

#4: Types

type Customer = { CustomerId: Guid FirstName: string LastName: string }

#4: Types

public class Customer { public Guid CustomerId { get; private set; } public string FirstName { get; private set; } public string LastName { get; private set; }

public Customer(Guid customerId, string firstName, string lastName) { CustomerId = customerId; FirstName = firstName; LastName = lastName; }

protected bool Equals(Customer other) { return CustomerId.Equals(other.CustomerId) && string.Equals(FirstName, other.FirstName) && string.Equals(LastName, other.LastName); }

public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((Customer) obj); }

public override int GetHashCode() { unchecked { var hashCode = CustomerId.GetHashCode(); hashCode = (hashCode*397) ^ (FirstName != null ? FirstName.GetHashCode() : 0); hashCode = (hashCode*397) ^ (LastName != null ? LastName.GetHashCode() : 0); return hashCode; } }}

#5: Type providers

Strongly typed «ORM»

SQL JSON XML WCF …

#5: Type providers

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

#6: Readability

// Version 1let executeCommand command = command |> validate |> log |> execute |> loglet result = executeCommand command

// Version 2let executeCommand = validate >> log >> execute >> loglet result = executeCommand command

#6: Readability

// Version 1public ExecutionResult ExecuteCommand(Command command){ return Log(Execute(Log(Validate(command))));}var result = ExecuteCommand(new Command());

// Version 2public ExecutionResult ExecuteCommand(Command command){ var validationResult = Validate(command); Log(validationResult); var executionResult = Execute(validationResult); Log(executionResult); return executionResult;}var result = ExecuteCommand(new Command());

The facts!

@simontcousins

@ScottWlaschin

http://tinyurl.com/CyclesInTheWild

http://tinyurl.com/DoesTheLanguageMakeADifference

Cycles

Compared 10 C# projects with 10 F# projects

Compared «top-level» types

Top-level type: “a type that is not nested and which is not compiler generated”

@ScottWlaschin

http://tinyurl.com/CyclesInTheWild

PROJECTS

Mono.Cecil, which inspects programs and libraries in the ECMA CIL format

NUnit

SignalR for real-time web functionality

NancyFx, a web framework

YamlDotNet, for parsing and emitting YAML

SpecFlow, a BDD tool

Json.NET

Entity Framework

ELMAH, a logging framework for ASP.NET

NuGet itself

Moq, a mocking framework

NDepend, a code analysis tool

FSharp.Core, the core F# library.

FSPowerPack.

FsUnit, extensions for NUnit.

Canopy, a wrapper around the Selenium test automation tool.

FsSql, a nice little ADO.NET wrapper.

WebSharper, the web framework.

TickSpec, a BDD tool.

FSharpx, an F# library.

FParsec, a parser library.

FsYaml, a YAML library built on FParsec.

Storm, a tool for testing web services.

Foq, a mocking framework.

C#

F#

SpecFlow

SpecFlow

I do think SpecFlow is great tool!

TickSpec

Does your language matter?

Application to assist in maintaining the stability and security of the electricity supply in the UK

Existing solution almost fully implemented in C#

Rewritten in F#

@simontcousins

http://tinyurl.com/DoesTheLanguageMakeADifference

“The C# project took five years and peaked at ~8 devs. It never fully implemented all of the contracts.

The F# project took less than a year and peaked at three devs (only one had prior experience with F#). All of the contracts were fully implemented.”

http://tinyurl.com/DoesTheLanguageMakeADifference

THE LANGUAGE YOU USE MAKE A DIFFERENCE

Encapsulated small types

Less top-level dependencies

Less «leaky» abstractions

Types and functions must be defined

Prevents cycles

Encapsulation

Much easier to do in F#

Linear

Generics

What can you

do?

Read

Code

http://www.peoplevine.com/page/peoplevine-for-startups

Start small, but think

big!

Demo?

RESOURCES

http://fsharpforfunandprofit.com/

http://tinyurl.com/DoesTheLanguageMakeADifference

http://www.meetup.com/OsloFSharp/ (if you live in Oslo)

http://fsharp.org/

Questions?

Thank you!

@TomasJansson

Vote!