Ra c
) /
ED D
(-) / ) -
G I ED D
E
var number = 100
mysteryJob()
print(number)
let number = 100
mysteryJob()
print(number)
D DI
var number = 100
mysteryJob()
print(number)
// ?
let number = 100
mysteryJob()
print(number)
// 100
mutable immutable
F
var condition: Bool = true
if condition {
// true
} else {
// false
}
let condition: Bool = true
// case true
mutable immutable
F
var condition: Bool = true
var condition2: Bool = false
if condition {
if condition2 {
// true && true
} else {
// true && false
}
} else {
if condition2 {
// false && true
} else {
// false && false
}
}
let condition: Bool = true
let condition2: Bool = false
// case true && false
mutable immutable
F
var condition: Bool = true
var condition2: Bool = false
var condition3: Bool = false
if condition {
if condition2 {
if condition3 {
// true && true && true
} else {
// true && true && false
}
} else {
if condition3 {
// true && false && true
} else {
// true && false && false
}
}
} else {
if condition2 {
if condition3 {
// false && true && true
} else {
// false && true && false
}
} else {
if condition3 {
// false && false && true
} else {
// false && false && false
}
}
}
let condition: Bool = true
let condition2: Bool = false
let condition2: Bool = false
// case true && false && false
mutable immutable
/ D
Data
Program Program Program Program
Data
Program Program Program Program
mutable immutable
D C
mutable immutable
struct Hero {
var name : String
var nickname: String
}
var hero = Hero(name: "Steve Rogers",
nickname: "Captain America")
print(hero)
//Hero(name: "Steve Rogers",
nickname: "Captain America")
hero.nickname = "First Avenger"
print(hero)
//Hero(name: "Steve Rogers",
nickname: "First Avengers")
struct Hero {
var name : String
var nickname: String
}
let hero = Hero(name: "Steve Rogers",
nickname: "Captain America")
print(hero)
//Hero(name: "Steve Rogers",
nickname: "Captain America")
let captain = Hero(name: hero.name,
nickname: "First Avenger")
print(hero)
//Hero(name: "Steve Rogers",
nickname: "Captain America")
print(captain)
//Hero(name: "Steve Rogers",
nickname: "First Avengers")
ED D
1. Predictable

2. Testability

3. Thread-Safe
Maintainable
}
4. Unfamiliar

5. Memory wasting

6. Low performance

