Slide 1

Slide 1 text

Blending 
 Kotlin's culture into Swift 2017/8/9 ezura

Slide 2

Slide 2 text

“\(self)” ezura (@eduraaa) iOS engineer @LINE I like Swift :) I like Kotlin, Objective-C, …

Slide 3

Slide 3 text

Kotlin delegation object variance interface generics sealed
 class

Slide 4

Slide 4 text

sealed
 class Kotlin

Slide 5

Slide 5 text

index What is `sealed class`? blending `sealed class` concept into Swift trying it on a real product code

Slide 6

Slide 6 text

abstract
 class
 Super class
 SubA class
 SubB

Slide 7

Slide 7 text

when (instance as Super) { is SubA -> … // do something is SubB -> … // do something else -> … // fatal error? makeshift code? }.let { … } !!: Only when treating "when" as an expression, checked whether it covers all. switch-case
 expression noise… Kotlin

Slide 8

Slide 8 text

switch instance as Super { case let a as SubA: … // do something case let b as SubB: … // do something default: … // fatal error? makeshift code? } noise… Even if the premise is broken, 
 we can not detect statically. Swift Inhibit the representation 
 that it covers the whole type in the context :(

Slide 9

Slide 9 text

sad code… func didSelect(item: Item) { switch item { case let item as Book: // do something // use item as Book case let item as Memo: // do something // use item as Memo default: assertionFailure("unexpected type: \(item)") } } noise…

Slide 10

Slide 10 text

when (instance as Super) { is SubA -> … // do something is SubB -> … // do something else -> … // fatal error? makeshift code? }.let { … } !!: Only when treating "when" as an expression, checked whether it covers all. switch-case
 expression Kotlin

Slide 11

Slide 11 text

when (instance as Super) { is Super.SubA -> … // do something is Super.SubB -> … // do something else -> … // fatal error? makeshift code? }.let { … } noise… Kotlin !!: Only when treating "when" as an expression, checked whether it covers all.

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

sealed class
 Super class
 SubA class
 SubB

Slide 14

Slide 14 text

sealed class Super { // ... class SubA: Super() { // ... } class SubB: Super() { // ... } } Kotlin

Slide 15

Slide 15 text

when (instance as Super) { is Super.SubA -> … // do something is Super.SubB -> … // do something } Kotlin

Slide 16

Slide 16 text

Kotlin Beautiful world :)

Slide 17

Slide 17 text

Kotlin Swift Beautiful world :) sealed class
 concept

Slide 18

Slide 18 text

Goal not for:
 Completely reproducing the function of `sealed` for:
 reproducing the concept of `sealed` To clarify that the code covers the types 
 that can be taken in the context Swift

Slide 19

Slide 19 text

resolve this issue func didSelect(item: Item) { switch item { case let item as Book: // do something // use item as Book case let item as Memo: // do something // use item as Memo default: assertionFailure("unexpected type: \(item)") } } noise…

Slide 20

Slide 20 text

abstract
 class
 Item class
 Book class
 Memo protocol struct/enum struct/enum

Slide 21

Slide 21 text

protocol Item { // ... } struct Book: Item { // ... } struct Memo: Item { // ... } Swift

Slide 22

Slide 22 text

Cover all situations that may exist enum

Slide 23

Slide 23 text

enum ItemType { case book(Book) case memo(Memo) } Swift

Slide 24

Slide 24 text

func didSelect(item: ItemType) { switch item { case .book(let book): // do something // use item as Book case .memo(let memo): // do something // use item as Memo default: assertionFailure("unexpected type: \(item)") } } Swift noise…

Slide 25

Slide 25 text

protocol Item { // ... var name: String { get } } struct Book: Item { // ... let name: String } struct Memo: Item { // ... let name: String } Swift

Slide 26

Slide 26 text

let item: ItemType = … let name = item.name Swift error… enum ItemType { case book(Book) case memo(Memo) }

Slide 27

Slide 27 text

let name: String = { switch item { case .book(let book): return book.name case .memo(let memo): return memo.name } }() Swift

Slide 28

Slide 28 text

Kotlin :(

Slide 29

Slide 29 text

enum ItemType { case book(Book) case memo(Memo) } Swift Bad point: There is no (or weak) expression 
 that `enum ItemType` is a set of Sub types of “Item"

Slide 30

Slide 30 text

enum ItemType { // … private var base: Item { switch self { case .book(let item as Item),
 .memo(let item as Item): return item } } var name: String { return base.name } } Swift 3

Slide 31

Slide 31 text

enum ItemType: Item { // … private var base: Item { switch self { case .book(let item as Item),
 .memo(let item as Item): return item } } var name: String { return base.name } } Swift 3 or

Slide 32

Slide 32 text

enum ItemType: Item { // ... private var base: Item { switch self { case .book(let item): return item case .memo(let item): return item } } var name: String { return base.name } } Xcode 9.0 beta 4

Slide 33

Slide 33 text

enum ItemType { case book(Book) case memo(Memo) private var base: Item { switch self { case .book(let item as Item),
 .memo(let item as Item): return item } } var name: String { return base.name } } Swift result

Slide 34

Slide 34 text

func didSelect(item: ItemType) { switch item { case .book(let book): // do something // use item as Book case .memo(let memo): // do something // use item as Memo default: assertionFailure("unexpected type: \(item)") } } Swift noise…

Slide 35

Slide 35 text

Swift protocol Item { // ... var name: String { get } } let item: ItemType = … let name = item.name

Slide 36

Slide 36 text

Appendix

Slide 37

Slide 37 text

In refactoring,
 we Partially incorporate similar concept

Slide 38

Slide 38 text

class SampleController { var item: Item // … func f() { switch item { case let item as Book: // do something // use item as Book case let item as Memo: // do something // use item as Memo default: assertionFailure("unexpected type: \(item)") } } } Swift before

Slide 39

Slide 39 text

class SampleController { enum ItemType { case book(Book) case memo(Memo) private var base: Item { … } // … } var item: ItemType func f() { … } } // usage SampleController(item: .book(book)) SampleController(item: .memo(memo)) Swift after

Slide 40

Slide 40 text

Conclusion blending Kotlin's “sealed class concept” into Swift We can express the context clearly with the above concept We can partially try this

Slide 41

Slide 41 text

Thank you 
 for listening