Swift Thinking
@NatashaTheRobot
Back to December
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
println("Hello, World!")
—Optionals?!
—Value Types
—Higher-order functions
Optionals?!
"~40% of bugs shipped to
customers in the last
three years would have
been caught immediately
by using Swift" - Sunset
Lake Software
enum Optional<T> {
case Some(T)
case None
}
let tSwiftAlbums = [
2014 : "1989",
2012: "Red",
2010: "Speak Now",
2008: "Fearless",
2006: "Taylor Swift"]
let possibleAlbumFrom2011: String? = tSwiftAlbums[2011]
let possibleAlbumFrom2014: String? = tSwiftAlbums[2014]
let tSwiftAlbums = [
2014 : "1989",
2012: "Red",
2010: "Speak Now",
2008: "Fearless",
2006: "Taylor Swift"]
let possibleAlbumFrom2014: String? = tSwiftAlbums[2014]
if possibleAlbumFrom2014 == .None {
println("Taylor Swift had no albums in 2014")
} else {
let albumFrom2014 = possibleAlbumFrom2014!
println("Taylor Swift's 2014 album was (albumFrom2014)")
}
let tSwiftAlbums = [
2014 : "1989",
2012: "Red",
2010: "Speak Now",
2008: "Fearless",
2006: "Taylor Swift"]
if let albumFor2014 = tSwiftAlbums[2014] {
println("Taylor Swift's 2014 album was (albumFor2014)")
} else {
println("Taylor Swift had no albums in 2014")
}
Value Types
—structs
—enums
—(tuples)
class Album {
let title: String
let artist: String
var copiesSold: Int
init(title: String, artist: String, copiesSold: Int) {
self.title = title
self.artist = artist
self.copiesSold = copiesSold
}
}
let tSwift1989 = Album(title: "1989",
artist: "Taylor Swift",
copiesSold: 4505000)
func another1000Sales(forAlbum album: Album) {
album.copiesSold += 1000
}
another1000Sales(forAlbum: tSwift1989)
tSwift1989.copiesSold // 4,506,000
struct Album {
let title: String
let artist: String
var copiesSold: Int
}
let tSwift1989 = Album(title: "1989",
artist: "Taylor Swift",
copiesSold: 4505000)
func another1000Sales(var forAlbum album: Album) {
album.copiesSold += 1000
album.copiesSold // 4,506,000
}
another1000Sales(forAlbum: tSwift1989)
tSwift1989.copiesSold // 4,505,000
Use a value type when:
—Comparing instance data with == makes sense
—You want copies to have independent state
—The data will be used in code across multiple
threads
Swift Blog: Value and Reference Types
Use a reference type (e.g. use a class) when:
—Comparing instance identity with == makes sense
—You want to create shared, mutable state
Swift Blog: Value and Reference Types
"Almost all types in Swift are value
types, including arrays,
dictionaries, numbers, booleans,
tuples, and enums. Classes are the
exception rather than the rule." -
Functional Swift Book
$ grep -e "^struct " swift.md | wc -l
81
$ grep -e "^enum " swift.md | wc -l
8
$ grep -e "^class " swift.md | wc -l
3
Higher-order Functions
a higher-order function is a function that does at
least one of the following:
—takes one or more functions as an input
—outputs a function
- Wikipedia
Array
—map
—reduce
—filter
—flatMap
struct Song {
let title: String
let album: String
}
let tSwiftSongs = [
Song(title: "Blank Space", album: "1989"),
Song(title: "All You Had to Do Was Stay", album: "Red"),
Song(title: "Back to December", album: "Speak Now"),
Song(title: "All You Had to Do Was Stay", album: "1989"),
Song(title: "Begin Again", album: "Red"),
Song(title: "Clean", album: "1989"),
Song(title: "Love Story", album: "Fearless"),
Song(title: "Shake It Off", album: "1989"),
Song(title: "Bad Blood", album: "1989")
]
struct tSwift1989Album {
let title = "1989"
var songs = [Song]()
}
class tSwift1989Album {
let title = "1989"
var songs = [Song]()
func add1989Songs() {
for song in tSwiftSongs {
if song.album == "1989" {
songs.append(song)
}
}
}
}
let album = tSwift1989Album()
album.add1989Songs()
album.songs.count // 5
let album = tSwift1989Album()
album.add1989Songs()
album.songs.count // 5
// MUCH FURTHER DOWN
album.add1989Songs()
let album = tSwift1989Album()
album.add1989Songs()
album.songs.count // 5
// MUCH FURTHER DOWN
album.add1989Songs()
album.songs.count // 10
let album = tSwift1989Album()
album.add1989Songs()
album.songs.count // 5
album.add1989Songs()
album.songs.count // 10
album.add1989Songs()
album.songs.count // 15
album.add1989Songs()
album.songs.count // 20
/// Return an `Array` containing the elements `x` of `self` for which
/// `includeElement(x)` is `true`
func filter(includeElement: (T) -> Bool) -> [T]
class tSwift1989Album {
let title = "1989"
var songs = [Song]()
func add1989SongsWithFilter() {
songs = tSwiftSongs.filter({ song in song.album == "1989"})
}
}
songs = tSwiftSongs.filter({ song in song.album == "1989"})
songs = tSwiftSongs.filter({ song in song.album == "1989"})
songs = tSwiftSongs.filter({ $0.album == "1989"})
songs = tSwiftSongs.filter({ song in song.album == "1989"})
songs = tSwiftSongs.filter({ $0.album == "1989"})
songs = tSwiftSongs.filter { $0.album == "1989"}
let album = tSwift1989Album()
album.add1989SongsWithFilter()
album.songs.count // 5
album.add1989SongsWithFilter()
album.songs.count // 5
album.add1989SongsWithFilter()
album.songs.count // 5
album.add1989SongsWithFilter()
album.songs.count // 5
album.add1989SongsWithFilter()
album.songs.count // 5
Swift Thinking
—Optionals?!
—Value Types
—Higher-order functions
Questions?!
@NatashaTheRobot

