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 error 
let 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 
unsafe 
and may crash 
Denis 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 = 0 
let 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 = 0 
let 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 -> Int 
let g = A.g // Int -> Int 
let 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

Denis Lebedev. Non functional swift.

  • 1.
  • 2.
    Swift 101 »proprietary (Apple) Denis Lebedev, 2014 2
  • 3.
    Swift 101 »proprietary (Apple) » LLVM-backed Denis Lebedev, 2014 3
  • 4.
    Swift 101 »proprietary (Apple) » LLVM-backed » multi-paradigm Denis Lebedev, 2014 4
  • 5.
    Swift 101 »proprietary (Apple) » LLVM-backed » multi-paradigm » statically typed and mostly typesafe Denis Lebedev, 2014 5
  • 6.
    “It's like Objective-C,but without C” Apple WWDC Denis Lebedev, 2014 6
  • 7.
    “Swift is allabout FP - it has map and filter” someone in the Internet Denis Lebedev, 2014 7
  • 8.
    This talk isnot about » Cocoa & iOS » filter / map » ADT-based JSON parsers Denis Lebedev, 2014 8
  • 9.
    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
  • 10.
    Types classification »Protocol: trait, type class Denis Lebedev, 2014 10
  • 11.
    Types classification »Protocol: trait, type class » Enum: sum type Denis Lebedev, 2014 11
  • 12.
    Types classification »Protocol: trait, type class » Enum: sum type » Struct: product type Denis Lebedev, 2014 12
  • 13.
    Types classification »Protocol: trait, type class » Enum: sum type » Struct: product type » Class: close to struct, has inheritance Denis Lebedev, 2014 13
  • 14.
    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
  • 15.
  • 16.
    Standard library »1 class, ~160 structs & protocols » no explicit root class Denis Lebedev, 2014 16
  • 17.
    Standard library : Bool » is a struct » implements protocols to inherit behavior Denis Lebedev, 2014 17
  • 18.
    Standard library »Int, Bool, Array, ... are structs » only Array and Dictionary for collections Denis Lebedev, 2014 18
  • 19.
    Standard library »heavily based on value types » ascetic but extendable » generic Denis Lebedev, 2014 19
  • 20.
    Enum » C-enum'on steroids' » good for pattern-matching Denis Lebedev, 2014 20
  • 21.
    Enum enum Types{ case Str(String) case Num(Double) } let a = Types.Num(1.0) Denis Lebedev, 2014 21
  • 22.
    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
  • 23.
    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
  • 24.
    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
  • 25.
    Mutability » letfor immutable instances » var as indicator of mutability let i = 0; i++ // compilation error let a = [1, 2]; a.append(3) // compilation error Denis Lebedev, 2014 25
  • 26.
    Mutability of structs » mark methods changing inner state as mutating » var if struct was mutated Denis Lebedev, 2014 26
  • 27.
    Optional » monadin Swift stdlib » enum-based » deeply-linked in the language Denis Lebedev, 2014 27
  • 28.
    Optional enum Optional<T>{ case None case Some(T) ... func map<U>(f: (T) -> U) -> U? } Denis Lebedev, 2014 28
  • 29.
    Optional var foo:Optional<Int> = .Some(3) switch foo { case .Some(let f): println(f) case .None: break } Denis Lebedev, 2014 29
  • 30.
    Optional : syntacticsygar var foo: Int? = 3 if let f = foo { println(f) } Denis Lebedev, 2014 30
  • 31.
    Optional : chaining var amount: Amount if let c = customer { if let a = account { amount = a.amount } } Denis Lebedev, 2014 31
  • 32.
    Optional : chainingwith syntactic sugar let amount = customer?.account?.amount // Optional(Amount) Denis Lebedev, 2014 32
  • 33.
    Optional : forceunwrapping let amount = customer!.account!.amount // Amount Denis Lebedev, 2014 33
  • 34.
    Optional : forceunwrapping let amount = customer!.account!.amount // Amount unsafe and may crash Denis Lebedev, 2014 34
  • 35.
    Optional » Playsnicely with Objective-C nil messaging » '!' operator may cause runtime crashes » '!' should be avoided in pure Swift Denis Lebedev, 2014 35
  • 36.
    Type extensions »Extend existing type Denis Lebedev, 2014 36
  • 37.
    Type extensions »Extend existing type extension String { func isBar() -> Bool { return self == "bar" } } "foo".isBar() // false Denis Lebedev, 2014 37
  • 38.
    Type extensions »Can implement protocols class B { var a: Int = 0 } extension B: Printable { var description: String { return "(a)" } } Denis Lebedev, 2014 38
  • 39.
    Protocols Task: implementgeneric stack protocol Stackable { mutating func pop() -> Int? mutating func push(Int) } Denis Lebedev, 2014 39
  • 40.
    Protocols : associatedtypes protocol Stackable { typealias Element mutating func pop() -> Element? mutating func push(Element) } Denis Lebedev, 2014 40
  • 41.
    Protocols : associatedtypes struct Stack<T> { var storage: [T] = [] } Denis Lebedev, 2014 41
  • 42.
    Protocols : associatedtypes 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
  • 43.
    Protocols : constraints Task: overload push to take an array mutating func push(s: [T]) { storage.extend(s) } Denis Lebedev, 2014 43
  • 44.
    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
  • 45.
    Protocols : recap » powerfull abstraction instrument » neat way of extending existing functionality Denis Lebedev, 2014 45
  • 46.
    Lazy evaluation »call-by-value model Denis Lebedev, 2014 46
  • 47.
    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
  • 48.
    Lazy evaluation »call-by-value model » lazy keyword is 'fake lazy' for lazy instantiation » autoclosure arguments for real laziness Denis Lebedev, 2014 48
  • 49.
    autoclosure Task: implement|| operator func OR(lhs: Bool, rhs: Bool) -> Bool { if lhs { return true } return rhs } let c = 0 let b = OR(c == 0, 1/c == 1) // error: division by zero Denis Lebedev, 2014 49
  • 50.
    autoclosure Task: implementshort-circuit || operator func OR( lhs: @autoclosure () -> Bool, rhs: @autoclosure () -> Bool) -> Bool { if lhs() { return true } return rhs() } let c = 0 let b = OR(c == 0, 1/c == 1) // true Denis Lebedev, 2014 50
  • 51.
    Functions & closures » first-class sitizens » function - special case of closure » closure has memory-management rules Denis Lebedev, 2014 51
  • 52.
    Currying » functionscan be written in curried form » no standard functions for currying Denis Lebedev, 2014 52
  • 53.
    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
  • 54.
    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 -> Int let g = A.g // Int -> Int let f = A().f // Int -> Int Denis Lebedev, 2014 54
  • 55.
    Open source »swiftz - purely functional data structures, functions, etc. » Concurrent - functional concurrency primitives » ReactiveCocoa - functional reactive programming » ExtSwift - collection extensions Denis Lebedev, 2014 55
  • 56.
    Tools : Compiler » Compiler is unstable, affects Xcode IDE stability » Sometimes compiler errors are non-informative Denis Lebedev, 2014 56
  • 57.
    Tools : Compiler » Swift compiler crashes - set of crash tests for the compiler Denis Lebedev, 2014 57
  • 58.
    Tools : Compiler » Swift compiler crashes - set of crash tests for the compiler Results: 1874 of 2024 tests crashed the compiler Denis Lebedev, 2014 58
  • 59.
    Tools : Playgrounds » Interactive scratchpad (a-la Scala's worksheet, iPython notebook) » Embed documentation generated from markdown » Render charts and 3D Denis Lebedev, 2014 59
  • 60.
    Interactive playground withdoc Denis Lebedev, 2014 60
  • 61.
    Rendering SceneKit objects Denis Lebedev, 2014 61
  • 62.
    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
  • 63.