Slide 1

Slide 1 text

Manuel M T Chakravarty University of New South Wales Adopting Functional Programming mchakravarty TacticalGrace justtesting.org 1 45 minute time slot [15+min Intro & What is FP?; 15-min Love Types; 15-min Minimise State]

Slide 2

Slide 2 text

2 My FP background: * Co-founder of the Programming Languages & Systems research group at UNSW * Internationally renowned research group: Haskell standardisation & type system; parallel programming * Program Chair of ICFP 2014

Slide 3

Slide 3 text

GPUs multicore CPUs 3 * Current work focuses on array programming for high-performance architectures, such as GPUs and multicores.

Slide 4

Slide 4 text

BIGPIXEL 4 My Cocoa background: * BigPixel — pixel art and sprite editor for iPad * New mixed-language Mac app » Let’s talk about Swift…

Slide 5

Slide 5 text

BIGPIXEL 4 My Cocoa background: * BigPixel — pixel art and sprite editor for iPad * New mixed-language Mac app » Let’s talk about Swift…

Slide 6

Slide 6 text

Swift Objective-C without the C 5 * Craig Federighi (apparently): Objective-C without the C * But Chris Lattner corrected that on the DevForums: ObjC + FP

Slide 7

Slide 7 text

Swift Objective-C with functional programming 5 * Craig Federighi (apparently): Objective-C without the C * But Chris Lattner corrected that on the DevForums: ObjC + FP

Slide 8

Slide 8 text

“What is functional programming?” 6 » What is functional programming? [Audience opinions…]

Slide 9

Slide 9 text

Types systems Types inference Generics Pattern matching REPL Higher-order functions Immutable structures Garbage collection Closures Purity Well-defined semantics Meta programming Equational reasoning List comprehensions Lambda calculus Monads etc. 7 * Collection of technologies * Usually draw inspiration from mathematics * Aimed at improving program composition * Modern Objective-C already adopts some of these technologies * Swift adopts many more

Slide 10

Slide 10 text

Types systems Types inference Generics Pattern matching REPL Higher-order functions Closures Garbage collection Immutable structures Purity Well-defined semantics Meta programming Equational reasoning List comprehensions Lambda calculus Monads etc. 7 * Collection of technologies * Usually draw inspiration from mathematics * Aimed at improving program composition * Modern Objective-C already adopts some of these technologies * Swift adopts many more

Slide 11

Slide 11 text

Types inference Types systems Higher-order functions Generics REPL Pattern matching Closures Garbage collection Immutable structures Purity Well-defined semantics Meta programming Equational reasoning List comprehensions Lambda calculus Monads etc. 7 * Collection of technologies * Usually draw inspiration from mathematics * Aimed at improving program composition * Modern Objective-C already adopts some of these technologies * Swift adopts many more

Slide 12

Slide 12 text

? 8 * It’s great to have a new language with lots of new, exciting features, but… * …it also leads to many questions. * When should you start looking into it? How to use new features? * What is the right way to use it? Where to use it? Where to find the time? * Consider this: How much Swift in WWDC 2014 videos? What about 2015?

Slide 13

Slide 13 text

? When? How? What? Where? 8 * It’s great to have a new language with lots of new, exciting features, but… * …it also leads to many questions. * When should you start looking into it? How to use new features? * What is the right way to use it? Where to use it? Where to find the time? * Consider this: How much Swift in WWDC 2014 videos? What about 2015?

Slide 14

Slide 14 text

? When? How? What? Where? WWDC 2015 8 * It’s great to have a new language with lots of new, exciting features, but… * …it also leads to many questions. * When should you start looking into it? How to use new features? * What is the right way to use it? Where to use it? Where to find the time? * Consider this: How much Swift in WWDC 2014 videos? What about 2015?

Slide 15

Slide 15 text

“Should I learn functional programming?” 9 * The one overarching question…and its follow up… » Let’s consult history…

Slide 16

Slide 16 text

“Should I learn functional programming?” “Can you afford not to?” 9 * The one overarching question…and its follow up… » Let’s consult history…

Slide 17

Slide 17 text

