89
Object Oriented Functional Programming Saul Mora [email protected] @casademora

ITT 2015 - Saul Mora - Object Oriented Function Programming

Embed Size (px)

Citation preview

Page 1: ITT 2015 - Saul Mora - Object Oriented Function Programming

Object Oriented Functional Programming

Saul Mora [email protected]

@casademora

Page 2: ITT 2015 - Saul Mora - Object Oriented Function Programming

Functional Object Oriented Programming

Saul Mora [email protected]

@casademora

Page 3: ITT 2015 - Saul Mora - Object Oriented Function Programming

Programming Oriented Functional Object

Saul Mora [email protected]

@casademora

Page 4: ITT 2015 - Saul Mora - Object Oriented Function Programming
Page 5: ITT 2015 - Saul Mora - Object Oriented Function Programming

Objects

Page 6: ITT 2015 - Saul Mora - Object Oriented Function Programming

C++

Objective C

C#

Java

RubyPython

Javascript PHP

Page 7: ITT 2015 - Saul Mora - Object Oriented Function Programming

Scala!

Clojure!

Swift

Page 8: ITT 2015 - Saul Mora - Object Oriented Function Programming
Page 9: ITT 2015 - Saul Mora - Object Oriented Function Programming

Will it blend

Page 10: ITT 2015 - Saul Mora - Object Oriented Function Programming

What a Functional Language is NOT

Page 11: ITT 2015 - Saul Mora - Object Oriented Function Programming

Statically Typed

Page 12: ITT 2015 - Saul Mora - Object Oriented Function Programming

Generic

Page 13: ITT 2015 - Saul Mora - Object Oriented Function Programming

Overloaded Operators

Page 14: ITT 2015 - Saul Mora - Object Oriented Function Programming

Optionals

Page 15: ITT 2015 - Saul Mora - Object Oriented Function Programming

A language where functions are value types

Page 16: ITT 2015 - Saul Mora - Object Oriented Function Programming

F(x) = y

Page 17: ITT 2015 - Saul Mora - Object Oriented Function Programming

f(x: Int) -> Int

Page 18: ITT 2015 - Saul Mora - Object Oriented Function Programming
Page 19: ITT 2015 - Saul Mora - Object Oriented Function Programming

let numbers = [1, 2, 3, 4, 5]var calculatedNumbers: [Int] = []for value in numbers { calculatedNumbers.append(value * 2)}

Page 20: ITT 2015 - Saul Mora - Object Oriented Function Programming

map

Page 21: ITT 2015 - Saul Mora - Object Oriented Function Programming
Page 22: ITT 2015 - Saul Mora - Object Oriented Function Programming
Page 23: ITT 2015 - Saul Mora - Object Oriented Function Programming
Page 24: ITT 2015 - Saul Mora - Object Oriented Function Programming

let numbers = [1, 2, 3, 4, 5]let calculatedNumbers = map(numbers) { $0 * 2 }

Page 25: ITT 2015 - Saul Mora - Object Oriented Function Programming

Declarative vs. Imperative

Page 26: ITT 2015 - Saul Mora - Object Oriented Function Programming

What vs. How

Page 27: ITT 2015 - Saul Mora - Object Oriented Function Programming

Deep Dive

Page 28: ITT 2015 - Saul Mora - Object Oriented Function Programming

func old_and_busted_expired(fileURL: NSURL) -> Bool

Page 29: ITT 2015 - Saul Mora - Object Oriented Function Programming

func old_and_busted_expired(fileURL: NSURL) -> Bool { let fileManager = NSFileManager() if let filePath = fileURL.path { if fileManager.fileExistsAtPath(filePath) { var error: NSError? let fileAttributes =

fileManager.attributesOfItemAtPath(filePath, error: &error)

if let fileAttributes = fileAttributes { if let creationDate =

fileAttributes[NSFileModificationDate] as? NSDate {

return creationDate.isBefore(NSDate.oneDayAgo())

} } else { NSLog("No file attributes \(filePath)") } } } return false}

Page 30: ITT 2015 - Saul Mora - Object Oriented Function Programming