( in some case )
ED FC ED D
Maintenance
Performance
vs
ECF EC EC
Data
feature
AI
struct Hero {
var name: String
var nickname: String
}
let hero = Hero(name: "Steve Rogers",
nickname: "Captain America")
var captain = hero
captain.nickname = "First Avenger" Copy On Write
HD C
protocol Mappable {
func map<U>(_ f: (Self) -> U) -> U
}
extension Mappable {
func map<U>(_ f: (Self) -> U) -> U {
return f(self)
}
}
extension Hero: Mappable { }
let hero = Hero(name: "Steve Rogers",
nickname: "Captain America")
let captain = hero.map { hero -> Hero in
var h = hero
h.nickname = "First Avenger"
return h
}
DD DD
extension Hero {
func get<Value>(_ kp: KeyPath<Hero, Value>) -> Value {
return self[keyPath: kp]
}
func set<Value>(_ kp: WritableKeyPath<Hero, Value>,
_ v: Value) -> Hero {
var h = self
h[keyPath: kp] = v
return h
}
}
let hero = Hero(name: "Steve Rogers",
nickname: "Captain America")
hero.get(.nickname)
//Captain America
let captain = hero.set(.nickname, "First Avenger")
C
struct Lens<Whole, Part> {
let get: (Whole) -> Part
let set: (Whole, Part) -> Whole
}
let heroNickNameLens: Lens<Hero, String> = Lens(
get: { $0.nickname },
set: {
var h = $0
h.nickname = $1
return h
}
)
let hero = Hero(name: "Steve Rogers",
nickname: "Captain America")
let captain = heroNickNameLens.set(hero, "First Avenger")
C
protocol Lensable {
static func lens<Part>(_ wkp: WritableKeyPath<Self, Part>) -> Lens<Self, Part>
}
extension Lensable {
static func lens<Part>(_ wkp: WritableKeyPath<Self, Part>) -> Lens<Self, Part> {
return Lens(
get: { whole in whole[keyPath: wkp] },
set: { whole, part in
var mutableWhole = whole
mutableWhole[keyPath: wkp] = part
return mutableWhole
}
)
}
}
extension Hero: Lensable {}
let hero = Hero(name: "Steve Rogers",
nickname: "Captain America")
let captain = Hero.lens(.nickname).set(hero, "First Avenger")
E D AD C
http://www.cs.ox.ac.uk/people/jeremy.gibbons/publications/poptics.pdf
https://github.com/hablapps/DontFearTheProfunctorOptics
feature
Data
E D
func valueChanger<T, U>(value: T, _ f: (T) -> U) -> U {
return f(value)
}
let name = "Original"
// Original
let changedName = valueChanger(value: name) { "($0) Changed" }
// Original Changed
E D
class Functor<T> {
let value: T
init(_ v: T) {
value = v
}
func map<U>(_ f: (T) -> U) -> Functor<U> {
let u = f(value)
return Functor<U>(u)
}
}
E D
let name = "Original" // Original
let changedName = Functor(name).map { "($0) Changed" }.value
// Original Changed
let changedNameLength = Functor(name) // Functor<String>
.map { "($0) Changed" } // Functor<String>
.map { $0.count } // Functor<Int>
.map { $0 * $0 } // Functor<Int>
.value // Int
// 256
E D
func stringLength(_ s: String) -> Functor<Int> {
return Functor(s).map { $0.count }
}
let name = "Original" // Original
let changedName = Functor(name).map { "($0) Changed" }.value
// Original Changed
let changedNameLength = Functor(name) // Functor<String>
.map { "($0) Changed" } // Functor<String>
.map (stringLength) // Functor<Functor<Int>>
.map { $0 * $0 }
.value
E D
func stringLength(_ s: String) -> Functor<Int> {
return Functor(s).map { $0.count }
}
let name = "Original" // Original
let changedName = Functor(name).map { "($0) Changed" }.value
// Original Changed
let changedNameLength = Functor(name) // Functor<String>
.map { "($0) Changed" } // Functor<String>
.map (stringLength) // Functor<Functor<Int>>
.map { $0 * $0 }
.value
Functor<Functor<Int>> 의 중첩된 것을 단일(Mono)하게 만들어야 함.
class Monad<T>: Functor<T> {
override func map<U>(_ f: (T) -> U) -> Monad<U> {
let cu = super.map(f)
return Monad<U>(cu.value)
}
func flatMap<U>(_ f: (T) -> Functor<U>) -> Monad<U> {
let fu = f(value)
return Monad<U>(fu.value)
}
}
func stringLength(_ s: String) -> Functor<Int> {
return Functor(s).map { $0.count }
}
let name = "Original" // Original
let changedName = Monad(name).map { "($0) Changed" }.value
// Original Changed
let changedNameLength = Monad(name) // Monad<String>
.map { "($0) Changed" } // Monad<String>
.flatMap (stringLength) // Monad<Int>
.map { $0 * $0 } // Monad<Int>
.value // Int
//256
E I
Immutable data 는 변하지 않는 값
f
g = f - ) -
b df - )
-) ).-
e f P
map / flatMap
Data
get / set
유지보수하기 좋다
20190330 immutable data

