Denis Lebedev. Non functional swift.

63
Non-functional Swift Denis Lebedev, 2014 1

Transcript of Denis Lebedev. Non functional swift.

Non-functional Swift

Denis Lebedev, 2014 1

Swift 101

» proprietary (Apple)

Denis Lebedev, 2014 2

Swift 101

» proprietary (Apple)

» LLVM-backed

Denis Lebedev, 2014 3

Swift 101

» proprietary (Apple)

» LLVM-backed

» multi-paradigm

Denis Lebedev, 2014 4

Swift 101

» proprietary (Apple)

» LLVM-backed

» multi-paradigm

» statically typed and mostly typesafe

Denis Lebedev, 2014 5

“It's like Objective-C, but without C”Apple WWDC

Denis Lebedev, 2014 6

“Swift is all about FP - it has map and filter”someone in the Internet

Denis Lebedev, 2014 7

This talk is not about

» Cocoa & iOS

» filter / map

» ADT-based JSON parsers

Denis Lebedev, 2014 8

It's about

» Standard library

» Simple yet powerful language concepts1

» Open source as a showcase of Swift possibilites

1 borrowed from other languages

Denis Lebedev, 2014 9

Types classification

» Protocol: trait, type class

Denis Lebedev, 2014 10

Types classification

» Protocol: trait, type class

» Enum: sum type

Denis Lebedev, 2014 11

Types classification

» Protocol: trait, type class

» Enum: sum type

» Struct: product type

Denis Lebedev, 2014 12

Types classification

» Protocol: trait, type class

» Enum: sum type

» Struct: product type

» Class: close to struct, has inheritance

Denis Lebedev, 2014 13

Types classification

» Protocol: -

» Enum: value-type

» Struct: value-type

» Class: reference-type2

2 Swift has no GC and uses reference counting, developer is responsible for maintaining reference cycles

Denis Lebedev, 2014 14

Denis Lebedev, 2014 15

Standard library

» 1 class, ~160 structs & protocols

» no explicit root class

Denis Lebedev, 2014 16

Standard library : Bool

» is a struct

» implements protocols to inherit behavior

Denis Lebedev, 2014 17

Standard library

» Int, Bool, Array, ... are structs

» only Array and Dictionary for collections

Denis Lebedev, 2014 18

Standard library

» heavily based on value types

» ascetic but extendable

» generic

Denis Lebedev, 2014 19

Enum

» C-enum 'on steroids'

» good for pattern-matching

Denis Lebedev, 2014 20

Enum

enum Types { case Str(String) case Num(Double)}

let a = Types.Num(1.0)

Denis Lebedev, 2014 21

Pattern matching

» works with enum