!let fileManager = NSFileManager()if let filePath = fileURL.path { if fileManager.fileExistsAtPath(filePath) { var error: NSError? let fileAttributes =

fileManager.attributesOfItemAtPath(filePath, error: &error)

if let fileAttributes = fileAttributes { if let creationDate =

fileAttributes[NSFileModificationDate] as? NSDate {

return creationDate .isBefore(NSDate.oneDayAgo())

} } else { NSLog("No file attributes \(filePath)") } }}

Page 31: ITT 2015 - Saul Mora - Object Oriented Function Programming

return creationDate.isBefore(NSDate.oneDayAgo())

Page 32: ITT 2015 - Saul Mora - Object Oriented Function Programming

!let fileManager = NSFileManager()if let filePath = fileURL.path { if fileManager.fileExistsAtPath(filePath) { var error: NSError? let fileAttributes =

fileManager.attributesOfItemAtPath(filePath, error: &error)

if let fileAttributes = fileAttributes { if let creationDate =

fileAttributes[NSFileModificationDate] as? NSDate {

return creationDate .isBefore(NSDate.oneDayAgo())

} } else { NSLog("No file attributes \(filePath)") } }}

Page 33: ITT 2015 - Saul Mora - Object Oriented Function Programming

unwrapping the file path!

check if the file exists!

extract and unwrap the file attributes!

extract, unwrap and cast the NSModifiedDateAttribute!

compute one day ago!

return comparison to file last modified date

Page 34: ITT 2015 - Saul Mora - Object Oriented Function Programming

let filePath = fileURL.path

Page 35: ITT 2015 - Saul Mora - Object Oriented Function Programming

let fileExists : (_) -> (_)

Page 36: ITT 2015 - Saul Mora - Object Oriented Function Programming

let fileExists : (String) -> (String?)

Page 37: ITT 2015 - Saul Mora - Object Oriented Function Programming

let fileExists : (String) -> (String?) ={ path in

fileManager.fileExistsAtPath(path) ? path : nil

}

Page 38: ITT 2015 - Saul Mora - Object Oriented Function Programming

let retrieveFileAttributes : (_) -> (_)

Page 39: ITT 2015 - Saul Mora - Object Oriented Function Programming

let retrieveFileAttributes : (String) -> ([NSObject: AnyObject]?)

Page 40: ITT 2015 - Saul Mora - Object Oriented Function Programming

let retrieveFileAttributes : (String) -> ([NSObject: AnyObject]?) = { path invar error : NSError?let attributes = fileManager.attributesOfItemAtPath(path, error: &error)

!if attributes == nil {NSLog("Unable to check \(filePath): \(error)")

}return attributes

}

Page 41: ITT 2015 - Saul Mora - Object Oriented Function Programming

let extractCreationDate : (_) -> (_)

Page 42: ITT 2015 - Saul Mora - Object Oriented Function Programming

let extractCreationDate : ([NSObject:AnyObject]) -> (NSDate?)

Page 43: ITT 2015 - Saul Mora - Object Oriented Function Programming

let extractCreationDate : [NSObject:AnyObject] -> NSDate? = { $0[NSFileModificationDate] as? NSDate }

Page 44: ITT 2015 - Saul Mora - Object Oriented Function Programming

filePath: String?

fileExists: String -> String?

extractFileAttributes: String -> [NSObject:AnyObject]?

extractCreationDate: [NSObject:AnyObject] -> NSDate?

Page 45: ITT 2015 - Saul Mora - Object Oriented Function Programming

let filePath: String?

let fileExists: String -> String?

let extractFileAttributes: String -> [NSObject:AnyObject]?

let extractCreationDate: [NSObject:AnyObject] -> NSDate?

Page 46: ITT 2015 - Saul Mora - Object Oriented Function Programming

bind

Page 47: ITT 2015 - Saul Mora - Object Oriented Function Programming

bind(A?, f(A,B?)) -> B?

Page 48: ITT 2015 - Saul Mora - Object Oriented Function Programming

func bind<A, B>(a: A?, f: A -> B?) -> B? { if let x = a { return f(x) } else { return .None }}

