Successfully reported this slideshow.
Your SlideShare is downloading. ×

A Deeper Deep Dive into Swift Literal

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Deep Dive into Swift Literal
Deep Dive into Swift Literal
Loading in …3
×

Check these out next

1 of 115 Ad

More Related Content

Similar to A Deeper Deep Dive into Swift Literal (20)

Advertisement

Recently uploaded (20)

A Deeper Deep Dive into Swift Literal

  1. 1. A Deeper Deep dive into Swift Literals freddi from LINE Fukuoka at try! Swift NYC 2019 (9th.Sep)
  2. 2. About Me freddi (Yuki Aki) from ! Developing LINE Creators Studio at LINE Fukuoka Organizer of HAKATA.swift
  3. 3. - What is a Literal in Computer Programming? - Why I want you to deep dive into Swift Literals? - Literals in Swift - Object of Literals - Architecture of Type from Literals - Conclusion Agenda High-Level Low-Level
  4. 4. What is a Literal in Computer Programming?
  5. 5. What is a Literal in Computer Programming? What is a Literal in Computer Programming? Notations for representing a fixed value in source code. Values we write in a conventional form whose is obvious
  6. 6. // Integer Literal let assigningIntegerLiteral = 42 // String Literal let assigningStringLiteral = "try! Swift" What is a Literal in Computer Programming?
  7. 7. Literal is a minimal way to represent the actual data for Programmer What is a Literal in Computer Programming?
  8. 8. Why I want you to deep-dive into Swift Literals?
  9. 9. Why I want you to deep-dive into Swift Literals? We have more chances to touch low level Swift compared to Other Languages
  10. 10. Why I want you to deep-dive into Swift Literals?
  11. 11. But,it is not easy to learn 😩 Why I want you to deep-dive into Swift Literals?
  12. 12. Compiler Code looks too difficult and is too long for reading Why I want you to deep-dive into Swift Literals?
  13. 13. Why I talk about Literals? Why I want you to deep-dive into Swift Literals?
  14. 14. Why I talk about Literals? I learned Swift Compiler things through understanding deep side of Swift Literals Why I want you to deep-dive into Swift Literals?
  15. 15. Literals in Swift
  16. 16. Literals in Swift (Basic Literals) // Integer Literal let assigningIntegerLiteral = 42 // Float Literal let assigningFloatLiteral = 10.0 // String Literal let assigningStringLiteral = "try! Swift"
 
 // Boolean Literal let assigningBooleanLiteral = true
  17. 17. Representing basic data - Integer Literal → integer numeric - Float Literal → floating numeric - String Literal → sentence - Boolean Literal → true/false Literals in Swift (Basic Literals)
  18. 18. Literals in Swift (Basic Literals with nested Type) // Optional from Nil Literal let assigningNilLiteral: Int? = nil // Array Literal let assigningArrayLiteralWithInt: [Int] = [42] // Dictionary Literal let assigningDictLiteral: [String: Int] = [:]
  19. 19. Context of Nested Values is necessary - Nil Literal → null value - Array Literal → sequencial value - Dictionary Literal → value with key Literals in Swift (Basic Literals with nested Type)
  20. 20. Literals in Swift (Basic Literals with nested Type) // Not declared what type you want to make optional ❌ let assigningNilLiteral = nil // Not declared what element type ❌ let assigningArrayLiteral = []
  21. 21. Literals in Swift (Special Literals) // Color Literal let color = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1) // Image Literal let image = #imageLiteral(resourceName: “cat”) // File Reference Literal let file = #fileLiteral(resourceName: “cat.txt”)
  22. 22. Swift also provides Special Literals for resources - Color Literal → color - Image Literal → image - File Reference Literal → file location Literals in Swift (Special Literals)
  23. 23. Literals in Swift (Special Literals) Color/Image/File Reference Literal are - rendered as Actual Data in Xcode - File → select from file manager - Color → adjusting color code
  24. 24. // Color Literal let color = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1) Literals in Swift (Special Literals)
  25. 25. Literals in Swift (Special Literals at Xcode!) // Color Literal let color =
  26. 26. // Color Literal let color = Literals in Swift (Special Literals at Xcode!)
  27. 27. // Image Literal let image = #imageLiteral(resourceName: “cat") Literals in Swift (Special Literals)
  28. 28. // Image Literal let image = Literals in Swift (Special Literals at Xcode!)
  29. 29. // Image Literal let image = Literals in Swift (Special Literals at Xcode!)
  30. 30. Literals are a minimal way to represent value by programmer There are many Literals in Swift,not only usual Literal! - Integer,Array,Nil,Color etc… Literals in Swift
  31. 31. Object of Literals
  32. 32. Object of Literals The Ways of determining Type of value are … - Type Annotation - Type Inference with Default Type of Literal
  33. 33. // Integer Literal // assigningIntegerLiteral is Int let assigningIntegerLiteral: Int = 42 Literals get Type from annotation after colon(:) Object of Literals(Type Annotation)
  34. 34. // Integer Literal // assigningIntegerLiteral is Float let assigningIntegerLiteral: Float = 42 Literals get Type from annotation after colon(:) Object of Literals(Type Annotation)
  35. 35. Object of Literals The Ways of determining Type of value are … - Type Annotation - Type Inference with Default Type of Literal
  36. 36. Object of Literals (Type Inference) // Integer Literal // assigningIntegerLiteral is Int let assigningIntegerLiteral = 42 Each Literal has Default Type,can be inferenced
  37. 37. Object of Literals (Special Literals) // Image Literal let image = #imageLiteral(resourceName: “cat”) type(of: image) // UIImage at UIKit, NSImage at AppKit AppKit UIKit Image Literal NSImage UIImage Color Literal NSColor UIColor
  38. 38. Object of Literals Some Literals are treated as Object which cannot be used Directly
  39. 39. Swift’s Compiling Flow 42 SIL(Swift Intermediate Language) Abstract Syntax Tree(AST) AST With Type information
  40. 40. Swift’s Compiling Flow 42 SIL(Swift Intermediate Language) Abstract Syntax Tree(AST) AST With Type information Front-End of Compiler Back-End of Compiler
  41. 41. 42 SIL(Swift Intermediate Language) Abstract Syntax Tree(AST) AST With Type information Swift’s Compiling Flow
  42. 42. SIL (Swift Intermediate Language) Intermediate Language between Swift and LLVM IR - Swift code will be converted SIL after AST - Some of optimization are operated at SIL
  43. 43. Format of SIL SIL is conforming Static Single Assignment format %a = some value 1 ⭕ %b = some value 2 ⭕ %a = some value 3 ❌ Value - Object is assigned to value at each line - Assigning to one value is allowed only once
  44. 44. SIL (Swift Intermediate Language) Why do we need SIL when deep dive into Literals?
  45. 45. SIL (Swift Intermediate Language) Why do we need SIL when deep dive into Literals? We can find how Swift Code is treated by Compiler
  46. 46. SIL (Swift Intermediate Language) Why do we need SIL when deep dive into Literals? We can find how Swift Code is treated by Compiler More easy to read SIL than reading compiler code
  47. 47. Let’s read SIL let assigningLiteral: Int = 42
  48. 48. let assigningLiteral: Int = 42 %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int Let’s read SIL
  49. 49. %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int let assigningLiteral: Int = 42 Let’s read SIL
  50. 50. let assigningLiteral: Int = 42 Allocation of memory to %3 %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int Let’s read SIL
  51. 51. $Builtin.Int64 object is assigned %4 %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int let assigningLiteral: Int = 42 Let’s read SIL
  52. 52. At first,Some Literals are … %4 = integer_literal $Builtin.Int64, 42 Literal Object - treated as “Literal Object” starts with $Builtin.*** - $Builtin.*** will be used in Actual Type Initializer
  53. 53. %4 = integer_literal $Builtin.Int64, 42 Literal Object At first,Some Literals are … - treated as “Literal Object” starts with $Builtin.*** - $Builtin.*** will be used in Actual Type Initializer Un-official name!;(
  54. 54. 42 $Builtin.Int64 4.2 $Builtin.FPIEEE64 “42” $Builtin.RawPointer $Builtin.Word Integer Float String Literal Object
  55. 55. 42 $Builtin.Int64 4.2 $Builtin.FPIEEE64 “42” $Builtin.RawPointer $Builtin.Word Integer Float String let value: Float = 42 Literal Object
  56. 56. true $Builtin.Int1 Boolean Digit after $Buildin.Int means bit-size Integer 42 $Builtin.Int64 Literal Object
  57. 57. true $Builtin.Int1 Boolean Digit after $Buildin.Int means bit-size Integer 42 $Builtin.Int64 Literal Object
  58. 58. #imageLiteral(resourceName: “cat”) UIImage(named: “cat”) Image Literal(at import UIKit) No Literal Object! Literal Object
  59. 59. $Builtin.Int64 object is assigned %4 %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int let assigningLiteral: Int = 42 Let’s read SIL
  60. 60. let assigningLiteral: Int = 42 %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int Let’s read SIL $Builtin.Int64 object is assigned %4
  61. 61. %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int Literal Object (%4) is passed to Int Initializer Let’s read SIL let assigningLiteral: Int = 42
  62. 62. Some Type which can be generated from Literal Let’s read SIL - has initializer which receives Literal Object - Initializer of default Type is used,if type not annotated
  63. 63. %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int Literal Object (%4) is passed to Int Initializer Let’s read SIL let assigningLiteral: Int = 42
  64. 64. %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int The generated Int Object is assigned to allocated place let assigningLiteral: Int = 42Let’s read SIL
  65. 65. "try! Swift" Let’s read SIL
  66. 66. "try! Swift" %2 = string_literal utf8 "try! Swift" // user: %7 %3 = integer_literal $Builtin.Word, 10 // user: %7 %4 = integer_literal $Builtin.Int1, -1 // user: %7 %5 = metatype $@thin String.Type // user: %7 // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) %6 = function_ref ... %7 = apply %6(%2, %3, %4, %5) ... Let’s read SIL(from string literal to String)
  67. 67. %2 = string_literal utf8 "try! Swift" // user: %7 %3 = integer_literal $Builtin.Word, 10 // user: %7 %4 = integer_literal $Builtin.Int1, -1 // user: %7 %5 = metatype $@thin String.Type // user: %7 // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) %6 = function_ref ... %7 = apply %6(%2, %3, %4, %5) ... Let’s read SIL(from string literal to String)
  68. 68. Let’s read SIL(from string literal to String) %2 = string_literal utf8 "try! Swift" // user: %7 %3 = integer_literal $Builtin.Word, 10 // user: %7 %4 = integer_literal $Builtin.Int1, -1 // user: %7 %2: $Builtin.RawPointer // pointer of string %4: $Builtin.Int1 // flag string is Ascii or not %3: $Builtin.Word // length of data on memory
  69. 69. %2 = string_literal utf8 "try! Swift" // user: %7 %3 = integer_literal $Builtin.Word, 10 // user: %7 %4 = integer_literal $Builtin.Int1, -1 // user: %7 %5 = metatype $@thin String.Type // user: %7 // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) %6 = function_ref ... %7 = apply %6(%2, %3, %4, %5) ... Let’s read SIL(from string literal to String)
  70. 70. // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) %6 = function_ref ... %7 = apply %6(%2, %3, %4, %5) ... Let’s read SIL(from string literal to String)
  71. 71. Swift Literals are treated as Literal Object at first - Literal Object will be used for Initializers of actual Swift Type Object of Literals %5 = struct $Int (%4 : $Builtin.Int64)
  72. 72. Architecture of Type from Literals
  73. 73. Literal Object At first,Some Literals are treated as “Literal Object” 42 $Builtin.Int64 4.2 $Builtin.FPIEEE64 “42” $Builtin.RawPointer $Builtin.Word Integer Float String
  74. 74. %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int Literal Object is passed to Int Initializer Initializer which receives Literal Object
  75. 75. Implementation of this initializer is required by _ExpressibleByBuiltin***Literal protocol %5 = struct $Int (%4 : $Builtin.Int64) Initializer which receives Literal Object
  76. 76. What is _ExpressibleByBuiltin***Literal protocol? _ExpressibleByBuiltin***Literal
  77. 77. What is _ExpressibleByBuiltin***Literal protocol? _ExpressibleByBuiltin***Literal public protocol _ExpressibleByBuiltinIntegerLiteral { init(_builtinIntegerLiteral value: Builtin.IntLiteral) } init(:Builtin.IntLiteral) is called on assigning Literal by = - Type which conforming with this protocol is convertible by Literal Object
  78. 78. _ExpressibleByBuiltin***Literal init(:Builtin.IntLiteral) is called on assigning Literal by = %5 = struct $Int (%4 : $Builtin.Int64) What is _ExpressibleByBuiltin***Literal protocol? - Type which conforming with this protocol is convertible by Literal Object
  79. 79. ExpressibleBy***Literal You may know ExpressibleBy***Literal protocol - makes Type be convertible by each Literal,using = - ExpressibleByIntegerLiteral - ExpressibleByFloatLiteral - ExpressibleByBooleanLiteral …
  80. 80. struct OriginalIntegerType: ExpressibleByIntegerLiteral { typealias IntegerLiteralType = Int init(integerLiteral value: IntegerLiteralType) {} } 
 let value: OriginalIntegerType = 10 ExpressibleBy***Literal How to make Original Type convertible from Literal?
  81. 81. struct OriginalIntegerType: ExpressibleByIntegerLiteral { typealias IntegerLiteralType = Int init(integerLiteral value: IntegerLiteralType) {} } 
 let value: OriginalIntegerType = 10 1.Set typealias to IntegerLiteralType the type should be converted from Integer Literal ExpressibleBy***Literal How to make Original Type convertible from Literal?
  82. 82. struct OriginalIntegerType: ExpressibleByIntegerLiteral { typealias IntegerLiteralType = Int init(integerLiteral value: IntegerLiteralType) {} } 
 let value: OriginalIntegerType = 10 2.Implement Initializer which receives IntegerLiteralType value ExpressibleBy***Literal How to make Original Type convertible from Literal?
  83. 83. struct OriginalIntegerType: ExpressibleByIntegerLiteral { typealias IntegerLiteralType = Int init(integerLiteral value: IntegerLiteralType) {} } 
 let value: OriginalIntegerType = 10 You can initialize your type by Literal! ExpressibleBy***Literal How to make Original Type convertible from Literal?
  84. 84. ExpressibleBy***Literal public struct CGFloat { #if arch(i386) || arch(arm) public typealias NativeType = Float
 #elseif arch(x86_64) || arch(arm64) || … public typealias NativeType = Double ...
 typealias FloatLiteralType = NativeType CGFloat is using ExpressibleByFloatLiteral
  85. 85. struct OriginalIntegerType: ExpressibleByIntegerLiteral { typealias IntegerLiteralType = Int init(integerLiteral value: IntegerLiteralType) {} } 
 let value: OriginalIntegerType = 10 ExpressibleBy***Literal How to make Original Type convertible from Literal? 1.Set typealias to IntegerLiteralType the type should be converted from Integer Literal
  86. 86. Associated Type in ExpressibleBy***Literal should conform with _ExpressibleByBuiltin***Literal protocol public protocol ExpressibleByIntegerLiteral { associatedtype IntegerLiteralType: _ExpressibleByBuiltinIntegerLiteral ExpressibleBy***Literal
  87. 87. Flow of Converting Literal Literal Object ( = Builtin.***) Swift Type Literal
  88. 88. Swift Type Literal Object ( = Builtin.***) Swift Type: _ExpressibleByBuiltin*** Swift Type: ExpressibleBy*** Literal Optional → Flow of Converting Literal
  89. 89. _ExpressibleByBuiltin***Literal Please note that … You cannot use _ExpressibleByBuiltin***Literal protocol in your usual Swift Code 🙃 🙃 🙃
  90. 90. $Builtin.Int64 $Builtin.FPIEEE64 What is “Literal Object” ??? 🤔 $Builtin.RawPointer $Builtin.Word Literal Object
  91. 91. Literal Object Implementation of this initializer is required by _ExpressibleByBuiltin***Literal protocol %5 = struct $Int (%4 : $Builtin.Int64)
  92. 92. Where will passed Literal Object go? %5 = struct $Int (%4 : $Builtin.Int64) Literal Object
  93. 93. public struct Int : …… {
 public var _value: Builtin.Int64 Literal Object will be stored in Some Swift Types from Literal Literal Object
  94. 94. // static Int.== infix(_:_:) sil public_external ... (Int, Int, @thin Int.Type) -> Bool { ... %3 = struct_extract %0 : $Int, #Int._value // user: %5 %4 = struct_extract %1 : $Int, #Int._value // user: %5 %5 = builtin "cmp_eq_Int64"(%3 : $Builtin.Int64, %4 : $Builtin.Int64) ... %6 = struct $Bool (%5 : $Builtin.Int1) // user: %7 public var _value: Builtin.Int64 == operator on Int Literal Object
  95. 95. // static Int.== infix(_:_:) sil public_external ... (Int, Int, @thin Int.Type) -> Bool { ... %3 = struct_extract %0 : $Int, #Int._value // user: %5 %4 = struct_extract %1 : $Int, #Int._value // user: %5 %5 = builtin "cmp_eq_Int64"(%3 : $Builtin.Int64, %4 : $Builtin.Int64) ... %6 = struct $Bool (%5 : $Builtin.Int1) // user: %7 public var _value: Builtin.Int64 1.Getting _value from left value and right value Literal Object == operator on Int
  96. 96. // static Int.== infix(_:_:) sil public_external ... (Int, Int, @thin Int.Type) -> Bool { ... %3 = struct_extract %0 : $Int, #Int._value // user: %5 %4 = struct_extract %1 : $Int, #Int._value // user: %5 %5 = builtin "cmp_eq_Int64"(%3 : $Builtin.Int64, %4 : $Builtin.Int64) ... %6 = struct $Bool (%5 : $Builtin.Int1) // user: %7 public var _value: Builtin.Int64 2. Passing each _value to Back-End function Literal Object == operator on Int
  97. 97. Swift Type from Literal Swift’s Compiling Flow Front-End of Compiler Back-End of Compiler $Builtin.*** Back-End Object
  98. 98. // static Int.== infix(_:_:) sil public_external ... (Int, Int, @thin Int.Type) -> Bool { ... %3 = struct_extract %0 : $Int, #Int._value // user: %5 %4 = struct_extract %1 : $Int, #Int._value // user: %5 %5 = builtin "cmp_eq_Int64"(%3 : $Builtin.Int64, %4 : $Builtin.Int64) ... %6 = struct $Bool (%5 : $Builtin.Int1) // user: %7 public var _value: Builtin.Int64 3.Return result as Bool in Swift Literal Object == operator on Int
  99. 99. Swift Type Literal Object ( = Builtin.***) Swift Type: _ExpressibleByBuiltin*** Swift Type: ExpressibleBy*** Literal Flow of Converting Literal
  100. 100. Literal Swift Type: ExpressibleBy*** Swift Type: _ExpressibleByBuiltin*** Literal Object ( = Builtin.***) Architecture of Type from Literals Int, String … CGFloat …
  101. 101. Operators(+,-,*,/,== …) Operators(+,-,*,/,== …) Architecture of Type from Literals Back-End Function ift Type: ExpressibleBy*** ype: _ExpressibleByBuiltin*** eral Object ( = Builtin.***) Swift Ty Swift Type: Literal O
  102. 102. Some Types generated from Literals are wrappers of Literal Object Literal Object represents object in Back-End Architecture of Type from Literals
  103. 103. $Builtin.Int64 Int UInt Architecture of Type from Literals Some Types generated from Literals are wrappers of Literal Object Literal Object represents object in Back-End
  104. 104. Some Types generated from Literals are wrappers of Literal Object Literal Object represents object in Back-End Architecture of Type from Literals
  105. 105. Some Types generated from Literals are wrappers of Literal Object Literal Object represents object in Back-End Architecture of Type from Literals Swift Type from Literal $Builtin.*** Back-End Object
  106. 106. Conclusion
  107. 107. Literals in Swift Literals are a minimal way to represent value by programmer There are many Literals in Swift,not only usual Literal! - Integer,Array,Nil,Color etc…
  108. 108. Literal Object At first,Some Literals are treated as “Literal Object” 42 $Builtin.Int64 4.2 $Builtin.FPIEEE64 “42” $Builtin.RawPointer $Builtin.Word Integer Float String
  109. 109. %3 = global_addr @$s4test16assigningLiteralSivp : $*Int %4 = integer_literal $Builtin.Int64, 42 %5 = struct $Int (%4 : $Builtin.Int64) store %5 to %3 : $*Int Literal Object is passed to Int Initializer Initializer which receives Literal Object
  110. 110. Architecture of Type from Literals Literal Swift Type: ExpressibleBy*** Swift Type: _ExpressibleByBuiltin*** Literal Object ( = Builtin.***) Int, String … CGFloat …
  111. 111. For more your understanding
  112. 112. https://github.com/apple/swift For more your understanding
  113. 113. https://www.youtube.com/watch?v=sT0SNp-Tw-8 For more your understanding
  114. 114. Swiftckaigi 19th November 2019@Japan For more your understanding
  115. 115. Thank you for listening!

×