A little history 10 * First came generics (Martin Odersky, Phil Wadler et al.) — based on Standard ML’s parametric polymorphism [Phil was one of the main people on the original Haskell Committee] * Then the rest (Martin Odersky et al.)

Slide 18

Slide 18 text

A little history Generics 10 * First came generics (Martin Odersky, Phil Wadler et al.) — based on Standard ML’s parametric polymorphism [Phil was one of the main people on the original Haskell Committee] * Then the rest (Martin Odersky et al.)

Slide 19

Slide 19 text

A little history Closures Types inference Types systems Higher-order functions Generics Pattern matching List comprehensions Monads etc. 10 * First came generics (Martin Odersky, Phil Wadler et al.) — based on Standard ML’s parametric polymorphism [Phil was one of the main people on the original Haskell Committee] * Then the rest (Martin Odersky et al.)

Slide 20

Slide 20 text

A little history Closures Types inference Types systems Higher-order functions Generics Pattern matching List comprehensions Monads etc. 11 * Then the rest (Martin Odersky et al.) * Similar situation as with Swift

Slide 21

Slide 21 text

A little history 11 * Then the rest (Martin Odersky et al.) * Similar situation as with Swift

Slide 22

Slide 22 text

12 * Java is still big, but… * …often the interesting projects are in Scala * See companies like Twitter, Atlassian, CBA * Big difference: Swift is from same company as the language it succeeds * So, I reckon Swift will replace Objective-C much more quickly

Slide 23

Slide 23 text

12 * Java is still big, but… * …often the interesting projects are in Scala * See companies like Twitter, Atlassian, CBA * Big difference: Swift is from same company as the language it succeeds * So, I reckon Swift will replace Objective-C much more quickly

Slide 24

Slide 24 text

scalaz Argonaut ScalaCheck shapeless Monocle scodec 13 * How Scala is used: fancy Java or adopting FP * The questions is, do you want to be part of the conversation? » It seems like a good idea to look more closely at FP

Slide 25

Slide 25 text

“What is the practical benefit of functional programming?” 14 * There are many success stories (Ericsson, Twitter, Facebook, WhatsApp, and so on) * But we want something more concrete…

Slide 26

Slide 26 text

Less testing! 15 * They tell you, more tests are better. That’s actually nonsense. Less tests are better.

Slide 27

Slide 27 text

16 * Common coder wisdom: everything else being equal, it is better to have less code.

Slide 28

Slide 28 text

Example code courtesy NSHipster (CC BY-NC 4.0): http://nshipster.com/xctestcase/ 17 * Tests are code (you have to write them, you have to debug them, you have to maintain them, you have to run them)

Slide 29

Slide 29 text

“What if you could gain the same confidence in correctness with less or simpler tests?” 18 * You would spend less time writing, maintaining, and running tests.

Slide 30

Slide 30 text

Possible states of your application 19 * Error states = if you reach such a state, your application will misbehave * Tested states = error states shown to be unreachable & valid states shown to be reachable * Functional programming aims to statically reduce the possible states » How do we get rid of unnecessary states?

Slide 31

Slide 31 text

Possible states of your application Error states 19 * Error states = if you reach such a state, your application will misbehave * Tested states = error states shown to be unreachable & valid states shown to be reachable * Functional programming aims to statically reduce the possible states » How do we get rid of unnecessary states?

Slide 32

Slide 32 text

Possible states of your application Error states Tested states 19 * Error states = if you reach such a state, your application will misbehave * Tested states = error states shown to be unreachable & valid states shown to be reachable * Functional programming aims to statically reduce the possible states » How do we get rid of unnecessary states?

Slide 33

Slide 33 text

Possible states of your application Error states Tested states 19 * Error states = if you reach such a state, your application will misbehave * Tested states = error states shown to be unreachable & valid states shown to be reachable * Functional programming aims to statically reduce the possible states » How do we get rid of unnecessary states?

Slide 34

Slide 34 text

Possible states of your application Error states Tested states eliminate bugs 19 * Error states = if you reach such a state, your application will misbehave * Tested states = error states shown to be unreachable & valid states shown to be reachable * Functional programming aims to statically reduce the possible states » How do we get rid of unnecessary states?

Slide 35

Slide 35 text