Page 49: ITT 2015 - Saul Mora - Object Oriented Function Programming

bind(filePath, fileExists)

Page 50: ITT 2015 - Saul Mora - Object Oriented Function Programming

bind(bind(filePath, fileExists), retrieveFileAttributes)

Page 51: ITT 2015 - Saul Mora - Object Oriented Function Programming

bind(bind(bind(filePath, fileExists), retrieveFileAttributes), extractCreationDate)

Page 52: ITT 2015 - Saul Mora - Object Oriented Function Programming

let creationDate: NSDate? = bind(bind(bind(filePath, fileExists), retrieveFileAttributes), extractCreationDate)

Page 53: ITT 2015 - Saul Mora - Object Oriented Function Programming

>>= operator

Page 54: ITT 2015 - Saul Mora - Object Oriented Function Programming

func >>=<A, B>(a: A?, f: A -> B?) -> B? { return bind(a, f)}

Page 55: ITT 2015 - Saul Mora - Object Oriented Function Programming

bind(filePath, fileExists)

Page 56: ITT 2015 - Saul Mora - Object Oriented Function Programming

filePath >>= fileExists

Page 57: ITT 2015 - Saul Mora - Object Oriented Function Programming

if let creationDate = filePath >>= fileExists >>= retrieveFileAttributes >>= extractCreationDate { return creationDate.isBefore(NSDate.oneDayAgo())}

Page 58: ITT 2015 - Saul Mora - Object Oriented Function Programming

let checkExpired: NSDate -> Bool? = { $0.isBefore(NSDate.oneDayAgo()) }

Page 59: ITT 2015 - Saul Mora - Object Oriented Function Programming

return filePath >>= fileExists >>= retrieveFileAttributes >>= extractCreationDate >>= checkExpired ?? false

Page 60: ITT 2015 - Saul Mora - Object Oriented Function Programming

func expired(fileURL: NSURL) -> Bool { let fileManager = NSFileManager() var error : NSError? let filePath = fileURL.path let fileExists : (String) -> (String?) =

{ path in fileManager.fileExistsAtPath(path) ? path : nil } let retrieveFileAttributes : (String) -> ([NSObject: AnyObject]?) =

{ path in var error : NSError? return fileManager.attributesOfItemAtPath(path, error: &error) } let extractCreationDate : ([NSObject:AnyObject]) -> NSDate? =

{ $0[NSFileModificationDate] as? NSDate } let checkExpired: NSDate -> Bool? =

{ $0.isBefore(NSDate.oneDayAgo()) } return filePath >>= fileExists >>= retrieveFileAttributes >>=

extractCreationDate >>= checkExpired ?? false}

Page 61: ITT 2015 - Saul Mora - Object Oriented Function Programming

Readability

Page 62: ITT 2015 - Saul Mora - Object Oriented Function Programming

bind!

flatMap (fmap)!

apply

>>= (>>-)!

<^> (<$>)!

<*>

Page 63: ITT 2015 - Saul Mora - Object Oriented Function Programming

func <^><A, B>(f: A -> B, a: A?) -> B? { return fmap(f, a)}!func fmap<A, B>(f: A -> B, a: A?) -> B? { if let x = a { return f(x) } else { return .None }}

Page 64: ITT 2015 - Saul Mora - Object Oriented Function Programming

func <*><A, B>(f: (A -> B)?, a: A?) -> B? { return apply(f, a)}!func apply<A, B>(f: (A -> B)?, a: A?) -> B? { if let x = a, let fx = f { return fx(x) } return .None}

Page 65: ITT 2015 - Saul Mora - Object Oriented Function Programming

Argohttp://github.com/thoughtbot/Argo

Page 66: ITT 2015 - Saul Mora - Object Oriented Function Programming

What about objects?

Page 67: ITT 2015 - Saul Mora - Object Oriented Function Programming

Caching

Page 68: ITT 2015 - Saul Mora - Object Oriented Function Programming

retrieve

Page 69: ITT 2015 - Saul Mora - Object Oriented Function Programming

