THINK SHARP, WRITE SWIFT
PASCAL BATTY
I’M A DEVELOPER
I’VE ALWAYS BEEN
A MAC NERD
I SAW A LOT OF
PEOPLE SWITCHING
I DON’T EVEN…
BASED ON SCIENTIFIC RESULTS
THE STAGES OF SWITCHING
😫 😯 😍
iOS
OS X
Apps
∞
Scripts + exe
OS X
Ubuntu
C# Swift
Object Oriented ✓ ✓
Type Inference ✓ ✓
Generics ✓ ✓
Tuples ✓ ✓
Lambdas ✓ ✓
Optional Chaining ✓ ✓
String Interpolation ✓ ✓
SWIFT VS C# FEATURE COMPARISON CHART
String Interpolation ✓ ✓
Operator overloading ✓ ✓
Null Coalescing ✓ ✓
Variadic Parameters ✓ ✓
Optional Parameters ✓ ✓
Extensions ✓ ✓
Auto-Properties ✓ ✓
Try/Catch ✓ ✓
Cool Logo ✓
THE GOOD OLD FIBONACCI SEQUENCE
LET’S COMPARE CODE
func fib(n: Int) -> Int
{
var fib0 = 0, fib1 = 1
for var i = 2; i <= n; i++
{
var tmp = fib0
fib0 = fib1
fib1 = tmp + fib1
}
return n > 0 ? fib1 : 0
}
static int fib(int n)
{
int fib0 = 0, fib1 = 1;
for (int i = 2; i <= n; i++)
{
int tmp = fib0;
fib0 = fib1;
fib1 = tmp + fib1;
}
return (n > 0 ? fib1 : 0);
}
C# Swift
as found on Wikibooks
SWIFT AND C#
ARE VERY SIMILAR
C# Swift
Garbage Collection Reference Counting
Interface Protocol
Constructor Initializer
const let
Linq MapReduce
Lambda Closure
func<> ->
SWIFT AND C# ARE KINDA SORTA SIMILAR
THE GOOD OLD FIBONACCI SEQUENCE
A FEW ADJUSTMENTS
func fib(n: Int) -> Int
{
var fib0 = 0, fib1 = 1
for var i = 2; i <= n; i++
{
var tmp = fib0
fib0 = fib1
fib1 = tmp + fib1
}
return n > 0 ? fib1 : 0
}
Variable was never mutated; consider changing to ‘let’ constant
THE GOOD OLD FIBONACCI SEQUENCE
A FEW ADJUSTMENTS
func fib(n: Int) -> Int
{
var fib0 = 0, fib1 = 1
for var i = 2; i <= n; i++
{
let tmp = fib0
fib0 = fib1
fib1 = tmp + fib1
}
return n > 0 ? fib1 : 0
}
++ is deprecated: it will be removed in Swift 3
THE GOOD OLD FIBONACCI SEQUENCE
A FEW ADJUSTMENTS
func fib(n: Int) -> Int
{
var fib0 = 0, fib1 = 1
for var i = 2; i <= n; i += 1
{
let tmp = fib0
fib0 = fib1
fib1 = tmp + fib1
}
return n > 0 ? fib1 : 0
}
C-Style for statement is deprecated and will be removed…
THE GOOD OLD FIBONACCI SEQUENCE
A FEW ADJUSTMENTS
func fib(n: Int) -> Int
{
var fib0 = 0, fib1 = 1
for i in 2...n
{
let tmp = fib0
fib0 = fib1
fib1 = tmp + fib1
}
return n > 0 ? fib1 : 0
}
Immutable value ‘i’ was never used; consider replacing with ‘_’
THE GOOD OLD FIBONACCI SEQUENCE
A FEW ADJUSTMENTS
func fib(n: Int) -> Int
{
var fib0 = 0, fib1 = 1
for _ in 2...n
{
let tmp = fib0
fib0 = fib1
fib1 = tmp + fib1
}
return n > 0 ? fib1 : 0
}
😌
THE COMPILER IS
PICKY BUT FRIENDLY
TYPE SYSTEM
LET US DIVE IN A LITTLE DEEPER
BUILDING BLOCKS
Class
Properties
Initializers
Instance Methods
Class Methods
Struct
Properties
Initializers
Instance methods
Static methods
Enum
Properties
Initializers
Instance methods
Static methods
VALUE TYPES
ARE AWESOME
I CAN’T ASK YOU TO JUST BELIEVE ME ON THIS
VALUE TYPES ARE AWESOME
▸ Immutability ensured by ‘let’
▸ No expensive boxing/unboxing
▸ Code is more thread-safe
▸ Performance is better
▸ Functional Programming is more convenient
LET US DIVE IN A LITTLE DEEPER
STANDARD TYPES
▸ Int, Float, Double
▸ Bool
▸ String, Character
▸ Array<T>, Dictionary<K: Hashable, V>, Set<T: Hashable>
THESE ARE ALL STRUCTS!
ENUMERABLES
YOU WON’T BELIEVE WHAT HAPPENS NEXT…
BRACE YOURSELVES…
ENUMERABLES AS YOU MAY KNOW THEM
enum Land {
case Forest
case Mountain
case Swamp
case Plains
case Island
}
enum Error : Int {
case NotFound = 404
case ServerError = 500
case Forbidden = 403
case Teapot = 418
}
Raw value can be
String, Character or
any numeric type
HERE COMES!
ENUMERABLES WITH ASSOCIATED VALUES!
enum PaymentMethod {
case Cash
case Check (Int)
case CreditCard (CardType, Int)
enum CardType { case Visa, MasterCard, Electron }
func display() {
switch self {
case Cash:
print("Paid by cash")
case let Check(number):
print("Paid by check #(number)")
case let CreditCard(type, number):
print("Paid by (type) #(number)")
}
}
}
let method = PaymentMethod.CreditCard(.Visa, 995423)
method.display()
NOT OVER YET!
… AND GENERICS!
enum Result<T, U> {
case Success(T)
case Error(U)
}
enum Optional<T> {
case Some(T)
case None
}
indirect enum Tree<T> {
case Empty
case Node(T, left: Tree<T>, right: Tree<T>)
}
OPTIONALS
(SPOILER: THEY’RE PRETTY COOL)
WHAT YOU MAY END UP DOING…
OPTIONALS IN THE WILD
let answer: String = "42"
let numericAnswer = Int(answer)
let byOneThousand = numericAnswer * 1000
let nineThousand: Float = 9 * 1000
let vegetaSays: String = "It's over (nineThousand) !!"
let nappaSays: String = "What!? " + String(nineThousand) + "?!"
VALUE OF OPTIONAL TYPE ‘INT?’ NOT UNWRAPPED;
DID YOU MEAN TO USE ‘!’ OR ‘?’ ?
Int?
BEAR WITH ME THERE
OPTIONALS
▸ Like nullables for all types!
▸ Variables, constants, arguments, properties or return
values
▸ You can’t use its value unless you unwrap it first
▸ If it is not Optional, it can never be nil
FORGOT TO CHECK NULLABILITY?
WON’T LET YOU USE THE VALUE
DO YOU KNOW THE ‘MAYBE’ MONAD ?
UNWRAPPING THE OPTIONAL
42
let answer: String = getAnswer()
let numericAnswer: Int? = Int(answer)
processNumericAnswer(numericAnswer)
???
Int?
Int nil
DO YOU KNOW THE ‘MAYBE’ MONAD ?
UNWRAPPING THE OPTIONAL
42
let answer: String = getAnswer()
let numericAnswer: Int? = Int(answer)
if let realAnswer: Int = numericAnswer {
processNumericAnswer(realAnswer)
}
else {
print("Please give a number")
} nil
Int?Int?
NOT EVERYTHING IS COMPULSORY
OPTIONAL PROPERTIES
struct Contact {
var firstName:String
var middleName:String?
var lastName:String
var emailAddress:String
var emailVerified:Bool
}
THAT’S A LOT OF PUNCTUATION!
NULL COALESCING AND OPTIONAL CHAINING
let answer: String = getAnswer()
let numericAnswer: Int? = Int(answer)
let sanitizedAnswer: Int = numericAnswer ?? 1
processNumericAnswer(sanitizedAnswer)
let contact: Contact? = getContact()
let email: String? = contact?.emailAddress
??
?.
FAMOUS LAST WORDS…
FORCE UNWRAP & IMPLICITLY UNWRAPPED OPTIONALS
!
« I KNOW WHAT I’M DOING.
IF YOU ENCOUNTER AN UNEXPECTED NIL
JUST CRASH AT RUNTIME »
THERE’S MORE!
PUT SOME LOGIC INSIDE YOUR TYPES!
FUN WITH PROPERTIES
struct Contact {
var firstName: String
var middleName: String?
var lastName: String
let securityNumber: Int
var fullName: String {
if let initial = middleName?.characters.first {
return "(firstName) (initial). (lastName)"
}
else {
return "(firstName) (lastName)"
}
}
var emailVerified: Bool
var emailAddress: String {
didSet {
emailVerified = false
}
}
}
MAP, FILTER, REDUCE, SORT
CLOSURES
let people:[Contact] = getContacts()
let targetNames:[String] = people
.filter({ contact in contact.lastName.hasPrefix("G") })
.map({ contact in contact.fullName })
.sort()
func multipleOf(factor: Int) -> Int -> Bool {
return { (number: Int) in number % factor == 0 }
}
let isEven = multipleOf(2)
isEven(4)
// Get the sum of multiples of 3 up to 100
(1...100)
.filter(multipleOf(3))
.reduce(0, combine: +)
https://github.com/mythz/swift-linq-examples
FUNCTIONAL
PROGRAMMING
IMAGINE THE POSSIBILITIES…
EXTENSIONS & PROTOCOLS
extension Contact {
func composeEmailBoilerplate() -> String { … }
var abbreviatedName: String { … }
}
protocol StringSerializable {
func serialize() -> String
}
extension StringSerializable {
func serialize() -> String { return "" }
}
extension Contact: StringSerializable {
func serialize() -> String { … }
}
PROTOCOL-ORIENTED
PROGRAMMING
WHERE TO START
YOU’VE GOT TO START SOMEWHERE
YOUR LEARNING ENVIRONMENT
OS X Ubuntu Windows
Xcode

