Real World F# - SDD 2015

Preview:

Citation preview

REAL-WORLD F# Phil TrelfordSDD, 2015

F# TAGLINE

F# is a practical, functional-first language

that lets you write simple code to solve complex problems

CASE STUDY Phil Trelford, @ptrelford#SDDConf, 2015

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

E-On

ANALYSIS OF 2 SIMILAR APPSC#

8 developers peak

5 years

Requirements not met

F#

2 developers peak

< 1 year

Requirements met

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

CODE PATHOGENS

Logging Exception handling

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?

LIVE DEMOS Phil Trelford, @ptrelford#SDDConf, 2015

THOUGHTWORKS TECH RADAR 2012F#

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

Languages

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

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

UNITS OF MEASURE

SQL TYPE PROVIDER

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

FUNCTIONAL C# Phil Trelford, @ptrelford#SDDConf, 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; }}

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); }}

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

INTEGRATING F# Phillip TrelfordSDD, 2015

F# COMPONENT DESIGN GUIDELINES

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

Classes

Interfaces

Modules

Records

Tuples(*)

F# specific

Discriminated unions

Function arguments

Curried arguments

Option

Async

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>

RESOURCES Phillip TrelfordSDD, 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

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 __

TRY IT BEFORE YOU BUY IT

BUY THE BOOK

QUESTIONS?

Twitter @ptrelford

Blog http://trelford.com/blog

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