Possible states of your application Error states Tested states eliminate bugs eliminate tests 19 * Error states = if you reach such a state, your application will misbehave * Tested states = error states shown to be unreachable & valid states shown to be reachable * Functional programming aims to statically reduce the possible states » How do we get rid of unnecessary states?

Slide 36

Slide 36 text

Design Rule 1 Love types 20 * We will look at two FP design rules in this talk. * Let’s start with types!

Slide 37

Slide 37 text

“A type signature is worth a thousand tests.” 21 » Let’s look at a simple example…

Slide 38

Slide 38 text

@interface MyInventory : NSObject @property NSDictionary *inventory; - (NSInteger)lookup:(NSString *)item; @end @implementation MyInventory - (instancetype)init { self = [super init]; if (self) _inventory = @{@"iPad Air": @10, @"MacBook Pro": @3, @"iPhone 5S": @7}; return self; } - (NSInteger)lookup:(NSString *)item { return [(NSNumber *)self.inventory[item]) integerValue]; } @end 22 * If we accidentally add a non-numeric value, [-lookup:] will crash.

Slide 39

Slide 39 text

@interface MyInventory : NSObject @property NSDictionary *inventory; - (NSInteger)lookup:(NSString *)item; @end @implementation MyInventory - (instancetype)init { self = [super init]; if (self) _inventory = @{@"iPad Air": @10, @"MacBook Pro": @3, @"iPhone 5S": @7}; return self; } - (NSInteger)lookup:(NSString *)item { return [(NSNumber *)self.inventory[item]) integerValue]; } @end @[@7]}; 22 * If we accidentally add a non-numeric value, [-lookup:] will crash.

Slide 40

Slide 40 text

class MyInventory { let inventory: [String: Int] = ["iPad Air": 10, ! ! ! ! ! ! ! ! ! ! ! ! ! "MacBook Pro": 3, ! ! ! ! ! ! ! ! ! ! ! ! ! "iPhone 5S": 7] func lookup(item: String) -> Int? { return inventory[item] } } 23 * How awesome is Swift?!? * If we try to add a non-numeric value, we get a type error. (Same if we tried it via a function.) * How to test the ObjC version? One test is not sufficient. * This is a simple example? What if dict not static? What if value type varies per dict?

Slide 41

Slide 41 text

class MyInventory { let inventory: [String: Int] = ["iPad Air": 10, ! ! ! ! ! ! ! ! ! ! ! ! ! "MacBook Pro": 3, ! ! ! ! ! ! ! ! ! ! ! ! ! "iPhone 5S": 7] func lookup(item: String) -> Int? { return inventory[item] } } [7]] 23 * How awesome is Swift?!? * If we try to add a non-numeric value, we get a type error. (Same if we tried it via a function.) * How to test the ObjC version? One test is not sufficient. * This is a simple example? What if dict not static? What if value type varies per dict?

Slide 42

Slide 42 text

class MyInventory { let inventory: [String: Int] = ["iPad Air": 10, ! ! ! ! ! ! ! ! ! ! ! ! ! "MacBook Pro": 3, ! ! ! ! ! ! ! ! ! ! ! ! ! "iPhone 5S": 7] func lookup(item: String) -> Int? { return inventory[item] } } [7]] ⛔️ dictionary type 23 * How awesome is Swift?!? * If we try to add a non-numeric value, we get a type error. (Same if we tried it via a function.) * How to test the ObjC version? One test is not sufficient. * This is a simple example? What if dict not static? What if value type varies per dict?

Slide 43

Slide 43 text

[Key: Value] == Dictionary [String: Int] == Dictionary 24 * This is not limited to builtin types. You can use the same power in your own definitions.

Slide 44

Slide 44 text

struct Dictionary : CollectionType, DictionaryLiteralConvertible { … } [Key: Value] == Dictionary [String: Int] == Dictionary 24 * This is not limited to builtin types. You can use the same power in your own definitions.

Slide 45

Slide 45 text

func i(x: T) -> T { return x } The expressiveness of types ??? 25 * Guess the function! (Assuming no type inspection nor non-termination) * Try this with tests. * ”Theorems for free!” (aka parametricity)

