正格評価・遅延評価
30Ⓒ Classmethod, Inc.
•正格評価(strict evaluation) とは?
評価結果が使用されるタイミングに関係なく
即時に行われる評価のこと
func add(a: Int, _ b: Int) -> Int {
return a + b
}
struct Component {
let c = add(1, 1)
}
Swift code
31.
正格評価・遅延評価
31Ⓒ Classmethod, Inc.
•正格評価(strict evaluation) とは?
評価結果が使用されるタイミングに関係なく
即時に行われる評価のこと
func add(a: Int, _ b: Int) -> Int {
return a + b
}
struct Component {
let c = add(1, 1)
}
cが用いられるタイミングに関係なく
インスタンス生成時に評価される
Swift code
32.
正格評価・遅延評価
32Ⓒ Classmethod, Inc.
•遅延評価(strict evaluation) とは?
即時に行われず、後々必要になったタイミングで
行われる評価のこと
func add(a: Int, _ b: Int) -> Int {
return a + b
}
struct LazyComponent {
lazy var d = add(1, 2)
}
Swift code
33.
正格評価・遅延評価
33Ⓒ Classmethod, Inc.
•遅延評価(strict evaluation) とは?
即時に行われず、後々必要になったタイミングで
行われる評価のこと
func add(a: Int, _ b: Int) -> Int {
return a + b
}
struct LazyComponent {
lazy var d = add(1, 2)
} dが用いられるタイミングで評価される
Swift code
lazy修飾子(Scala)
35Ⓒ Classmethod, Inc.
•lazyをval(定数)の前につけると遅延評価になる
object LazyConstants {
lazy val const: String = {
println("computed")
"constant"
}
}
val a = LazyConstants.const
Scala code
36.
lazy修飾子(Scala)
36Ⓒ Classmethod, Inc.
•lazyをval(定数)の前につけると遅延評価になる
object LazyConstants {
lazy val const: String = {
println("computed")
"constant"
}
}
val a = LazyConstants.const
Scala code
宣言時には評価されない
37.
lazy修飾子(Scala)
37Ⓒ Classmethod, Inc.
•lazyをval(定数)の前につけると遅延評価になる
object LazyConstants {
lazy val const: String = {
println("computed")
"constant"
}
}
val a = LazyConstants.const
Scala code
宣言時には評価されない
アクセス時に評価され、
computed が出力される
38.
lazy修飾子(Swift)
38Ⓒ Classmethod, Inc.
•lazyをvar(変数)の前につけると遅延評価になる
class LazyConstants {
lazy var const: String = {
print("computed")
return "constant"
}()
}
let constants = LazyConstants()
let const = constants.const
Swift code
39.
lazy修飾子(Swift)
39Ⓒ Classmethod, Inc.
•lazyをvar(変数)の前につけると遅延評価になる
class LazyConstants {
lazy var const: String = {
print("computed")
return "constant"
}()
}
let constants = LazyConstants()
let const = constants.const
Swift code
インスタンス生成時には評価されない
40.
lazy修飾子(Swift)
40Ⓒ Classmethod, Inc.
•lazyをvar(変数)の前につけると遅延評価になる
class LazyConstants {
lazy var const: String = {
print("computed")
return "constant"
}()
}
let constants = LazyConstants()
let const = constants.const
Swift code
インスタンス生成時には評価されない
プロパティアクセス時に評価され、
computed が出力される
41.
lazy修飾子(Swift)
41Ⓒ Classmethod, Inc.
•グローバル変数、定数はlazy修飾子をつけなくても
自動的に遅延評価になる
let someConst: String = {
print("computed")
return "constant"
}()
let length = someConst.utf8.count
Swift code
42.
lazy修飾子(Swift)
42Ⓒ Classmethod, Inc.
•グローバル変数、定数はlazy修飾子をつけなくても
自動的に遅延評価になる
let someConst: String = {
print("computed")
return "constant"
}()
let length = someConst.utf8.count
Swift code
この時点では評価されない
43.
lazy修飾子(Swift)
43Ⓒ Classmethod, Inc.
•グローバル変数、定数はlazy修飾子をつけなくても
自動的に遅延評価になる
let someConst: String = {
print("computed")
return "constant"
}()
let length = someConst.utf8.count
Swift code
この時点では評価されない
アクセス時に評価され、
computed が出力される
遅延コレクション(Scala)
52Ⓒ Classmethod, Inc.
•ビューはmap, filter等の変換メソッド処理を
遅延するコレクションを提供する
val vectorView = Vector(1 to 5: _*).view
val middleView =
vectorView.map { x => println(x); x * 2 }
middleView.map { _ + 3 }.force
Scala code
53.
遅延コレクション(Scala)
53Ⓒ Classmethod, Inc.
•ビューはmap, filter等の変換メソッド処理を
遅延するコレクションを提供する
val vectorView = Vector(1 to 5: _*).view
val middleView =
vectorView.map { x => println(x); x * 2 }
middleView.map { _ + 3 }.force
Scala code
遅延コレクション生成
54.
遅延コレクション(Scala)
54Ⓒ Classmethod, Inc.
•ビューはmap, filter等の変換メソッド処理を
遅延するコレクションを提供する
val vectorView = Vector(1 to 5: _*).view
val middleView =
vectorView.map { x => println(x); x * 2 }
middleView.map { _ + 3 }.force
Scala code
遅延コレクション生成
この時点では中の処理は実施されず
中間のVectorも作成されない
55.
遅延コレクション(Scala)
55Ⓒ Classmethod, Inc.
•ビューはmap, filter等の変換メソッド処理を
遅延するコレクションを提供する
val vectorView = Vector(1 to 5: _*).view
val middleView =
vectorView.map { x => println(x); x * 2 }
middleView.map { _ + 3 }.force
Scala codeforceメソッドで正格コレクションに戻され、
それまでの変換メソッド処理が実施される。
(1 2 3 4 5が出力される)
遅延コレクション生成
この時点では中の処理は実施されず
中間のVectorも作成されない
56.
遅延コレクション(Swift 2.x)
56Ⓒ Classmethod,Inc.
• LazySequenceプロトコルはmap, filter等の変換
メソッド処理を遅延するコレクションを提供する
let lazyArr = [1,2,3,4,5].lazy
let middleArr = lazyArr.map { x -> Int in
print(x); return x * 2
}
let endArr = middleArr.map { x in x + 3 }
for _ in endArr { }
Swift code
57.
遅延コレクション(Swift 2.x)
57Ⓒ Classmethod,Inc.
• LazySequenceプロトコルはmap, filter等の変換
メソッド処理を遅延するコレクションを提供する
let lazyArr = [1,2,3,4,5].lazy
let middleArr = lazyArr.map { x -> Int in
print(x); return x * 2
}
let endArr = middleArr.map { x in x + 3 }
for _ in endArr { }
Swift code
遅延コレクション生成
58.
遅延コレクション(Swift 2.x)
58Ⓒ Classmethod,Inc.
• LazySequenceプロトコルはmap, filter等の変換
メソッド処理を遅延するコレクションを提供する
let lazyArr = [1,2,3,4,5].lazy
let middleArr = lazyArr.map { x -> Int in
print(x); return x * 2
}
let endArr = middleArr.map { x in x + 3 }
for _ in endArr { }
Swift code
遅延コレクション生成
この時点では中の処理は
実施されず、中間のArrayも作成されない
59.
遅延コレクション(Swift 2.x)
59Ⓒ Classmethod,Inc.
• LazySequenceプロトコルはmap, filter等の変換
メソッド処理を遅延するコレクションを提供する
let lazyArr = [1,2,3,4,5].lazy
let middleArr = lazyArr.map { x -> Int in
print(x); return x * 2
}
let endArr = middleArr.map { x in x + 3 }
for _ in endArr { }
Swift code
必要になった時にそれまでの変換メソッド処理が実施される。
(1 2 3 4 5が出力される)
遅延コレクション生成
この時点では中の処理は
実施されず、中間のArrayも作成されない
リスコフ置換原則
63Ⓒ Classmethod, Inc.
•リスコフ置換原則
Let Φ(x) be a property provable about
objects x of type T. Then Φ(y) should be true
for objects y of type S where S is a subtype
of T.
Liskov, and Wing(1993) A Behavioral Notion of Subtyping
共変・反変
86Ⓒ Classmethod, Inc.
•共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
反変型引数 共変型引数
↓ ↑
T
S
U
V
TはSの派生型 VはUの派生型
87.
共変・反変
87Ⓒ Classmethod, Inc.
•共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
反変型引数 共変型引数
↓ ↑↑
T
S
U
V
TはSの派生型 VはUの派生型
[反変S, 共変V]は[反変T, 共変U]の派生型
88.
共変・反変
88Ⓒ Classmethod, Inc.
•共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
→共変型引数については派生順序を保持、
反変型引数については派生順序を逆転
反変型引数 共変型引数
↓ ↑↑
T
S
U
V
TはSの派生型 VはUの派生型
[反変S, 共変V]は[反変T, 共変U]の派生型
共変(Swift)
97Ⓒ Classmethod, Inc.
•Array<T>はTについて共変
struct Array<T> …
var anyArray: [Any] = []
let intArray: [Int] = [2, 3, 4]
anyArray = intArray
Swift code
98.
共変(Swift)
98Ⓒ Classmethod, Inc.
•Array<T>はTについて共変
struct Array<T> …
var anyArray: [Any] = []
let intArray: [Int] = [2, 3, 4]
anyArray = intArray
Swift code
派生順序は Any > Int
99.
共変(Swift)
99Ⓒ Classmethod, Inc.
•Array<T>はTについて共変
struct Array<T> …
var anyArray: [Any] = []
let intArray: [Int] = [2, 3, 4]
anyArray = intArray
Swift code
派生順序は Any > Int
型引数の派生順序が保存され、
Array<Int> は Array<Any> の派生型として扱える
100.
共変(Swift)
100Ⓒ Classmethod, Inc.
•Array<T>はTについて共変
struct Array<T> …
var anyArray: [Any] = []
let intArray: [Int] = [2, 3, 4]
anyArray = intArray
Swift code
派生順序は Any > Int
型引数の派生順序が保存され、
Array<Int> は Array<Any> の派生型として扱える
将来共変を表すためのキーワードが入るかも?(憶測
反変(Scala)
102Ⓒ Classmethod, Inc.
•-を型引数の前につけると反変となる
class Consumer[-T] {
def consume(p: T) = {}
}
var anyConsumer: Consumer[Any] =
new Consumer[Any]()
var intConsumer: Consumer[Int] =
new Consumer[Int]()
intConsumer = anyConsumer
Scala code
103.
反変(Scala)
103Ⓒ Classmethod, Inc.
•-を型引数の前につけると反変となる
class Consumer[-T] {
def consume(p: T) = {}
}
var anyConsumer: Consumer[Any] =
new Consumer[Any]()
var intConsumer: Consumer[Int] =
new Consumer[Int]()
intConsumer = anyConsumer
Scala code
派生順序は Any > Int
104.
反変(Scala)
104Ⓒ Classmethod, Inc.
•-を型引数の前につけると反変となる
class Consumer[-T] {
def consume(p: T) = {}
}
var anyConsumer: Consumer[Any] =
new Consumer[Any]()
var intConsumer: Consumer[Int] =
new Consumer[Int]()
intConsumer = anyConsumer
Scala code
派生順序は Any > Int
型引数の派生順序が逆転、
Consumer[Any] は Consumer[Int]の派生型として扱える
反変(Swift 2.1)
113Ⓒ Classmethod,Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
testVariance(innerIntAny)
testVariance(innerAnyInt)
testVariance(innerAnyAny)
testVariance(innerIntInt)
Swift code
114.
反変(Swift 2.1)
114Ⓒ Classmethod,Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
testVariance(innerIntAny)
testVariance(innerAnyInt)
testVariance(innerAnyAny)
testVariance(innerIntInt)
Swift code
渡される関数の型は全て (Int) -> Any の派生型
115.
反変(Swift 2.1)
115Ⓒ Classmethod,Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
testVariance(innerIntAny)
testVariance(innerAnyInt)
testVariance(innerAnyAny)
testVariance(innerIntInt)
Swift code
将来反変を表すためのキーワードが入るかも?(憶測
渡される関数の型は全て (Int) -> Any の派生型