WHAT
Functional programming is a programming paradigm
1. treats computation as the evaluation of mathematical functions
2. avoids changing-state and mutable data
— Wikipedia
Slide 5
Slide 5 text
PARADIGM
Slide 6
Slide 6 text
No content
Slide 7
Slide 7 text
THINK
Slide 8
Slide 8 text
IMPERATIVE: MACHINE
let nums = [1, 2, 3, 4, 5, 6, 7]
var strs = [String]()
for var i = 0; i < nums.count; ++i {
strs.append(String(nums[i]))
}
Slide 9
Slide 9 text
DECLARATIVE: MATHEMATICS
let nums = [1, 2, 3, 4, 5, 6, 7]
let strs = nums.map(String.init)
Slide 10
Slide 10 text
WHY
Slide 11
Slide 11 text
CURRY
Slide 12
Slide 12 text
CURRY
func x(a: A, b: B, c: C) -> E
func x(a: A) -> (b: B) -> (c: C) -> E
Slide 13
Slide 13 text
CURRY
struct User {
func login(password: String)
}
let passwd = "@Swift"
let usr = User()
usr.login(passwd)
Slide 14
Slide 14 text
CURRY
struct User {
func login(password: String)
}
let passwd = "@Swift"
let usr = User()
User.login(usr)(passwd)
CURRY IN PRACTICE
struct User {
func name() -> String
}
let collation: UILocalizedIndexedCollation = ...
let sorted = collation.sortedArrayFromArray(users,
collationStringSelector: "name")
Slide 17
Slide 17 text
CURRY IN PRACTICE
class Wrapper: NSObject {
let payload: T
let localization: (T) -> () -> String
@objc func localizable() -> NSString {
return localization(payload)()
}
static var selector: Selector {
return "localizable"
}
}
Slide 18
Slide 18 text
CURRY IN PRACTICE
let wrappers = users.map {
Wrapper(payload: $0, localization: User.name)
}
let sorted = collation.sortedArrayFromArray(wrappers,
collationStringSelector: Wrapper.selector)
Slide 19
Slide 19 text
FUNCTIONAL ABSTRACTION
Slide 20
Slide 20 text
OPTIONAL
enum Optional {
case None
case Some(T)
}
Slide 21
Slide 21 text
OPTIONAL
func map(f: T -> U) -> U?
func flatMap(f: T -> U?) -> U?
let date: NSDate? = ...
let formatter: NSDateFormatter = ...
let dateString = date.map(formatter.stringFromDate)
ASYNC CALLBACK
(value: T?, error: ErrorType?) -> Void
if let error = error {
// handle error
} else if let value = value {
// handle value
} else {
// all nil?
}
// all non-nil?!
Slide 31
Slide 31 text
RESULT
enum Result {
case Failure(ErrorType)
case Success(Value)
}
Slide 32
Slide 32 text
RESULT
(result: Result) -> Void
switch result {
case let .Error(error):
// handle error
case let .Success(value):
// handle value
}
Slide 33
Slide 33 text
RESULT
enum Result {
func map(...) -> Result {
...
}
func flatMap(...) -> Result {
...
}
}
Slide 34
Slide 34 text
RESULT
func flatMap(@noescape transform: Value throws -> Result) rethrows -> Result {
switch self {
case let .Failure(error):
return .Failure(error)
case let .Success(value):
return try transform(value)
}
}
func map(@noescape transform: Value throws -> T) rethrows -> Result {
return try flatMap { .Success(try transform($0)) }
}
Slide 35
Slide 35 text
RESULT
func toImage(data: NSData) -> Result
func addAlpha(image: UIImage) -> Result
func roundCorner(image: UIImage) -> Result
func applyBlur(image: UIImage) -> Result
Slide 36
Slide 36 text
RESULT
toImage(data)
.flatMap(addAlpha)
.flatMap(roundCorner)
.flatMap(applyBlur)
Slide 37
Slide 37 text
REFERENCE
▸ Wikipedia
▸ Haskell Wiki
▸ Functional Programming in Swift
▸ objc.io