Slide 1

Slide 1 text

Practical Declarative Programming KyleFuller

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Imperative Programming

Slide 5

Slide 5 text

Describe how to achive something

Slide 6

Slide 6 text

Declarative Programming

Slide 7

Slide 7 text

Describe what to do. Not how to do it.

Slide 8

Slide 8 text

Why Declarative Programming?

Slide 9

Slide 9 text

Readability

Slide 10

Slide 10 text

Simplicity

Slide 11

Slide 11 text

Constraint driven Less room for errors

Slide 12

Slide 12 text

Why are we not doing declarative programming?

Slide 13

Slide 13 text

How

Slide 14

Slide 14 text

Domain Specific Languages (DSLs)

Slide 15

Slide 15 text

Constraints

Slide 16

Slide 16 text

Regular expressions

Slide 17

Slide 17 text

\d\d / \d\d / \d\d\d\d 12 / 06 / 2015

Slide 18

Slide 18 text

SQL Structured Query Language

Slide 19

Slide 19 text

SELECT * FROM comments WHERE author == 'Kyle'

Slide 20

Slide 20 text

NSPredicate

Slide 21

Slide 21 text

NSPredicate(format: "name == 'Kyle'")

Slide 22

Slide 22 text

Functional Programming

Slide 23

Slide 23 text

What makes up functional programming?

Slide 24

Slide 24 text

What makes up functional programming? 4 first class functions 4 immutable data 4 reducing 4 pipelining 4 recursing 4 currying 4 monads

Slide 25

Slide 25 text

What makes up functional programming? 4 first class functions 4 immutable data 4 reducing 4 pipelining 4 recursing 4 currying 4 monads

Slide 26

Slide 26 text

Side-effects

Slide 27

Slide 27 text

What is not functional function?

Slide 28

Slide 28 text

Un-functional Function var value = 0 func increment() { value += 1 }

Slide 29

Slide 29 text

Un-functional Function func increment() { let center = NSNotificationCenter.defaultCenter() let value = center.valueForKey("key") as? Int ?? 0 center.setValue(value + 1, forKey: "key") }

Slide 30

Slide 30 text

Functional Function func increment(value:Int) -> Int { return value + 1 }

Slide 31

Slide 31 text

High Order Functions

Slide 32

Slide 32 text

High Order Functions 4 Functions that take other functions as arguments

Slide 33

Slide 33 text

High Order Functions 4 Functions that take other functions as arguments 4 Functions that returns a functions

Slide 34

Slide 34 text

Everything is a closure

Slide 35

Slide 35 text

State of callables in Objective-C

Slide 36

Slide 36 text

@implementation Object - (void)message:(NSString *)value { } @end

Slide 37

Slide 37 text

@implementation Object - (void)message:(NSString *)value { } @end [object message:@“Hello”];

Slide 38

Slide 38 text

void message(NSString *value) { }

Slide 39

Slide 39 text

void message(NSString *value) { } message(@“Hello”);

Slide 40

Slide 40 text

void (^message)(NSString *value) = ^void(NSString *value) { };

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

void (^message)(NSString *value) = ^void(NSString *value) { }; message(@“Hello”);

Slide 43

Slide 43 text

Callables in Swift

Slide 44

Slide 44 text

(String) -> ()

Slide 45

Slide 45 text

let message:(String -> ())

Slide 46

Slide 46 text

let message:(String -> ()) = { value in }

Slide 47

Slide 47 text

func message(value:String) { }

Slide 48

Slide 48 text

message("AltConf")

Slide 49

Slide 49 text

Interchangeability

Slide 50

Slide 50 text

func message1(value:String) { println(“Hello \(value)”) }

Slide 51

Slide 51 text

func message1(value:String) { println(“Hello \(value)”) } var message2:(String -> ()) = { value in println(“Hi \(value)”) }

Slide 52

Slide 52 text

func message1(value:String) { println(“Hello \(value)”) } var message2:(String -> Void) = { value in println(“Hi \(value)”) } message2 = message1 message2(“AltConf”) // Hello AltConf

Slide 53

Slide 53 text

Functional programming by Example

Slide 54

Slide 54 text

let groups = [ ["Kyle", "Katie"], ["André", "Maxine", "Ash"] ]

Slide 55

Slide 55 text

How many people are in each group?

Slide 56

Slide 56 text

How many people are in each group? let groups = [["Kyle", "Katie"], ["André", "Maxine", "Ash"]] var counts = [Int]() for group in groups { let people = count(group) counts.append(people) } counts // [2, 3]

Slide 57

Slide 57 text

map

Slide 58

Slide 58 text

map (source, transform) -> ([T])

Slide 59

Slide 59 text

transform (item) -> (T)

Slide 60

Slide 60 text

How many people are in each group? let groups = [["Kyle", "Katie"], ["André", "Maxine", "Ash"]] map(groups) { count($0) } // [2, 3]

Slide 61

Slide 61 text

count (sequence) -> (Int)

Slide 62