Slide 46

Slide 46 text

func i(x: T) -> T { return x } The expressiveness of types 25 * Guess the function! (Assuming no type inspection nor non-termination) * Try this with tests. * ”Theorems for free!” (aka parametricity)

Slide 47

Slide 47 text

func i(x: T) -> T { return x } func m(f: (T -> U), a: [T]) -> [U] { return a.map(f) } The expressiveness of types ??? 25 * Guess the function! (Assuming no type inspection nor non-termination) * Try this with tests. * ”Theorems for free!” (aka parametricity)

Slide 48

Slide 48 text

func i(x: T) -> T { return x } func m(f: (T -> U), a: [T]) -> [U] { return a.map(f) } The expressiveness of types 25 * Guess the function! (Assuming no type inspection nor non-termination) * Try this with tests. * ”Theorems for free!” (aka parametricity)

Slide 49

Slide 49 text

func i(x: T) -> T { return x } func m(f: (T -> U), a: [T]) -> [U] { return a.map(f) } func r(e: U, f: ((U, T) -> U), a: [T]) -> U { return a.reduce(e, combine: f) } The expressiveness of types ??? 25 * Guess the function! (Assuming no type inspection nor non-termination) * Try this with tests. * ”Theorems for free!” (aka parametricity)

Slide 50

Slide 50 text

func i(x: T) -> T { return x } func m(f: (T -> U), a: [T]) -> [U] { return a.map(f) } func r(e: U, f: ((U, T) -> U), a: [T]) -> U { return a.reduce(e, combine: f) } The expressiveness of types 25 * Guess the function! (Assuming no type inspection nor non-termination) * Try this with tests. * ”Theorems for free!” (aka parametricity)

Slide 51

Slide 51 text

func i(x: T) -> T { return x } func m(f: (T -> U), a: [T]) -> [U] { return a.map(f) } func r(e: U, f: ((U, T) -> U), a: [T]) -> U { return a.reduce(e, combine: f) } The expressiveness of types Try this: write a unit test giving the same guarantees 25 * Guess the function! (Assuming no type inspection nor non-termination) * Try this with tests. * ”Theorems for free!” (aka parametricity)

Slide 52

Slide 52 text

Types let the compiler eliminate (error) states 26 * Test frameworks are run less frequently * Usually, because they are slow: they typically alway test everything * Not bit rot » That gets us to the second design rule…

Slide 53

Slide 53 text

Types let the compiler eliminate (error) states Every single time you build ✓ 26 * Test frameworks are run less frequently * Usually, because they are slow: they typically alway test everything * Not bit rot » That gets us to the second design rule…

Slide 54

Slide 54 text

Types let the compiler eliminate (error) states Every single time you build ✓ Only checks what changed ✓ 26 * Test frameworks are run less frequently * Usually, because they are slow: they typically alway test everything * Not bit rot » That gets us to the second design rule…

Slide 55

Slide 55 text

Types let the compiler eliminate (error) states Every single time you build ✓ Only checks what changed ✓ ✓ Checked documentation 26 * Test frameworks are run less frequently * Usually, because they are slow: they typically alway test everything * Not bit rot » That gets us to the second design rule…

Slide 56

Slide 56 text

Design Rule 2 Minimise (mutable) state 27 * The second design rule is about managing state differently.

Slide 57

Slide 57 text

Possible states of your application 28

Slide 58

Slide 58 text

Possible states of your application Lack of composition 28

Slide 59

Slide 59 text

Possible states of your application Lack of composition Mutable data 28

Slide 60

Slide 60 text

Possible states of your application Lack of composition Interdependent data Duplicating data Mutable data 28

Slide 61

Slide 61 text

WWDC 2014, Session 229 Advanced iOS Application Architecture and Patterns 29 * This is a large topic, and it would take too long now to go into much detail. * For concrete advice and examples, see this great talk by Andy Matuschak and Colin Barrett » Applying these ideas can be tricky…

Slide 62

Slide 62 text

WWDC 2014, Session 229 Advanced iOS Application Architecture and Patterns Avoid state duplication 29 * This is a large topic, and it would take too long now to go into much detail. * For concrete advice and examples, see this great talk by Andy Matuschak and Colin Barrett » Applying these ideas can be tricky…