Playground
REPL Ubuntu

Bash
WHEREVER YOU ARE
SWIFT SANDBOX
https://swiftlang.ng.bluemix.net
ONE OF THE PERKS OF DOING SWIFT ON THE MAC
PLAYGROUND
BECAUSE WE DON’T HAVE THE TIME TO SEE EVERYTHING
LEARN
▸ Updated eBook from Apple
▸ Available for free
▸ on iBooks
▸ on swift.org
▸ swiftdoc.org is a nice and fast
documentation website
SOLVE PROBLEMS!
Exercism.io Codingame.com
😫
Picky Compiler
SyntaxError Handling
Optionals
Incomplete

Generics
Argument

Naming
No

async/await
Value Types
for loops
A POLARIZING ASPECT
ARGUMENT NAMING
(1...100)
.filter(multipleOf(3))
.reduce(0, combine: +)
array.insert(0, 4)
array.insert(0, atIndex: 4)
😫
Picky Compiler
SyntaxError Handling
Optionals
Incomplete

Generics
Argument

Naming
No

async/await
Value Types
for loops
😯
Expressive code
guard.map().reduce()
Optionals
defer
Associated

Types
Protocols
typedef

Everything
enums
ClosuresValue Semantics
A CONVENTION-CREATING KEYWORD
GUARD
func multipleOf(factor: Int) -> Int -> Bool {
return { (number: Int) in number % factor == 0 }
}
A CONVENTION-CREATING KEYWORD
GUARD
func multipleOf(factor: Int) -> Int -> Bool {
guard factor != 0 else { return { _ in false } }
return { (number: Int) in number % factor == 0 }
}
😯
Expressive code
guard.map().reduce()
Optionals
defer
Associated

