Blending Kotlin's culture into Swift

Blending Kotlin's culture into Swift

6a55a7fb19c1fa78e86ddca7a69db088?s=128

Yuka Ezura

August 09, 2017
Tweet

Transcript

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

  2. “\(self)” ezura (@eduraaa) iOS engineer @LINE I like Swift :)

    I like Kotlin, Objective-C, …
  3. Kotlin delegation object variance interface generics sealed
 class

  4. sealed
 class Kotlin

  5. index What is `sealed class`? blending `sealed class` concept into

    Swift trying it on a real product code
  6. abstract
 class
 Super class
 SubA class
 SubB

  7. 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
  8. 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 :(
  9. 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…
  10. 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
  11. 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.
  12. None
  13. sealed class
 Super class
 SubA class
 SubB

  14. sealed class Super { // ... class SubA: Super() {

    // ... } class SubB: Super() { // ... } } Kotlin
  15. when (instance as Super) { is Super.SubA -> … //

    do something is Super.SubB -> … // do something } Kotlin
  16. Kotlin Beautiful world :)

  17. Kotlin Swift Beautiful world :) sealed class
 concept

  18. 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
  19. 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…
  20. abstract
 class
 Item class
 Book class
 Memo protocol struct/enum struct/enum

  21. protocol Item { // ... } struct Book: Item {

    // ... } struct Memo: Item { // ... } Swift
  22. Cover all situations that may exist enum

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

  24. 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…
  25. protocol Item { // ... var name: String { get

    } } struct Book: Item { // ... let name: String } struct Memo: Item { // ... let name: String } Swift
  26. let item: ItemType = … let name = item.name Swift

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

    book): return book.name case .memo(let memo): return memo.name } }() Swift
  28. Kotlin :(

  29. 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"
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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…
  35. Swift protocol Item { // ... var name: String {

    get } } let item: ItemType = … let name = item.name
  36. Appendix

  37. In refactoring,
 we Partially incorporate similar concept

  38. 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
  39. 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
  40. Conclusion blending Kotlin's “sealed class concept” into Swift We can

    express the context clearly with the above concept We can partially try this
  41. Thank you 
 for listening