Funcitonal Swift Conference: The Functional Way
-
Upload
natasha-murashev -
Category
Software
-
view
4.280 -
download
0
description
Transcript of Funcitonal Swift Conference: The Functional Way
![Page 1: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/1.jpg)
THE FUNCTIONAL WAY
@NATASHATHEROBOT
![Page 2: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/2.jpg)
"functional programming is a programming paradigm... that treats
computation as the evaluation of mathematical functions and avoids changing-state and mutable data."
Wikipedia
![Page 3: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/3.jpg)
"A mathematical function is a function that when you give it the same
argument, it will give you the same result" - Edx FP101x
![Page 4: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/4.jpg)
▸ computation as the evaluation of mathematical functions▸ avoid changing state▸ avoid mutable data
![Page 5: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/5.jpg)
![Page 6: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/6.jpg)
NO SIDE EFFECTS
![Page 7: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/7.jpg)
let numbers = Array(1...10)var total = 0
func addNumbers() { for number in numbers { total += number }}
![Page 8: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/8.jpg)
addNumbers()total // 55
addNumbers()total // 110
addNumbers()total // 165
![Page 9: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/9.jpg)
let myNumbers = Array(1...10)var total = addNumbers(myNumbers)
func addNumbers(numbers: [Int]) -> Int { // can also be written shorthand as // numbers.reduce(0,+) return numbers.reduce(0) { (sum, number) in sum + number }}
![Page 10: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/10.jpg)
total = addNumbers(myNumbers) // 55
total = addNumbers(myNumbers) // 55
total = addNumbers(myNumbers) // 55
![Page 11: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/11.jpg)
import Foundation
class Gift {
let recipient: String let item: String let budget: NSDecimalNumber let status: Status
enum Status: String { case Purchased = "Purchased" case Wrapped = "Wrapped" case Delivered = "Delivered" }
init(recipient: String, item: String, budget: NSDecimalNumber, status: Status) { self.recipient = recipient self.item = item self.budget = budget self.status = status }
}
![Page 12: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/12.jpg)
extension Gift {
func todo() -> String { switch status { case .Purchased: return "Wrap it!" case .Wrapped: return "Mail it!" case .Delivered: return "Relax and drink some eggnog :)" } }
}
![Page 13: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/13.jpg)
extension Gift {
func todo(fromStatus status: Status) -> String { switch status { case .Purchased: return "Wrap it!" case .Wrapped: return "Mail it!" case .Delivered: return "Relax and drink some eggnog :)" } }
}
![Page 14: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/14.jpg)
class GiftTests: XCTestCase {
func testTodo_Purchased() { let gift = Gift( recipient: "My Cousin Julie, item: "GoldieBlox", budget: NSDecimalNumber(double: 20.00), status: .Purchased)
XCTAssertEqual(gift.todo(), "Wrap it!") }
func testTodo_Wrapped() { let gift = Gift( recipient: "My Cousin Julie", item: "GoldieBlox", budget: NSDecimalNumber(double: 20.00), status: .Wrapped)
XCTAssertEqual(gift.todo(), "Mail it!") }
func testTodo_Delivered() { let gift = Gift( recipient: "My Cousin Julie", item: "GoldieBlox", budget: NSDecimalNumber(double: 20.00), status: .Delivered)
XCTAssertEqual(gift.todo(), "Relax and drink some eggnog :)") }
}
![Page 15: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/15.jpg)
import XCTest
class GiftTests: XCTestCase {
let gift = Gift( recipient: "My Cousin Tommy", item: "Choo Choo Train", budget: NSDecimalNumber(double: 20.00), status: .Purchased)
func testTodo_Purchased() { XCTAssertEqual(gift.todo(fromStatus: .Purchased), "Wrap it!") }
func testTodo_Wrapped() { XCTAssertEqual(gift.todo(fromStatus: .Wrapped), "Mail it!") }
func testTodo_Delivered() { XCTAssertEqual(gift.todo(fromStatus: .Delivered), "Relax and drink some eggnog :)") }
}
![Page 16: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/16.jpg)
import XCTest
class GiftTests: XCTestCase {
func testTodo_Purchased() { XCTAssertEqual(Gift.todo(fromStatus: .Purchased), "Wrap it!") }
func testTodo_Wrapped() { XCTAssertEqual(Gift.todo(fromStatus: .Wrapped), "Mail it!") }
func testTodo_Delivered() { XCTAssertEqual(Gift.todo(fromStatus: .Delivered), "Relax and drink some eggnog :)") }
}
![Page 17: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/17.jpg)
VALUE TYPES
![Page 18: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/18.jpg)
"Almost all types in Swift are value types, including arrays, dictionaries, numbers, booleans, tuples, and enums. Classes are the exception rather than
the rule." - Functional Swift Book
![Page 19: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/19.jpg)
NSError *err = nil;CGFloat result = [MYArithmetic divide:2.5 by:3.0 error:&err];
if (err) { NSLog(@"%@", err)} else { [MYArithmetic doSomethingWithResult:result]}
@nomothetis
![Page 20: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/20.jpg)
enum Result { case Success(AnyObject) case Failure(NSError)}
@nomothetis
![Page 21: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/21.jpg)
let result = MYArithmetic.divide(2.5, by:3)
switch result {case Success(let quotient): doSomethingWithResult(quotient)case Failure(let error): handleError(error)}
@nomothetis
![Page 22: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/22.jpg)
http://nomothetis.svbtle.com/error-handling-in-swift
![Page 23: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/23.jpg)
CURRYING
![Page 24: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/24.jpg)
func add(x: Int, y: Int) -> Int { return x + y}
add(2, 3) // 5
![Page 25: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/25.jpg)
func add(x: Int) -> Int -> Int { return { y in return x + y }}
let partialAdd = add(2)// let addFunc: (Int -> Int)
let sum = partialAdd(3)// 5
let arr = [1,2,3]let incrementBy2 = arr.map(partialAdd)// [3,4,5]
add(6)(4)// 10
![Page 26: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/26.jpg)
func add(#x: Int)(y: Int) -> Int { return x + y}
add(x: 2)(y: 3)// 5
![Page 27: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/27.jpg)
struct Logger { /// Level of log message to aid in the filtering of logs enum Level: Int, Printable { /// Messages intended only for debug mode case Debug = 3
/// Messages intended to warn of potential errors case Warn = 2
/// Critical error messages case Error = 1
/// Log level to turn off all logging case None = 0
var description: String { switch(self) { case .Debug: return "Debug" case .Warn: return "Warning" case .Error: return "Error" case .None: return "" } } }}
@drewag
![Page 28: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/28.jpg)
extension Logger {
/// What is the max level to be logged /// /// Any logs under the given log level will be ignored static var logLevel: Level = .Warn
/// Log a message to the console static func log (#level: Level) (name: String) (message: String) -> String { if level.rawValue <= Logger.logLevel.rawValue { return "\(level.description): \(name) - \(message)" }
return "" }}
@drewag
![Page 29: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/29.jpg)
Logger.log(level: .Debug)(name: "MyFunction")(message: "Is this being called?")// Debug: MyFunction - Is this being called?
![Page 30: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/30.jpg)
extension Logger {
/// Logger for debug messages static var debug = Logger.log(level: .Debug) // static var debug: (name: String) -> (message: String) -> String
/// Logger for warnings static var warn = Logger.log(level: .Warn)
/// Logger for errors static var error = Logger.log(level: .Error)
}
@drewag
![Page 31: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/31.jpg)
Logger.logLevel = .Debug
func myFunctionToDebug() { var x = 5 // do something to x Logger.debug(name: "myFunctionToDebug")(message: "x: \(x)")}
myFunctionToDebug()// Prints: "Debug: myFunctionToDebug - x: 10"
@drewag
![Page 32: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/32.jpg)
func myFunctionToDebug() { var x = 5 var y = 3
// do something to x // do something to y
let debugMyFunction = Logger.debug(name: "myFunctionToDebug")
debugMyFunction(message: "x: \(x)") debugMyFunction(message: "y: \(y)")}
myFunctionToDebug()// Prints: "Debug: myFunctionToDebug - x: 10"// Prints: "Debug: myFunctionToDebug - y: 13"
![Page 33: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/33.jpg)
http://drewag.me/posts/practical-use-for-curried-functions-in-swift
![Page 34: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/34.jpg)
TYPE-DRIVEN DESIGN
![Page 35: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/35.jpg)
func credits(account: Account) -> Int { // ask data source for account credits return credits}
@FunctionalSwift
![Page 36: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/36.jpg)
typealias Credits = Int
func credits(account: Account) -> Credits { // ask data source for amount of credits return amount}
@FunctionalSwift
![Page 37: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/37.jpg)
"One important lesson I've learned is that designing the right types for your
problem is a great way to help the compiler debug your program." -
@wouterswierstra
![Page 38: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/38.jpg)
struct Credits { let amount: Int }
func credits(account: Account) -> Credits { // ask data source for amount of credits return Credits(amount: amount)}
@FunctionalSwift
![Page 39: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/39.jpg)
let myCredits = credits(myAccount)myCredits + 1 // ERROR// Cannot invoke '+' with an argument of type// '(Credit, IntegerLiteralConvertable)'
![Page 40: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/40.jpg)
http://www.objc.io/snippets/8.html
http://www.swiftcast.tv/articles/the-design-of-types
![Page 41: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/41.jpg)
RESOURCES▸ Functional Swift Book
▸ Edx FP101x▸ Functional Snippets
▸ An Introduction to Haskell - Skills Matter▸ swiftnews.curated.co
![Page 42: Funcitonal Swift Conference: The Functional Way](https://reader035.fdocuments.us/reader035/viewer/2022081401/559a90f31a28ab811d8b46d5/html5/thumbnails/42.jpg)
QUESTIONS?@NATASHATHEROBOT