Slide 62 text

transform (item) -> (T)

Slide 63

Slide 63 text

(item) -> (T) (sequence) -> (Int)

Slide 64

Slide 64 text

How many people are in each group? let groups = [["Kyle", "Katie"], ["André", "Maxine", "Ash"]] map(groups, count) // [2, 3]

Slide 65

Slide 65 text

Order the numbers of people in each group

Slide 66

Slide 66 text

[2, 3] -> [3, 2]

Slide 67

Slide 67 text

sorted

Slide 68

Slide 68 text

sorted (sequence, isOrderedBefore) -> (sequence)

Slide 69

Slide 69 text

isOrderedBefore (lhs, rhs) -> (Bool)

Slide 70

Slide 70 text

Order the numbers of people in each group let count = [2, 3]

Slide 71

Slide 71 text

Order the numbers of people in each group let count = [2, 3] sorted(count) { (lhs, rhs) in lhs > rhs } // largest group is [3, 2].first

Slide 72

Slide 72 text

Operators are closures

Slide 73

Slide 73 text

> (lhs, rhs) -> (Bool)

Slide 74

Slide 74 text

let count = [2, 3] sorted(count, >) // largest group is [3, 2].first

Slide 75

Slide 75 text

Building an array of all people

Slide 76

Slide 76 text

Building an array of all people let groups = [["Kyle", "Katie"], ["André", "Maxine", "Ash"]] var people = [String]() for group in groups { people += group } // ["Kyle", "Katie", "André", "Maxine", "Ash"]

Slide 77

Slide 77 text

reduce

Slide 78

Slide 78 text

reduce (sequence, initial(U), combine) -> (U)

Slide 79

Slide 79 text

combine (U, value) -> (U)

Slide 80

Slide 80 text

+ (U, U) -> (U)

Slide 81

Slide 81 text

reduce(groups, [], +)

Slide 82

Slide 82 text

Building an array of all people let groups = [["Kyle", "Katie"], ["André", "Maxine", "Ash"]] reduce(groups, [], +) // ["Kyle", "Katie", "André", "Maxine", "Ash"]

Slide 83

Slide 83 text

let input = "Kyle,Katie\nAndré,Maxine,Ash"

Slide 84

Slide 84 text

let input = "Kyle,Katie\nAndré,Maxine,Ash" var groups = [[String]]() for line in input.componentsSeparatedByString("\n") { let group = line.componentsSeparatedByString(",") groups.append(group) } groups // [["Kyle", "Katie"], ["André", "Maxine", "Ash"]]

Slide 85

Slide 85 text

let input = "Kyle,Katie\nAndré,Maxine,Ash" let groups = map(input.componentsSeparatedByString("\n")) { line in line.componentsSeparatedByString(",") } groups // [["Kyle", "Katie"], ["André", "Maxine", "Ash"]]

Slide 86

Slide 86 text

let input = "Kyle,Katie\nAndré,Maxine,Ash" func commaSeparator(input:String) -> [String] { return input.componentsSeparatedByString(",") } map(input.componentsSeparatedByString("\n"), commaSeparator) // [["Kyle", "Katie"], ["André", "Maxine", "Ash"]]

Slide 87

Slide 87 text

High Order Functions 4 Functions that returns a functions

Slide 88

Slide 88 text

func separateBy(separator:String) -> ((String) -> [String]) { func inner(source:String) -> [String] { return source.componentsSeparatedByString(separator) } return inner }

Slide 89

Slide 89 text

func separateBy(separator:String) -> ((String) -> [String]) { func inner(source:String) -> [String] { return source.componentsSeparatedByString(separator) } return inner } let lineSeparator = separateBy("\n") let commaSeparator = separateBy(",")

Slide 90

Slide 90 text

func separateBy(separator:String)(source:String) -> [String] { return source.componentsSeparatedByString(separator) } let lineSeparator = separateBy("\n") let commaSeparator = separateBy(",")

Slide 91

Slide 91 text

let input = "Kyle,Katie\nAndré,Maxine,Ash" map(lineSeparator(input), commaSeparator) // [["Kyle", "Katie"], ["André", "Maxine", "Ash"]]

Slide 92

Slide 92 text

Why are map and reduce better?

Slide 93

Slide 93 text

Declarative

Slide 94

Slide 94 text

Immutability

Slide 95

Slide 95 text

Don’t iterate over arrays

Slide 96

Slide 96 text

Don’t iterate over arrays 4 Use map

Slide 97

Slide 97 text

Don’t iterate over arrays 4 Use map 4 Use reduce

Slide 98

Slide 98 text

Write declaratively Not imperatively

Slide 99

Slide 99 text

Conclusion 4 DSLs can be used to reduce bugs and build simpler generic declaritive languages 4 We’ve seen how Functional Programming can be used to build declarative code 4 We’ve seen how declarative code helps simplicity, testability and on boarding new developers

Slide 100

Slide 100 text

fuller.li/talks KyleFuller [email protected]