Types
Protocols
typedef

Everything
enums
ClosuresValue Semantics
😍
Object-Oriented

Programming
Functional

Programming
Protocol-Oriented

Programming
THINK SHARP,
WRITE SWIFT
THINK SWIFT
THANK YOU 💙
Pascal Batty
@scalbatty
scalbatty
blog.soat.fr https://github.com/scalbatty/Think-Sharp-Write-Swift

Think sharp, write swift

  • 1.
    THINK SHARP, WRITESWIFT PASCAL BATTY
  • 2.
  • 3.
  • 6.
    I SAW ALOT OF PEOPLE SWITCHING
  • 7.
  • 8.
    BASED ON SCIENTIFICRESULTS THE STAGES OF SWITCHING 😫 😯 😍
  • 9.
  • 10.
    C# Swift Object Oriented✓ ✓ Type Inference ✓ ✓ Generics ✓ ✓ Tuples ✓ ✓ Lambdas ✓ ✓ Optional Chaining ✓ ✓ String Interpolation ✓ ✓ SWIFT VS C# FEATURE COMPARISON CHART
  • 11.
    String Interpolation ✓✓ Operator overloading ✓ ✓ Null Coalescing ✓ ✓ Variadic Parameters ✓ ✓ Optional Parameters ✓ ✓ Extensions ✓ ✓ Auto-Properties ✓ ✓ Try/Catch ✓ ✓ Cool Logo ✓
  • 12.
    THE GOOD OLDFIBONACCI SEQUENCE LET’S COMPARE CODE func fib(n: Int) -> Int { var fib0 = 0, fib1 = 1 for var i = 2; i <= n; i++ { var tmp = fib0 fib0 = fib1 fib1 = tmp + fib1 } return n > 0 ? fib1 : 0 } static int fib(int n) { int fib0 = 0, fib1 = 1; for (int i = 2; i <= n; i++) { int tmp = fib0; fib0 = fib1; fib1 = tmp + fib1; } return (n > 0 ? fib1 : 0); } C# Swift as found on Wikibooks
  • 13.
    SWIFT AND C# AREVERY SIMILAR
  • 14.
    C# Swift Garbage CollectionReference Counting Interface Protocol Constructor Initializer const let Linq MapReduce Lambda Closure func<> -> SWIFT AND C# ARE KINDA SORTA SIMILAR
  • 15.
    THE GOOD OLDFIBONACCI SEQUENCE A FEW ADJUSTMENTS func fib(n: Int) -> Int { var fib0 = 0, fib1 = 1 for var i = 2; i <= n; i++ { var tmp = fib0 fib0 = fib1 fib1 = tmp + fib1 } return n > 0 ? fib1 : 0 } Variable was never mutated; consider changing to ‘let’ constant
  • 16.
    THE GOOD OLDFIBONACCI SEQUENCE A FEW ADJUSTMENTS func fib(n: Int) -> Int { var fib0 = 0, fib1 = 1 for var i = 2; i <= n; i++ { let tmp = fib0 fib0 = fib1 fib1 = tmp + fib1 } return n > 0 ? fib1 : 0 } ++ is deprecated: it will be removed in Swift 3
  • 17.
    THE GOOD OLDFIBONACCI SEQUENCE A FEW ADJUSTMENTS func fib(n: Int) -> Int { var fib0 = 0, fib1 = 1 for var i = 2; i <= n; i += 1 { let tmp = fib0 fib0 = fib1 fib1 = tmp + fib1 } return n > 0 ? fib1 : 0 } C-Style for statement is deprecated and will be removed…
  • 18.
    THE GOOD OLDFIBONACCI SEQUENCE A FEW ADJUSTMENTS func fib(n: Int) -> Int { var fib0 = 0, fib1 = 1 for i in 2...n { let tmp = fib0 fib0 = fib1 fib1 = tmp + fib1 } return n > 0 ? fib1 : 0 } Immutable value ‘i’ was never used; consider replacing with ‘_’
  • 19.
    THE GOOD OLDFIBONACCI SEQUENCE A FEW ADJUSTMENTS func fib(n: Int) -> Int { var fib0 = 0, fib1 = 1 for _ in 2...n { let tmp = fib0 fib0 = fib1 fib1 = tmp + fib1 } return n > 0 ? fib1 : 0 } 😌
  • 20.
  • 21.
  • 22.
    LET US DIVEIN A LITTLE DEEPER BUILDING BLOCKS Class Properties Initializers Instance Methods Class Methods Struct Properties Initializers Instance methods Static methods Enum Properties Initializers Instance methods Static methods
  • 23.
  • 24.
    I CAN’T ASKYOU TO JUST BELIEVE ME ON THIS VALUE TYPES ARE AWESOME ▸ Immutability ensured by ‘let’ ▸ No expensive boxing/unboxing ▸ Code is more thread-safe ▸ Performance is better ▸ Functional Programming is more convenient
  • 25.
    LET US DIVEIN A LITTLE DEEPER STANDARD TYPES ▸ Int, Float, Double ▸ Bool ▸ String, Character ▸ Array<T>, Dictionary<K: Hashable, V>, Set<T: Hashable> THESE ARE ALL STRUCTS!
  • 26.
    ENUMERABLES YOU WON’T BELIEVEWHAT HAPPENS NEXT…
  • 27.
    BRACE YOURSELVES… ENUMERABLES ASYOU MAY KNOW THEM enum Land { case Forest case Mountain case Swamp case Plains case Island } enum Error : Int { case NotFound = 404 case ServerError = 500 case Forbidden = 403 case Teapot = 418 } Raw value can be String, Character or any numeric type
  • 28.
    HERE COMES! ENUMERABLES WITHASSOCIATED VALUES! enum PaymentMethod { case Cash case Check (Int) case CreditCard (CardType, Int) enum CardType { case Visa, MasterCard, Electron } func display() { switch self { case Cash: print("Paid by cash") case let Check(number): print("Paid by check #(number)") case let CreditCard(type, number): print("Paid by (type) #(number)") } } } let method = PaymentMethod.CreditCard(.Visa, 995423) method.display()
  • 29.
    NOT OVER YET! …AND GENERICS! enum Result<T, U> { case Success(T) case Error(U) } enum Optional<T> { case Some(T) case None } indirect enum Tree<T> { case Empty case Node(T, left: Tree<T>, right: Tree<T>) }
  • 30.
  • 31.
    WHAT YOU MAYEND UP DOING… OPTIONALS IN THE WILD let answer: String = "42" let numericAnswer = Int(answer) let byOneThousand = numericAnswer * 1000 let nineThousand: Float = 9 * 1000 let vegetaSays: String = "It's over (nineThousand) !!" let nappaSays: String = "What!? " + String(nineThousand) + "?!" VALUE OF OPTIONAL TYPE ‘INT?’ NOT UNWRAPPED; DID YOU MEAN TO USE ‘!’ OR ‘?’ ? Int?
  • 32.
    BEAR WITH METHERE OPTIONALS ▸ Like nullables for all types! ▸ Variables, constants, arguments, properties or return values ▸ You can’t use its value unless you unwrap it first ▸ If it is not Optional, it can never be nil
  • 33.
    FORGOT TO CHECKNULLABILITY? WON’T LET YOU USE THE VALUE
  • 34.
    DO YOU KNOWTHE ‘MAYBE’ MONAD ? UNWRAPPING THE OPTIONAL 42 let answer: String = getAnswer() let numericAnswer: Int? = Int(answer) processNumericAnswer(numericAnswer) ??? Int? Int nil
  • 35.
    DO YOU KNOWTHE ‘MAYBE’ MONAD ? UNWRAPPING THE OPTIONAL 42 let answer: String = getAnswer() let numericAnswer: Int? = Int(answer) if let realAnswer: Int = numericAnswer { processNumericAnswer(realAnswer) } else { print("Please give a number") } nil Int?Int?
  • 36.
    NOT EVERYTHING ISCOMPULSORY OPTIONAL PROPERTIES struct Contact { var firstName:String var middleName:String? var lastName:String var emailAddress:String var emailVerified:Bool }
  • 37.
    THAT’S A LOTOF PUNCTUATION! NULL COALESCING AND OPTIONAL CHAINING let answer: String = getAnswer() let numericAnswer: Int? = Int(answer) let sanitizedAnswer: Int = numericAnswer ?? 1 processNumericAnswer(sanitizedAnswer) let contact: Contact? = getContact() let email: String? = contact?.emailAddress ?? ?.
  • 38.
    FAMOUS LAST WORDS… FORCEUNWRAP & IMPLICITLY UNWRAPPED OPTIONALS ! « I KNOW WHAT I’M DOING. IF YOU ENCOUNTER AN UNEXPECTED NIL JUST CRASH AT RUNTIME »
  • 39.
  • 40.
    PUT SOME LOGICINSIDE YOUR TYPES! FUN WITH PROPERTIES struct Contact { var firstName: String var middleName: String? var lastName: String let securityNumber: Int var fullName: String { if let initial = middleName?.characters.first { return "(firstName) (initial). (lastName)" } else { return "(firstName) (lastName)" } } var emailVerified: Bool var emailAddress: String { didSet { emailVerified = false } } }
  • 41.
    MAP, FILTER, REDUCE,SORT CLOSURES let people:[Contact] = getContacts() let targetNames:[String] = people .filter({ contact in contact.lastName.hasPrefix("G") }) .map({ contact in contact.fullName }) .sort() func multipleOf(factor: Int) -> Int -> Bool { return { (number: Int) in number % factor == 0 } } let isEven = multipleOf(2) isEven(4) // Get the sum of multiples of 3 up to 100 (1...100) .filter(multipleOf(3)) .reduce(0, combine: +) https://github.com/mythz/swift-linq-examples
  • 42.
  • 43.
    IMAGINE THE POSSIBILITIES… EXTENSIONS& PROTOCOLS extension Contact { func composeEmailBoilerplate() -> String { … } var abbreviatedName: String { … } } protocol StringSerializable { func serialize() -> String } extension StringSerializable { func serialize() -> String { return "" } } extension Contact: StringSerializable { func serialize() -> String { … } }
  • 44.
  • 45.
  • 46.
    YOU’VE GOT TOSTART SOMEWHERE YOUR LEARNING ENVIRONMENT OS X Ubuntu Windows Xcode
 Playground REPL Ubuntu
 Bash
  • 47.
    WHEREVER YOU ARE SWIFTSANDBOX https://swiftlang.ng.bluemix.net
  • 48.
    ONE OF THEPERKS OF DOING SWIFT ON THE MAC PLAYGROUND
  • 49.
    BECAUSE WE DON’THAVE THE TIME TO SEE EVERYTHING LEARN ▸ Updated eBook from Apple ▸ Available for free ▸ on iBooks ▸ on swift.org ▸ swiftdoc.org is a nice and fast documentation website
  • 50.
  • 51.
  • 52.
    A POLARIZING ASPECT ARGUMENTNAMING (1...100) .filter(multipleOf(3)) .reduce(0, combine: +) array.insert(0, 4) array.insert(0, atIndex: 4)
  • 53.
  • 54.
  • 55.
    A CONVENTION-CREATING KEYWORD GUARD funcmultipleOf(factor: Int) -> Int -> Bool { return { (number: Int) in number % factor == 0 } }
  • 56.
    A CONVENTION-CREATING KEYWORD GUARD funcmultipleOf(factor: Int) -> Int -> Bool { guard factor != 0 else { return { _ in false } } return { (number: Int) in number % factor == 0 } }
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
    THANK YOU 💙 PascalBatty @scalbatty scalbatty blog.soat.fr https://github.com/scalbatty/Think-Sharp-Write-Swift