Swift Thinking

  • 1.
  • 2.
    Back to December #import<Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); } return 0; }
  • 3.
  • 8.
  • 9.
  • 10.
    "~40% of bugsshipped to customers in the last three years would have been caught immediately by using Swift" - Sunset Lake Software
  • 12.
    enum Optional<T> { caseSome(T) case None }
  • 13.
    let tSwiftAlbums =[ 2014 : "1989", 2012: "Red", 2010: "Speak Now", 2008: "Fearless", 2006: "Taylor Swift"] let possibleAlbumFrom2011: String? = tSwiftAlbums[2011] let possibleAlbumFrom2014: String? = tSwiftAlbums[2014]
  • 15.
    let tSwiftAlbums =[ 2014 : "1989", 2012: "Red", 2010: "Speak Now", 2008: "Fearless", 2006: "Taylor Swift"] let possibleAlbumFrom2014: String? = tSwiftAlbums[2014] if possibleAlbumFrom2014 == .None { println("Taylor Swift had no albums in 2014") } else { let albumFrom2014 = possibleAlbumFrom2014! println("Taylor Swift's 2014 album was (albumFrom2014)") }
  • 16.
    let tSwiftAlbums =[ 2014 : "1989", 2012: "Red", 2010: "Speak Now", 2008: "Fearless", 2006: "Taylor Swift"] if let albumFor2014 = tSwiftAlbums[2014] { println("Taylor Swift's 2014 album was (albumFor2014)") } else { println("Taylor Swift had no albums in 2014") }
  • 18.
  • 19.
  • 20.
    class Album { lettitle: String let artist: String var copiesSold: Int init(title: String, artist: String, copiesSold: Int) { self.title = title self.artist = artist self.copiesSold = copiesSold } }
  • 21.
    let tSwift1989 =Album(title: "1989", artist: "Taylor Swift", copiesSold: 4505000) func another1000Sales(forAlbum album: Album) { album.copiesSold += 1000 } another1000Sales(forAlbum: tSwift1989) tSwift1989.copiesSold // 4,506,000
  • 22.
    struct Album { lettitle: String let artist: String var copiesSold: Int }
  • 23.
    let tSwift1989 =Album(title: "1989", artist: "Taylor Swift", copiesSold: 4505000) func another1000Sales(var forAlbum album: Album) { album.copiesSold += 1000 album.copiesSold // 4,506,000 } another1000Sales(forAlbum: tSwift1989) tSwift1989.copiesSold // 4,505,000
  • 24.
    Use a valuetype when: —Comparing instance data with == makes sense —You want copies to have independent state —The data will be used in code across multiple threads Swift Blog: Value and Reference Types
  • 25.
    Use a referencetype (e.g. use a class) when: —Comparing instance identity with == makes sense —You want to create shared, mutable state Swift Blog: Value and Reference Types
  • 26.
    "Almost all typesin Swift are value types, including arrays, dictionaries, numbers, booleans, tuples, and enums. Classes are the exception rather than the rule." - Functional Swift Book
  • 27.
    $ grep -e"^struct " swift.md | wc -l 81 $ grep -e "^enum " swift.md | wc -l 8 $ grep -e "^class " swift.md | wc -l 3
  • 28.
  • 29.
    a higher-order functionis a function that does at least one of the following: —takes one or more functions as an input —outputs a function - Wikipedia
  • 30.
  • 31.
    struct Song { lettitle: String let album: String } let tSwiftSongs = [ Song(title: "Blank Space", album: "1989"), Song(title: "All You Had to Do Was Stay", album: "Red"), Song(title: "Back to December", album: "Speak Now"), Song(title: "All You Had to Do Was Stay", album: "1989"), Song(title: "Begin Again", album: "Red"), Song(title: "Clean", album: "1989"), Song(title: "Love Story", album: "Fearless"), Song(title: "Shake It Off", album: "1989"), Song(title: "Bad Blood", album: "1989") ]
  • 32.
    struct tSwift1989Album { lettitle = "1989" var songs = [Song]() }
  • 33.
    class tSwift1989Album { lettitle = "1989" var songs = [Song]() func add1989Songs() { for song in tSwiftSongs { if song.album == "1989" { songs.append(song) } } } }
  • 34.
    let album =tSwift1989Album() album.add1989Songs() album.songs.count // 5
  • 35.
    let album =tSwift1989Album() album.add1989Songs() album.songs.count // 5 // MUCH FURTHER DOWN album.add1989Songs()
  • 36.
    let album =tSwift1989Album() album.add1989Songs() album.songs.count // 5 // MUCH FURTHER DOWN album.add1989Songs() album.songs.count // 10
  • 37.
    let album =tSwift1989Album() album.add1989Songs() album.songs.count // 5 album.add1989Songs() album.songs.count // 10 album.add1989Songs() album.songs.count // 15 album.add1989Songs() album.songs.count // 20
  • 38.
    /// Return an`Array` containing the elements `x` of `self` for which /// `includeElement(x)` is `true` func filter(includeElement: (T) -> Bool) -> [T]
  • 39.
    class tSwift1989Album { lettitle = "1989" var songs = [Song]() func add1989SongsWithFilter() { songs = tSwiftSongs.filter({ song in song.album == "1989"}) } }
  • 40.
    songs = tSwiftSongs.filter({song in song.album == "1989"})
  • 41.
    songs = tSwiftSongs.filter({song in song.album == "1989"}) songs = tSwiftSongs.filter({ $0.album == "1989"})
  • 42.
    songs = tSwiftSongs.filter({song in song.album == "1989"}) songs = tSwiftSongs.filter({ $0.album == "1989"}) songs = tSwiftSongs.filter { $0.album == "1989"}
  • 43.
    let album =tSwift1989Album() album.add1989SongsWithFilter() album.songs.count // 5 album.add1989SongsWithFilter() album.songs.count // 5 album.add1989SongsWithFilter() album.songs.count // 5 album.add1989SongsWithFilter() album.songs.count // 5 album.add1989SongsWithFilter() album.songs.count // 5
  • 45.
  • 46.