Slide 63

Slide 63 text

WWDC 2014, Session 229 Advanced iOS Application Architecture and Patterns Avoid state duplication Use immutable data 29 * This is a large topic, and it would take too long now to go into much detail. * For concrete advice and examples, see this great talk by Andy Matuschak and Colin Barrett » Applying these ideas can be tricky…

Slide 64

Slide 64 text

M V C 30 * Applying these ideas to existing apps can be hard * Especially with bloated controllers

Slide 65

Slide 65 text

M V C Kitchen sink 30 * Applying these ideas to existing apps can be hard * Especially with bloated controllers

Slide 66

Slide 66 text

M V Citchen sink K 31 * View owns the view model * View model adapts the model to be suitable for presentation * View model can be unit tested (independent of views & view controllers) * We need AppKit & UIKit controller classes: but keep controllers small

Slide 67

Slide 67 text

M V C V M iew odel 31 * View owns the view model * View model adapts the model to be suitable for presentation * View model can be unit tested (independent of views & view controllers) * We need AppKit & UIKit controller classes: but keep controllers small

Slide 68

Slide 68 text

M V C V M iew odel ownership 31 * View owns the view model * View model adapts the model to be suitable for presentation * View model can be unit tested (independent of views & view controllers) * We need AppKit & UIKit controller classes: but keep controllers small

Slide 69

Slide 69 text

M V C V M iew odel adapt model for presentation ownership 31 * View owns the view model * View model adapts the model to be suitable for presentation * View model can be unit tested (independent of views & view controllers) * We need AppKit & UIKit controller classes: but keep controllers small

Slide 70

Slide 70 text

M V C V M iew odel adapt model for presentation suitable for unit testing ownership 31 * View owns the view model * View model adapts the model to be suitable for presentation * View model can be unit tested (independent of views & view controllers) * We need AppKit & UIKit controller classes: but keep controllers small

Slide 71

Slide 71 text

M V C V M iew odel &C adapt model for presentation suitable for unit testing ownership 31 * View owns the view model * View model adapts the model to be suitable for presentation * View model can be unit tested (independent of views & view controllers) * We need AppKit & UIKit controller classes: but keep controllers small

Slide 72

Slide 72 text

Possible states of your application 32 * Immutable models in Swift using structs, enums & classes with readonly properties (lets)

Slide 73

Slide 73 text

Possible states of your application simple relationship between view state and the state of the view model ✓ 32 * Immutable models in Swift using structs, enums & classes with readonly properties (lets)

Slide 74

Slide 74 text

Possible states of your application simple relationship between view state and the state of the view model ✓ (parts of the) model can be immutable ✓ 32 * Immutable models in Swift using structs, enums & classes with readonly properties (lets)

Slide 75

Slide 75 text

struct Project { let name: String let image: UIImage let canvas: Canvas let url: NSURL // Create empty project init(name: String) // Create project for image at URL init(url: NSURL) // Create project from image for fixed URL init(image: UIImage, name: String, url: NSURL) // Rename project func rename(name: String) -> Project // Remove project backing file func remove() } 33 * No aliasing to worry about * Tests don’t depend on context (except the file system — which is global mutable state) * Cf. blog post by Alexandros Salazar: http://nomothetis.svbtle.com/immutable-swift

Slide 76

Slide 76 text

types >< state Questions to ask How can I use types to eliminate tests? How can I minimise state to eliminate tests? 34 » For some more background on the universal nature of FP…

Slide 77

Slide 77 text

“Do Extraterrestrials Use Functional Programming?” https://speakerdeck.com/mchakravarty/do-extraterrestrials-use-functional-programming 2013 35 * YOW! Lambda Jam 2013 keynote * Annual conference on functional programming for developers in Australia

Slide 78

Slide 78 text

Thank you! 36

Slide 79

Slide 79 text

"Nile blue 05" by Kuebi = Armin Kübelbeck - Own work. CC BY-SA 3.0 - http://commons.wikimedia.org/wiki/File:Nile_blue_05.jpg Images from http://wikimedia.org http://openclipart.org 37