protocol DataSource { func fetchItem() -> Int?}!func retrieve<S: DataSource, T>(from: S, or: S) -> T? { return from.fetchItem() ?? or.fetchItem()}

Page 70: ITT 2015 - Saul Mora - Object Oriented Function Programming

protocol DataSource { func fetchItem() -> Int?}!func retrieveItem<S: DataSource, T>(from: S, or: S) -> T? { return from.fetchItem() ?? or.fetchItem()}

Page 71: ITT 2015 - Saul Mora - Object Oriented Function Programming

return <DataSource>!.functionCall()! -> Int?

Page 72: ITT 2015 - Saul Mora - Object Oriented Function Programming

!func retrieve<S: DataSource, T>

(from: S, or: S, using: S -> T?) -> T?{ return using(from) ?? using(or)}

Page 73: ITT 2015 - Saul Mora - Object Oriented Function Programming

let localDataSource: DataSourcelet remoteDataSource: DataSourcereturn retrieve(from: localDataSource, or: remoteDataSource) { $0.fetchItem() }

Page 74: ITT 2015 - Saul Mora - Object Oriented Function Programming

Data Client

RemoteDataSource

LocalDataSource

Page 75: ITT 2015 - Saul Mora - Object Oriented Function Programming

Data Client

RemoteDataSource

LocalDataSource

Page 76: ITT 2015 - Saul Mora - Object Oriented Function Programming

Data Client

RemoteDataSource

LocalDataSource

DataSourceCache

Page 77: ITT 2015 - Saul Mora - Object Oriented Function Programming

Data Client RemoteDataSource

LocalDataSource

DataSourceCache

Cache Strategy

Page 78: ITT 2015 - Saul Mora - Object Oriented Function Programming

protocol DataSourceCacheStrategy { func retrieve<T>(from: [DataSource], using: DataSource -> T?) -> T? } !struct DataSourceCache { let strategy: DataSourceCacheStrategy let localDataSource: DataSource let remoteDataSource: DataSource func fetch<T>(applyFunction: DataSource -> T?) -> T? { let sources = [localDataSource, remoteDataSource] return strategy.retrieve(sources, using: applyFunction) } }

Page 79: ITT 2015 - Saul Mora - Object Oriented Function Programming

struct BasicDataSourceCacheStrategy: DataSourceCacheStrategy { func retrieve<T>(from: [DataSource], using: DataSource -> T?) -> T? { for dataSource in from { if let result = using(dataSource) { return result } } return nil } }

Page 80: ITT 2015 - Saul Mora - Object Oriented Function Programming

struct MoreFancyDataSourceCacheStrategy: DataSourceCacheStrategy { ! func retrieve<T>(from: [DataSource], using: DataSource -> T?) -> T? { let cacheValidation: T? -> Bool = { $0 != nil } for dataSource in from { let result = using(dataSource) if cacheValidation(result) { return result } } return nil } }

Page 81: ITT 2015 - Saul Mora - Object Oriented Function Programming

https://gist.github.com/casademora/

3b784e57bd09c0bc9147

Page 82: ITT 2015 - Saul Mora - Object Oriented Function Programming

Encapsulation

Page 83: ITT 2015 - Saul Mora - Object Oriented Function Programming

Abstraction

Page 84: ITT 2015 - Saul Mora - Object Oriented Function Programming

SOLID

Page 85: ITT 2015 - Saul Mora - Object Oriented Function Programming

Object Oriented in the Large, Functional in the

Small

Page 86: ITT 2015 - Saul Mora - Object Oriented Function Programming

- Alan Kay, The Early History of Smalltalk

I was less interested in programs as algebraic patterns than I was in a clear scheme that could

handle a variety of styles of programming.

Page 87: ITT 2015 - Saul Mora - Object Oriented Function Programming

Programming

Page 88: ITT 2015 - Saul Mora - Object Oriented Function Programming

–Alan Kay

Programming is at heart a practical art in which real things are built, and a real implementation

thus has to exist.

Page 89: ITT 2015 - Saul Mora - Object Oriented Function Programming

Object Oriented Functional Programming

Saul Mora [email protected]

@casademora