20190330 immutable data

  • 1.
    Ra c ) / EDD (-) / ) -
  • 2.
  • 3.
    E var number =100 mysteryJob() print(number) let number = 100 mysteryJob() print(number)
  • 4.
    D DI var number= 100 mysteryJob() print(number) // ? let number = 100 mysteryJob() print(number) // 100 mutable immutable
  • 5.
    F var condition: Bool= true if condition { // true } else { // false } let condition: Bool = true // case true mutable immutable
  • 6.
    F var condition: Bool= true var condition2: Bool = false if condition { if condition2 { // true && true } else { // true && false } } else { if condition2 { // false && true } else { // false && false } } let condition: Bool = true let condition2: Bool = false // case true && false mutable immutable
  • 7.
    F var condition: Bool= true var condition2: Bool = false var condition3: Bool = false if condition { if condition2 { if condition3 { // true && true && true } else { // true && true && false } } else { if condition3 { // true && false && true } else { // true && false && false } } } else { if condition2 { if condition3 { // false && true && true } else { // false && true && false } } else { if condition3 { // false && false && true } else { // false && false && false } } } let condition: Bool = true let condition2: Bool = false let condition2: Bool = false // case true && false && false mutable immutable
  • 8.
    / D Data Program ProgramProgram Program Data Program Program Program Program mutable immutable
  • 9.
    D C mutable immutable structHero { var name : String var nickname: String } var hero = Hero(name: "Steve Rogers", nickname: "Captain America") print(hero) //Hero(name: "Steve Rogers", nickname: "Captain America") hero.nickname = "First Avenger" print(hero) //Hero(name: "Steve Rogers", nickname: "First Avengers") struct Hero { var name : String var nickname: String } let hero = Hero(name: "Steve Rogers", nickname: "Captain America") print(hero) //Hero(name: "Steve Rogers", nickname: "Captain America") let captain = Hero(name: hero.name, nickname: "First Avenger") print(hero) //Hero(name: "Steve Rogers", nickname: "Captain America") print(captain) //Hero(name: "Steve Rogers", nickname: "First Avengers")
  • 10.
    ED D 1. Predictable 2.Testability 3. Thread-Safe Maintainable } 4. Unfamiliar 5. Memory wasting 6. Low performance ( in some case )
  • 11.
    ED FC EDD Maintenance Performance vs
  • 12.
  • 13.
  • 14.
    AI struct Hero { varname: String var nickname: String } let hero = Hero(name: "Steve Rogers", nickname: "Captain America") var captain = hero captain.nickname = "First Avenger" Copy On Write
  • 15.
    HD C protocol Mappable{ func map<U>(_ f: (Self) -> U) -> U } extension Mappable { func map<U>(_ f: (Self) -> U) -> U { return f(self) } } extension Hero: Mappable { } let hero = Hero(name: "Steve Rogers", nickname: "Captain America") let captain = hero.map { hero -> Hero in var h = hero h.nickname = "First Avenger" return h }
  • 16.
    DD DD extension Hero{ func get<Value>(_ kp: KeyPath<Hero, Value>) -> Value { return self[keyPath: kp] } func set<Value>(_ kp: WritableKeyPath<Hero, Value>, _ v: Value) -> Hero { var h = self h[keyPath: kp] = v return h } } let hero = Hero(name: "Steve Rogers", nickname: "Captain America") hero.get(.nickname) //Captain America let captain = hero.set(.nickname, "First Avenger")
  • 17.
    C struct Lens<Whole, Part>{ let get: (Whole) -> Part let set: (Whole, Part) -> Whole } let heroNickNameLens: Lens<Hero, String> = Lens( get: { $0.nickname }, set: { var h = $0 h.nickname = $1 return h } ) let hero = Hero(name: "Steve Rogers", nickname: "Captain America") let captain = heroNickNameLens.set(hero, "First Avenger")
  • 18.
    C protocol Lensable { staticfunc lens<Part>(_ wkp: WritableKeyPath<Self, Part>) -> Lens<Self, Part> } extension Lensable { static func lens<Part>(_ wkp: WritableKeyPath<Self, Part>) -> Lens<Self, Part> { return Lens( get: { whole in whole[keyPath: wkp] }, set: { whole, part in var mutableWhole = whole mutableWhole[keyPath: wkp] = part return mutableWhole } ) } } extension Hero: Lensable {} let hero = Hero(name: "Steve Rogers", nickname: "Captain America") let captain = Hero.lens(.nickname).set(hero, "First Avenger")
  • 19.
    E D ADC http://www.cs.ox.ac.uk/people/jeremy.gibbons/publications/poptics.pdf https://github.com/hablapps/DontFearTheProfunctorOptics
  • 20.
  • 21.
    E D func valueChanger<T,U>(value: T, _ f: (T) -> U) -> U { return f(value) } let name = "Original" // Original let changedName = valueChanger(value: name) { "($0) Changed" } // Original Changed
  • 22.
    E D class Functor<T>{ let value: T init(_ v: T) { value = v } func map<U>(_ f: (T) -> U) -> Functor<U> { let u = f(value) return Functor<U>(u) } }
  • 23.
    E D let name= "Original" // Original let changedName = Functor(name).map { "($0) Changed" }.value // Original Changed let changedNameLength = Functor(name) // Functor<String> .map { "($0) Changed" } // Functor<String> .map { $0.count } // Functor<Int> .map { $0 * $0 } // Functor<Int> .value // Int // 256
  • 24.
    E D func stringLength(_s: String) -> Functor<Int> { return Functor(s).map { $0.count } } let name = "Original" // Original let changedName = Functor(name).map { "($0) Changed" }.value // Original Changed let changedNameLength = Functor(name) // Functor<String> .map { "($0) Changed" } // Functor<String> .map (stringLength) // Functor<Functor<Int>> .map { $0 * $0 } .value
  • 25.
    E D func stringLength(_s: String) -> Functor<Int> { return Functor(s).map { $0.count } } let name = "Original" // Original let changedName = Functor(name).map { "($0) Changed" }.value // Original Changed let changedNameLength = Functor(name) // Functor<String> .map { "($0) Changed" } // Functor<String> .map (stringLength) // Functor<Functor<Int>> .map { $0 * $0 } .value Functor<Functor<Int>> 의 중첩된 것을 단일(Mono)하게 만들어야 함.
  • 26.
    class Monad<T>: Functor<T>{ override func map<U>(_ f: (T) -> U) -> Monad<U> { let cu = super.map(f) return Monad<U>(cu.value) } func flatMap<U>(_ f: (T) -> Functor<U>) -> Monad<U> { let fu = f(value) return Monad<U>(fu.value) } }
  • 27.
    func stringLength(_ s:String) -> Functor<Int> { return Functor(s).map { $0.count } } let name = "Original" // Original let changedName = Monad(name).map { "($0) Changed" }.value // Original Changed let changedNameLength = Monad(name) // Monad<String> .map { "($0) Changed" } // Monad<String> .flatMap (stringLength) // Monad<Int> .map { $0 * $0 } // Monad<Int> .value // Int //256
  • 28.
    E I Immutable data는 변하지 않는 값 f g = f - ) - b df - ) -) ).- e f P map / flatMap Data get / set 유지보수하기 좋다