30
REAL-WORLD F# Phil Trelford SDD, 2015

Real World F# - SDD 2015

Embed Size (px)

Citation preview

Page 1: Real World F# -  SDD 2015

REAL-WORLD F# Phil TrelfordSDD, 2015

Page 2: Real World F# -  SDD 2015

F# TAGLINE

F# is a practical, functional-first language

that lets you write simple code to solve complex problems

Page 3: Real World F# -  SDD 2015

CASE STUDY Phil Trelford, @ptrelford#SDDConf, 2015

Page 4: Real World F# -  SDD 2015

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

E-On

Page 5: Real World F# -  SDD 2015

ANALYSIS OF 2 SIMILAR APPSC#

8 developers peak

5 years

Requirements not met

F#

2 developers peak

< 1 year

Requirements met

Page 6: Real World F# -  SDD 2015

LINES OF CODE

Implementation

C# F#

Braces 56,929 643

Blanks 29,080 3,630

Null Checks 3,011 15

Comments 53,270 487

Useful Code 163,276 16,667

App Code 305,566 21,442

Test Code 42,864 9,359

Total Code 348,430 30,801

Page 7: Real World F# -  SDD 2015

CODE PATHOGENS

Logging Exception handling

Page 8: Real World F# -  SDD 2015

SUMMARY

I can fit the whole F# solution in the blank lines of the C# solution

with 7,000 lines to spare.

WTF C#! OMG F#!

I have spent most of my life writing buggy, bloated software that was impossible to reason about. What was I thinking?

Page 9: Real World F# -  SDD 2015

LIVE DEMOS Phil Trelford, @ptrelford#SDDConf, 2015

Page 10: Real World F# -  SDD 2015

THOUGHTWORKS TECH RADAR 2012F#

“F# is excellent at concisely expressing business and domain logic.”

Languages

Page 11: Real World F# -  SDD 2015

CURRENCY CONVERSIONS

[<Measure>] type EUR[<Measure>] type GBPlet rateEurGbp = 0.783M<GBP/EUR>

// Converts amount in EUR to GBPlet euroToPounds (eur:decimal<EUR>) = eur * rateEurGbp

Page 12: Real World F# -  SDD 2015

UNITS IN CELLStype 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 13: Real World F# -  SDD 2015

UNITS OF MEASURE

Page 14: Real World F# -  SDD 2015

SQL TYPE PROVIDER

Page 15: Real World F# -  SDD 2015

AUTOMATING 2048 WITH CANOPYstart firefox

url "http://gabrielecirulli.github.io/2048/

press up

press left

press right

let score = element ".score-container"

printfn "Score %s" score.Text

Page 17: Real World F# -  SDD 2015

FUNCTIONAL C# Phil Trelford, @ptrelford#SDDConf, 2015

Page 18: Real World F# -  SDD 2015

FUNCTIONAL C# - MAP/REDUCEusing System;using System.Collections.Generic;

public class Enumerable{ public static IEnumerable<TResult> Map<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> func) { foreach(var item in source) { yield return func(item); } }

public static TAccumulate Reduce<TSource,TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate,TSource,TAccumulate> func) { var current = seed; foreach(var item in source) { current = func(current, item); } return current; }}

Page 19: Real World F# -  SDD 2015

HIGHER ORDER FUNCTIONS – C# MAPpublic static IEnumerable<TResult> Map<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> func){ foreach(var item in source) { yield return func(item); }}

Page 20: Real World F# -  SDD 2015

HIGHER ORDER FUNCTIONS – F# MAP/REDUCElet map func items =

for item in items do

func item

let reduce func seed items =

let mutable acc = seed

for item in items do

acc <- func acc

acc

Page 21: Real World F# -  SDD 2015

INTEGRATING F# Phillip TrelfordSDD, 2015

Page 22: Real World F# -  SDD 2015

F# COMPONENT DESIGN GUIDELINES

Page 23: Real World F# -  SDD 2015

C#/F# INTEROP (MOSTLY IT JUST WORKS)C# friendly

Classes

Interfaces

Modules

Records

Tuples(*)

F# specific

Discriminated unions

Function arguments

Curried arguments

Option

Async

Page 24: Real World F# -  SDD 2015

CONTINUOUS INTEGRATION

F# Project - FSharp.Core App.config – Binding Redirect

<?xml version="1.0" encoding="utf-8"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />

</startup> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<dependentAssembly> <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />

</dependentAssembly> </assemblyBinding> </runtime> </configuration>

Page 25: Real World F# -  SDD 2015

RESOURCES Phillip TrelfordSDD, 2015

Page 26: Real World F# -  SDD 2015

F# Software Foundation

http://www.fsharp.org

software stacks

trainings teaching F# user groups snippets

mac and linux cross-platform books and tutorials

F# community open-source MonoDevelop

contributions research support

consultancy mailing list

Page 27: Real World F# -  SDD 2015

F# KOANS

[<Koan>]let SquareEvenNumbersWithPipelineOperator() =(* In F#, you can use the pipeline operator to get the benefit of the parens style with the readability of the statement style. *)

let result = [0..5] |> List.filter isEven |> List.map square AssertEquality result __

Page 28: Real World F# -  SDD 2015

TRY IT BEFORE YOU BUY IT

Page 29: Real World F# -  SDD 2015

BUY THE BOOK

Page 30: Real World F# -  SDD 2015

QUESTIONS?

Twitter @ptrelford

Blog http://trelford.com/blog

F# eXchange: http://tinyurl.com/fsharpex