switch a {case .Str(let val): println(val)case .Num(let val): println(val) // 1.0}

Denis Lebedev, 2014 22

Pattern matching

» can match any type

switch str {case let x where x.hasPrefix("a"): println(str)default: println("did not match")}

Denis Lebedev, 2014 23

Enum : limitations

enum Result<T, U> { case Success(T) case Error(U)}

// error: unimplemented IR generation // feature non-fixed multi-payload enum layout

Denis Lebedev, 2014 24

Mutability

» let for immutable instances

» var as indicator of mutability

let i = 0; i++ // compilation errorlet a = [1, 2]; a.append(3) // compilation error

Denis Lebedev, 2014 25

Mutability of structs

» mark methods changing inner state as mutating

» var if struct was mutated

Denis Lebedev, 2014 26

Optional

» monad in Swift stdlib

» enum-based

» deeply-linked in the language

Denis Lebedev, 2014 27

Optional

enum Optional<T> { case None case Some(T)

...

func map<U>(f: (T) -> U) -> U?}

Denis Lebedev, 2014 28

Optional

var foo: Optional<Int> = .Some(3)

switch foo {case .Some(let f): println(f)case .None: break}

Denis Lebedev, 2014 29

Optional : syntactic sygar

var foo: Int? = 3

if let f = foo { println(f) }

Denis Lebedev, 2014 30

Optional : chaining

var amount: Amount

if let c = customer { if let a = account { amount = a.amount }}

Denis Lebedev, 2014 31

Optional : chaining with syntactic sugar

let amount = customer?.account?.amount // Optional(Amount)

Denis Lebedev, 2014 32

Optional : force unwrapping

let amount = customer!.account!.amount // Amount

Denis Lebedev, 2014 33

Optional : force unwrapping

let amount = customer!.account!.amount // Amount

unsafeand may crashDenis Lebedev, 2014 34

Optional

» Plays nicely with Objective-C nil messaging

» '!' operator may cause runtime crashes

» '!' should be avoided in pure Swift

Denis Lebedev, 2014 35

Type extensions

» Extend existing type

Denis Lebedev, 2014 36

Type extensions

» Extend existing type

extension String { func isBar() -> Bool { return self == "bar" }}

"foo".isBar() // false

Denis Lebedev, 2014 37

Type extensions

» Can implement protocols

class B { var a: Int = 0}

extension B: Printable { var description: String { return "\(a)" }}

Denis Lebedev, 2014 38

Protocols

Task: implement generic stack

protocol Stackable { mutating func pop() -> Int? mutating func push(Int)}

Denis Lebedev, 2014 39

Protocols : associated types

protocol Stackable { typealias Element

mutating func pop() -> Element? mutating func push(Element)}

Denis Lebedev, 2014 40

Protocols : associated types

struct Stack<T> { var storage: [T] = []}

Denis Lebedev, 2014 41

Protocols : associated types

extension Stack: Stackable { typealias Element = T

mutating func pop() -> Element? { return storage.count > 0 ? storage.removeLast() : nil }

mutating func push(e: Element) { storage.append(e) }}

Denis Lebedev, 2014 42

Protocols : constraints

Task: overload push to take an array

mutating func push(s: [T]) { storage.extend(s) }

Denis Lebedev, 2014 43

Protocols : constraints

Task: overload push to take any sequence

mutating func push <S: SequenceType where S.Generator.Element == T>(s: S) {

storage.extend(s) }

Denis Lebedev, 2014 44

Protocols : recap

» powerfull abstraction instrument

» neat way of extending existing functionality

Denis Lebedev, 2014 45

Lazy evaluation

» call-by-value model

Denis Lebedev, 2014 46

Lazy evaluation

» call-by-value model

» lazy keyword is 'fake lazy' for lazy instantiation

class A { lazy var b = [1,2,3,4]}

Denis Lebedev, 2014 47

Lazy evaluation

» call-by-value model

» lazy keyword is 'fake lazy' for lazy instantiation

» autoclosure arguments for real laziness

Denis Lebedev, 2014 48

autoclosure

Task: implement || operator

func OR(lhs: Bool, rhs: Bool) -> Bool { if lhs { return true } return rhs}

let c = 0let b = OR(c == 0, 1/c == 1) // error: division by zero

Denis Lebedev, 2014 49

autoclosure

Task: implement short-circuit || operator

func OR(lhs: @autoclosure () -> Bool, rhs: @autoclosure () -> Bool) -> Bool { if lhs() { return true } return rhs()}

let c = 0let b = OR(c == 0, 1/c == 1) // true

Denis Lebedev, 2014 50

Functions & closures

» first-class sitizens

» function - special case of closure

» closure has memory-management rules

Denis Lebedev, 2014 51

Currying

» functions can be written in curried form

» no standard functions for currying

Denis Lebedev, 2014 52

Currying

func sum(a: Int)(b: Int) -> Int { return a + b}

let a = sum(3)(5) //error: missing argument label

let a = sum(3)(b: 5)

Denis Lebedev, 2014 53

Currying & classes

class A { func f(i: Int) -> Int { return i } class func g(i: Int) -> Int { return i }}

let a_f = A.f // A -> Int -> Intlet g = A.g // Int -> Intlet f = A().f // Int -> Int

Denis Lebedev, 2014 54

Open source

» swiftz - purely functional data structures, functions, etc.

» Concurrent - functional concurrency primitives

» ReactiveCocoa - functional reactive programming

» ExtSwift - collection extensions

Denis Lebedev, 2014 55

Tools : Compiler

» Compiler is unstable, affects Xcode IDE stability

» Sometimes compiler errors are non-informative

Denis Lebedev, 2014 56

Tools : Compiler

» Swift compiler crashes - set of crash tests for the compiler

Denis Lebedev, 2014 57

Tools : Compiler

» Swift compiler crashes - set of crash tests for the compiler

Results: 1874 of 2024 tests crashed the compiler

Denis Lebedev, 2014 58

Tools : Playgrounds

» Interactive scratchpad (a-la Scala's worksheet, iPython notebook)

» Embed documentation generated from markdown

» Render charts and 3D

Denis Lebedev, 2014 59

Interactive playground with doc

Denis Lebedev, 2014 60

Rendering SceneKit objects

Denis Lebedev, 2014 61

Conclusion on Swift

» Filled with functional concepts

» Someday will become mainstream in Cocoa world

» Language and tools are immature, it's like v0.9 but called 1.1

Denis Lebedev, 2014 62

Thanks!Denis Lebedev, 2014 63