SlideShare a Scribd company logo
1 of 117
Download to read offline
Swift2.xを
Scalaから見る
1
安達 勇一
クラスメソッド株式会社
2015年11月11日
Ⓒ Classmethod, Inc.
2
安達 勇一
• 2013/12 入社

• TwitterID: @UsrNameu1

• Github: https://github.com/
UsrNameu1

• Blog: http://dev.classmethod.jp/
author/yad

• ここ半年はサーバーサイドメイン
Topics for today
• ミックスイン
• 正格評価・遅延評価
• 変位指定
3Ⓒ Classmethod, Inc.
Topics for today
• ミックスイン
• 正格評価・遅延評価
• 変位指定
4Ⓒ Classmethod, Inc.
ミックスイン
• ミックスイン
• 抽象インターフェイス
• デフォルト実装
• ミックスイン対象制限
5Ⓒ Classmethod, Inc.
ミックスイン
6Ⓒ Classmethod, Inc.
• ミックスイン(mix-in)とは?
クラスが「本来の型」に加えて、なんらかの任意の振
る舞いを提供していることを宣言するために、クラスが
実装する型
Bloch(2008)  Effective Java 2nd edition
ミックスイン
• ミックスイン
• 抽象インターフェイス
• デフォルト実装
• ミックスイン対象制限
7Ⓒ Classmethod, Inc.
抽象インターフェイス(Scala)
8Ⓒ Classmethod, Inc.
• traitは抽象インターフェイスをサポートしている
trait AbstractTrait {
type DataType
val constant: DataType
var variable: DataType
def method(): DataType
}
Scala code
抽象インターフェイス(Scala)
9Ⓒ Classmethod, Inc.
• traitは抽象インターフェイスをサポートしている
trait AbstractTrait {
type DataType
val constant: DataType
var variable: DataType
def method(): DataType
}
抽象型メンバー、定数、変数、メソッドが定義できる
Scala code
抽象インターフェイス(Swift)
10Ⓒ Classmethod, Inc.
• protocolは抽象インターフェイスをサポートしている
protocol AbstractProtocol {
typealias DataType
var constant: DataType { get }
var variable: DataType { get set }
func method() -> DataType
init(t: DataType)
subscript(i: Int) -> DataType { get }
func + (lhs: DataType, rhs: DataType)
-> DataType
}
Swift code
抽象インターフェイス(Swift)
11Ⓒ Classmethod, Inc.
• protocolは抽象インターフェイスをサポートしている
protocol AbstractProtocol {
typealias DataType
var constant: DataType { get }
var variable: DataType { get set }
func method() -> DataType
init(t: DataType)
subscript(i: Int) -> DataType { get }
func + (lhs: DataType, rhs: DataType)
-> DataType
} 抽象型メンバー、プロパティ、メソッド、イニシャライザ
サブスクリプト、演算子が定義できる
Swift code
ミックスイン
• ミックスイン
• 抽象インターフェイス
• デフォルト実装
• ミックスイン対象制限
12Ⓒ Classmethod, Inc.
デフォルト実装(Scala)
13Ⓒ Classmethod, Inc.
• traitはデフォルト実装をサポートしている
trait AbstractTrait {
type DataType = String
val constant: DataType = “aa”
var variable: DataType = “aaa”
def method(): DataType = { “aaaa” }
}
Scala code
デフォルト実装(Scala)
14Ⓒ Classmethod, Inc.
• traitはデフォルト実装をサポートしている
trait AbstractTrait {
type DataType = String
val constant: DataType = “aa”
var variable: DataType = “aaa”
def method(): DataType = { “aaaa” }
}
デフォルトの実装をtraitの各メンバーに対して定義できる
Scala code
デフォルト実装(Swift 2.x)
15Ⓒ Classmethod, Inc.
• protocol extensionはデフォルト実装をサポートしている
extension AbstractProtocol {
typealias DataType = String
var constant: DataType { return “a” }
func method() -> DataType { return “aa” }
}
Swift code
デフォルト実装(Swift 2.x)
16Ⓒ Classmethod, Inc.
• protocol extensionはデフォルト実装をサポートしている
extension AbstractProtocol {
typealias DataType = String
var constant: DataType { return “a” }
func method() -> DataType { return “aa” }
}
デフォルトの実装をprotocolの各メンバーに対して定義できる
Swift code
ミックスイン
• ミックスイン
• 抽象インターフェイス
• デフォルト実装
• ミックスイン対象制限
17Ⓒ Classmethod, Inc.
ミックスイン対象制限(Scala)
18Ⓒ Classmethod, Inc.
• traitは自分型アノテーションで継承の対象になる型を
限定できる
trait AbstractTrait {
self: SomeClass =>
def method(): String = { “aaaa” }
}
Scala code
ミックスイン対象制限(Scala)
19Ⓒ Classmethod, Inc.
• traitは自分型アノテーションで継承の対象になる型を
限定できる
trait AbstractTrait {
self: SomeClass =>
def method(): String = { “aaaa” }
}
Scala code
ミックスインの対象になる型をSomeClassに限定できる
→AbstractTraitはSomeClassと
 そのサブ型からしか継承できない
ミックスイン対象制限(Swift 2.x)
20Ⓒ Classmethod, Inc.
• protocol extensionのSelfへの制約によって
デフォルト実装が使える継承の対象となる型を制限できる
extension AbstractProtocol
where Self: SomeClass {
func method() -> String { return “aa” }
}
Swift code
ミックスイン対象制限(Swift 2.x)
21Ⓒ Classmethod, Inc.
• protocol extensionのSelfへの制約によって
デフォルト実装が使える継承の対象となる型を制限できる
extension AbstractProtocol
where Self: SomeClass {
func method() -> String { return “aa” }
}
デフォルトの実装を使える型はSomeClassとそのサブ型のみ
Swift code
ミックスイン対象制限(Swift 2.x)
22Ⓒ Classmethod, Inc.
• protocol extensionのSelfへの制約によって
デフォルト実装が使える継承の対象となる型を制限できる
extension AbstractProtocol
where Self: SomeClass {
func method() -> String { return “aa” }
}
デフォルトの実装を使える型はSomeClassとそのサブ型のみ
Swift code
See also→
http://www.slideshare.net/UsrNameu1/swift2-protocol-extension
ミックスインのまとめ
23Ⓒ Classmethod, Inc.
Scala Swift
抽象インターフェイス
デフォルト実装
ミックスイン対象型への制約
trait protocol
trait protocol extension
traitでの
自分型アノテーション
protocol extensionでの
Self への制約
Topics for today
• ミックスイン
• 正格評価・遅延評価
• 変位指定
24Ⓒ Classmethod, Inc.
正格評価・
遅延評価
• 正格評価・遅延評価
• lazy修飾子
• 遅延引数
• 遅延コレクション
25Ⓒ Classmethod, Inc.
正格評価・遅延評価
26Ⓒ Classmethod, Inc.
• 評価(evaluation) とは?
式から値を計算し、取り出す操作
正格評価・遅延評価
27Ⓒ Classmethod, Inc.
• 評価(evaluation) とは?
式から値を計算し、取り出す操作
let a = 1 + 1
Swift code
正格評価・遅延評価
28Ⓒ Classmethod, Inc.
• 評価(evaluation) とは?
式から値を計算し、取り出す操作
let a = 1 + 1
1 + 1という式から2を計算し、取り出す
Swift code
正格評価・遅延評価
29Ⓒ Classmethod, Inc.
• 評価(evaluation) とは?
式から値を計算し、取り出す操作
let a = 1 + 1
1 + 1という式から2を計算し、取り出す
a という名前の定数に代入する
Swift code
正格評価・遅延評価
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Ⓒ 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Ⓒ 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Ⓒ 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修飾子
• 遅延引数
• 遅延コレクション
34Ⓒ Classmethod, Inc.
lazy修飾子(Scala)
35Ⓒ Classmethod, Inc.
• lazyをval(定数)の前につけると遅延評価になる
 
object LazyConstants {
lazy val const: String = {
println("computed")
"constant"
}
}
val a = LazyConstants.const
Scala code
lazy修飾子(Scala)
36Ⓒ Classmethod, Inc.
• lazyをval(定数)の前につけると遅延評価になる
 
object LazyConstants {
lazy val const: String = {
println("computed")
"constant"
}
}
val a = LazyConstants.const
Scala code
宣言時には評価されない
lazy修飾子(Scala)
37Ⓒ Classmethod, Inc.
• lazyをval(定数)の前につけると遅延評価になる
 
object LazyConstants {
lazy val const: String = {
println("computed")
"constant"
}
}
val a = LazyConstants.const
Scala code
宣言時には評価されない
アクセス時に評価され、
computed が出力される
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
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
インスタンス生成時には評価されない
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 が出力される
lazy修飾子(Swift)
41Ⓒ Classmethod, Inc.
• グローバル変数、定数はlazy修飾子をつけなくても
自動的に遅延評価になる
 
let someConst: String = {
print("computed")
return "constant"
}()
let length = someConst.utf8.count
Swift code
lazy修飾子(Swift)
42Ⓒ Classmethod, Inc.
• グローバル変数、定数はlazy修飾子をつけなくても
自動的に遅延評価になる
 
let someConst: String = {
print("computed")
return "constant"
}()
let length = someConst.utf8.count
Swift code
この時点では評価されない
lazy修飾子(Swift)
43Ⓒ Classmethod, Inc.
• グローバル変数、定数はlazy修飾子をつけなくても
自動的に遅延評価になる
 
let someConst: String = {
print("computed")
return "constant"
}()
let length = someConst.utf8.count
Swift code
この時点では評価されない
アクセス時に評価され、
computed が出力される
正格評価・
遅延評価
• 正格評価・遅延評価
• lazy修飾子
• 遅延引数
• 遅延コレクション
44Ⓒ Classmethod, Inc.
遅延引数(Scala)
45Ⓒ Classmethod, Inc.
• 名前渡しパラメーターは引数の評価を遅延する
 
val assertionsEnabled = true
def byNameAssert(pred: => Boolean) =
if (assertionsEnabled && !pred)
throw new AssertionError
byNameAssert(2 > 5)
Scala code
遅延引数(Scala)
46Ⓒ Classmethod, Inc.
• 名前渡しパラメーターは引数の評価を遅延する
 
val assertionsEnabled = true
def byNameAssert(pred: => Boolean) =
if (assertionsEnabled && !pred)
throw new AssertionError
byNameAssert(2 > 5)
Scala code
assertionsEnabled が真の時
初めて引数 pred を評価する
遅延引数(Scala)
47Ⓒ Classmethod, Inc.
• 名前渡しパラメーターは引数の評価を遅延する
 
val assertionsEnabled = true
def byNameAssert(pred: => Boolean) =
if (assertionsEnabled && !pred)
throw new AssertionError
byNameAssert(2 > 5)
Scala code
assertionsEnabled が真の時
初めて引数 pred を評価する
評価は引数を渡すタイミングではなく、
byNameAssert内部の処理が走るタイミングで行われる
遅延引数(Swift)
48Ⓒ Classmethod, Inc.
• @autoclosureは引数の評価を遅延する
 
func myAnd(
lhs: Bool,
@autoclosure _ rhs: () -> Bool
) -> Bool {
if lhs { return rhs() }
else { return false }
}
let result = myAnd(true, 1 < 2)
Swift code
遅延引数(Swift)
49Ⓒ Classmethod, Inc.
• @autoclosureは引数の評価を遅延する
 
func myAnd(
lhs: Bool,
@autoclosure _ rhs: () -> Bool
) -> Bool {
if lhs { return rhs() }
else { return false }
}
let result = myAnd(true, 1 < 2)
Swift code
lhs が真の時初めて引数 rhs を評価する
遅延引数(Swift)
50Ⓒ Classmethod, Inc.
• @autoclosureは引数の評価を遅延する
 
func myAnd(
lhs: Bool,
@autoclosure _ rhs: () -> Bool
) -> Bool {
if lhs { return rhs() }
else { return false }
}
let result = myAnd(true, 1 < 2)
Swift code
lhs が真の時初めて引数 rhs を評価する
評価は引数を渡すタイミングではなく、
myAnd内部の処理が走るタイミングで行われる
正格評価・
遅延評価
• 正格評価・遅延評価
• lazy修飾子
• 遅延引数
• 遅延コレクション
51Ⓒ Classmethod, Inc.
遅延コレクション(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
遅延コレクション(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
遅延コレクション生成
遅延コレクション(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も作成されない
遅延コレクション(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も作成されない
遅延コレクション(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
遅延コレクション(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
遅延コレクション生成
遅延コレクション(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も作成されない
遅延コレクション(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も作成されない
遅延評価のまとめ
60Ⓒ Classmethod, Inc.
Scala Swift
lazy修飾子
遅延引数
遅延コレクション
つけると評価は遅延
つけると評価は遅延
グローバル定数変数は
つけなくても遅延
名前渡しパラメーター @autoclosure
コレクションに対して
.viewで生成
force で正格評価
コレクションに対して
.lazyで生成
必要なときに評価
Topics for today
• ミックスイン
• 正格評価・遅延評価
• 変位指定
61Ⓒ Classmethod, Inc.
変位指定
• リスコフ置換原則
• 共変・反変
• 共変
• 反変
62Ⓒ Classmethod, Inc.
リスコフ置換原則
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
リスコフ置換原則
64Ⓒ Classmethod, Inc.
• リスコフ置換原則
  T型のオブジェクトxに関して属性 Φ(x)が真
→ T型の派生型であるS型のオブジェクトyに関して
属性Φ(y)が真であるべき
リスコフ置換原則
65Ⓒ Classmethod, Inc.
• リスコフ置換原則
 SがTの派生型なら
T型の値が使える箇所でS型の値も使える
リスコフ置換原則
66Ⓒ Classmethod, Inc.
• リスコフ置換原則
 SがTの派生型なら
T型の値が使える箇所でS型の値も使える
「派生型」として満たされるべき原則
(必ずしも「継承」を意味しない)
変位指定
• リスコフ置換原則
• 共変・反変
• 共変
• 反変
67Ⓒ Classmethod, Inc.
共変・反変
68Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
共変・反変
69Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
型引数のない通常の型 
共変・反変
70Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
型引数のない通常の型 
T S
音楽は娯楽の「派生型」として置換可能
共変・反変
71Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
型引数のない通常の型 
→継承関係のみを気にすればうまくいく
T S
音楽は娯楽の「派生型」として置換可能
• ある型が別の型の派生型かどうかを判別する
型引数xのある型 
72Ⓒ Classmethod, Inc.
共変・反変
• ある型が別の型の派生型かどうかを判別する
型引数xのある型 
73Ⓒ Classmethod, Inc.
共変・反変
• ある型が別の型の派生型かどうかを判別する
型引数xのある型 
74Ⓒ Classmethod, Inc.
メタルの作曲家は娯楽の提供者の
「派生型」として置換可能
T S
共変・反変
共変・反変
75Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
型引数xのある型 
共変・反変
76Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
型引数xのある型 
共変・反変
77Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
型引数xのある型 
TS
有機物消費者は竹を食べるパンダの
「派生型」として置換可能
共変・反変
78Ⓒ Classmethod, Inc.
• ある型が別の型の派生型かどうかを判別する
型引数xのある型 
→型引数の継承関係でうまく判断できないケースがある
TS
有機物消費者は竹を食べるパンダの
「派生型」として置換可能
共変・反変
79Ⓒ Classmethod, Inc.
• 共変・反変で
型引数xのある型同士の派生型を判別する
共変(Covariant)型引数の場合
 
共変・反変
80Ⓒ Classmethod, Inc.
• 共変・反変で
型引数xのある型同士の派生型を判別する
共変(Covariant)型引数の場合
→型引数の派生順序を引き継ぐ
 
型引数xの派生順序
「xの提供者」の派生順序
共変・反変
81Ⓒ Classmethod, Inc.
• 共変・反変で
型引数xのある型同士の派生型を判別する
反変(Contravariant)型引数の場合
 
共変・反変
82Ⓒ Classmethod, Inc.
• 共変・反変で
型引数xのある型同士の派生型を判別する
反変(Contravariant)型引数の場合
→型引数の派生順序が反転する
 
型引数xの派生順序
「xの消費者」の派生順序
共変・反変
83Ⓒ Classmethod, Inc.
• 共変・反変で
型引数xのある型同士の派生型を判別する
反変(Contravariant)型引数の場合
→型引数の派生順序が反転する
 
型引数xの派生順序
「xの消費者」の派生順序
PECS
(Producer extends Consumer super)
と呼ばれる基準もある
共変・反変
84Ⓒ Classmethod, Inc.
• 共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
↓ ↑
T
S
U
V
共変・反変
85Ⓒ Classmethod, Inc.
• 共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
↓ ↑
T
S
U
V
TはSの派生型 VはUの派生型
共変・反変
86Ⓒ Classmethod, Inc.
• 共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
反変型引数 共変型引数
↓ ↑
T
S
U
V
TはSの派生型 VはUの派生型
共変・反変
87Ⓒ Classmethod, Inc.
• 共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
反変型引数 共変型引数
↓ ↑↑
T
S
U
V
TはSの派生型 VはUの派生型
[反変S, 共変V]は[反変T, 共変U]の派生型
共変・反変
88Ⓒ Classmethod, Inc.
• 共変・反変で型引数xのある型同士の派生型を判別する
型引数が複数あり、共変・反変が共存する場合
→共変型引数については派生順序を保持、
 反変型引数については派生順序を逆転
反変型引数 共変型引数
↓ ↑↑
T
S
U
V
TはSの派生型 VはUの派生型
[反変S, 共変V]は[反変T, 共変U]の派生型
共変・反変は派生型についての
判定材料を与える
89Ⓒ Classmethod, Inc.
変位指定
• リスコフ置換原則
• 共変・反変
• 共変
• 反変
90Ⓒ Classmethod, Inc.
共変(Scala)
91Ⓒ Classmethod, Inc.
• +を型引数の前につけると共変となる
 sealed abstract class List[+A] …
var anyList: List[Any] = Nil
val intList: List[Int] = List(2, 3, 4)
anyList = intList
Scala code
共変(Scala)
92Ⓒ Classmethod, Inc.
• +を型引数の前につけると共変となる
 sealed abstract class List[+A] …
var anyList: List[Any] = Nil
val intList: List[Int] = List(2, 3, 4)
anyList = intList
Scala code
派生順序は Any > Int
共変(Scala)
93Ⓒ Classmethod, Inc.
• +を型引数の前につけると共変となる
 sealed abstract class List[+A] …
var anyList: List[Any] = Nil
val intList: List[Int] = List(2, 3, 4)
anyList = intList
Scala code
派生順序は Any > Int
型引数の派生順序が保存され、
List[Int] は List[Any]の派生型として扱える
共変(Objective-C)
94Ⓒ Classmethod, Inc.
• __covariantを型引数の前につけると共変となる
 @interface NSArray<__covariant ObjectType>…
NSArray<NSObject *> *anyArray = @[];
NSArray<NSNumber *> *numberArray =
@[@2, @3, @4];
anyArray = numberArray;
Objective-C code
共変(Objective-C)
95Ⓒ Classmethod, Inc.
• __covariantを型引数の前につけると共変となる
 @interface NSArray<__covariant ObjectType>…
NSArray<NSObject *> *anyArray = @[];
NSArray<NSNumber *> *numberArray =
@[@2, @3, @4];
anyArray = numberArray;
Objective-C code
派生順序は NSObject > NSNumber
共変(Objective-C)
96Ⓒ Classmethod, Inc.
• __covariantを型引数の前につけると共変となる
 @interface NSArray<__covariant ObjectType>…
NSArray<NSObject *> *anyArray = @[];
NSArray<NSNumber *> *numberArray =
@[@2, @3, @4];
anyArray = numberArray;
Objective-C code
派生順序は NSObject > NSNumber
型引数の派生順序が保存され、
NSArray<NSNumber *>* は
NSArray<NSObject *>* の派生型として扱える
共変(Swift)
97Ⓒ Classmethod, Inc.
• Array<T>はTについて共変
  struct Array<T> …
var anyArray: [Any] = []
let intArray: [Int] = [2, 3, 4]
anyArray = intArray
Swift code
共変(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
共変(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> の派生型として扱える
共変(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> の派生型として扱える
将来共変を表すためのキーワードが入るかも?(憶測
変位指定
• リスコフ置換原則
• 共変・反変
• 共変
• 反変
101Ⓒ Classmethod, Inc.
反変(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
反変(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
反変(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]の派生型として扱える
反変(Objective-C)
105Ⓒ Classmethod, Inc.
• __contravariantを型引数の前につけると反変となる
 @interface Consumer<__contravariant Type>
: NSObject
- (void)consume:(Type)obj;
@end
@implementation Consumer
- (void)consume:(id)obj {}
@end
Objective-C code
反変(Objective-C)
106Ⓒ Classmethod, Inc.
• __contravariantを型引数の前につけると反変となる
 @interface Consumer<__contravariant Type>
: NSObject
- (void)consume:(Type)obj;
@end
@implementation Consumer
- (void)consume:(id)obj {}
@end
Objective-C code
実装の引数にはidを渡す
反変(Objective-C)
107Ⓒ Classmethod, Inc.
• __contravariantを型引数の前につけると反変となる
 
Consumer<NSObject *> *anyConsumer =
[Consumer<NSObject *> new];
Consumer<NSNumber *> *numberConsumer =
[Consumer<NSNumber *> new];
numberConsumer = anyConsumer;
Objective-C code
反変(Objective-C)
108Ⓒ Classmethod, Inc.
• __contravariantを型引数の前につけると反変となる
 
Consumer<NSObject *> *anyConsumer =
[Consumer<NSObject *> new];
Consumer<NSNumber *> *numberConsumer =
[Consumer<NSNumber *> new];
numberConsumer = anyConsumer;
Objective-C code
派生順序は NSObject > NSNumber
反変(Objective-C)
109Ⓒ Classmethod, Inc.
• __contravariantを型引数の前につけると反変となる
 
Consumer<NSObject *> *anyConsumer =
[Consumer<NSObject *> new];
Consumer<NSNumber *> *numberConsumer =
[Consumer<NSNumber *> new];
numberConsumer = anyConsumer;
Objective-C code
派生順序は NSObject > NSNumber
型引数の派生順序が逆転、
Consumer<NSObject *>* は
Consumer<NSNumber *>* の派生型として扱える
反変(Swift 2.1)
110Ⓒ Classmethod, Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
 
func testVariance(foo:(Int) -> Any){ foo(1) }
func innerAnyInt(p1: Any) -> Int{ return 1 }
func innerAnyAny(p1: Any) -> Any{ return 1 }
func innerIntInt(p1: Int) -> Int{ return 1 }
func innerIntAny(p1: Int) -> Any{ return 1 }
Swift code
http://www.uraimo.com/2015/09/29/Swift2.1-Function-Types-Conversion-
Covariance-Contravariance/
反変(Swift 2.1)
111Ⓒ Classmethod, Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
 
func testVariance(foo:(Int) -> Any){ foo(1) }
func innerAnyInt(p1: Any) -> Int{ return 1 }
func innerAnyAny(p1: Any) -> Any{ return 1 }
func innerIntInt(p1: Int) -> Int{ return 1 }
func innerIntAny(p1: Int) -> Any{ return 1 }
Swift code
引数にIntかその上位派生型、
返り値にAnyかその下位派生型をもつ関数を許容
http://www.uraimo.com/2015/09/29/Swift2.1-Function-Types-Conversion-
Covariance-Contravariance/
反変(Swift 2.1)
112Ⓒ Classmethod, Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
 
func testVariance(foo:(Int) -> Any){ foo(1) }
func innerAnyInt(p1: Any) -> Int{ return 1 }
func innerAnyAny(p1: Any) -> Any{ return 1 }
func innerIntInt(p1: Int) -> Int{ return 1 }
func innerIntAny(p1: Int) -> Any{ return 1 }
Swift code
引数にIntかその上位派生型、
返り値にAnyかその下位派生型をもつ関数を許容
http://www.uraimo.com/2015/09/29/Swift2.1-Function-Types-Conversion-
Covariance-Contravariance/
これらの関数は引数がIntかその上位派生型Any
返り値がAnyかその下位派生型Int
反変(Swift 2.1)
113Ⓒ Classmethod, Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
 
testVariance(innerIntAny)
testVariance(innerAnyInt)
testVariance(innerAnyAny)
testVariance(innerIntInt)
Swift code
反変(Swift 2.1)
114Ⓒ Classmethod, Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
 
testVariance(innerIntAny)
testVariance(innerAnyInt)
testVariance(innerAnyAny)
testVariance(innerIntInt)
Swift code
渡される関数の型は全て (Int) -> Any の派生型
反変(Swift 2.1)
115Ⓒ Classmethod, Inc.
• T -> S (関数の型)はTについて反変、Sについて共変
 
testVariance(innerIntAny)
testVariance(innerAnyInt)
testVariance(innerAnyAny)
testVariance(innerIntInt)
Swift code
将来反変を表すためのキーワードが入るかも?(憶測
渡される関数の型は全て (Int) -> Any の派生型
変位指定のまとめ
116Ⓒ Classmethod, Inc.
Scala ObjC Swift
共変
反変
[ +T ]
[ -T ]
<__covariant T>
<__contravariant T>
Array<T>
が対応
T -> S の引数型
Tが対応
• Effective Java 第二版 項目18
http://www.amazon.co.jp/dp/4621066056
• Scala スケーラブルプログラミング §19.3
http://www.amazon.co.jp/dp/4844330845
• Java Generics: What is PECS?
http://stackoverflow.com/questions/2723397/java-generics-
what-is-pecs
117Ⓒ Classmethod, Inc.
References

More Related Content

What's hot

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
Perlと出会い、Perlを作る
Perlと出会い、Perlを作るPerlと出会い、Perlを作る
Perlと出会い、Perlを作るgoccy
 
OpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler OverviewOpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler Overviewnothingcosmos
 
TensorFlow Lite Delegateとは?
TensorFlow Lite Delegateとは?TensorFlow Lite Delegateとは?
TensorFlow Lite Delegateとは?Mr. Vengineer
 
gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)tnoda
 
Java 9で進化する診断ツール
Java 9で進化する診断ツールJava 9で進化する診断ツール
Java 9で進化する診断ツールYasumasa Suenaga
 
JDK 10 へようこそ
JDK 10 へようこそJDK 10 へようこそ
JDK 10 へようこそDavid Buck
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!bitter_fox
 
Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義JPCERT Coordination Center
 
Retrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃん
Retrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃんRetrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃん
Retrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃんYukari Sakurai
 
第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2lyrical_logical
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
基礎からのCode Contracts
基礎からのCode Contracts基礎からのCode Contracts
基礎からのCode ContractsYoshifumi Kawai
 
Java9新機能概要
Java9新機能概要Java9新機能概要
Java9新機能概要HonMarkHunt
 
これからのNashorn
これからのNashornこれからのNashorn
これからのNashornLogico
 
groovy 2.1.0 20130118
groovy 2.1.0 20130118groovy 2.1.0 20130118
groovy 2.1.0 20130118Uehara Junji
 
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャーssuser070fa9
 

What's hot (20)

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
Perlと出会い、Perlを作る
Perlと出会い、Perlを作るPerlと出会い、Perlを作る
Perlと出会い、Perlを作る
 
Aerospike deep dive LDTs
Aerospike deep dive LDTsAerospike deep dive LDTs
Aerospike deep dive LDTs
 
OpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler OverviewOpenJDK HotSpot C1Compiler Overview
OpenJDK HotSpot C1Compiler Overview
 
TensorFlow Lite Delegateとは?
TensorFlow Lite Delegateとは?TensorFlow Lite Delegateとは?
TensorFlow Lite Delegateとは?
 
gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)gen-class とバイトコード(第3回 gen-class 勉強会資料)
gen-class とバイトコード(第3回 gen-class 勉強会資料)
 
Java 9で進化する診断ツール
Java 9で進化する診断ツールJava 9で進化する診断ツール
Java 9で進化する診断ツール
 
JDK 10 へようこそ
JDK 10 へようこそJDK 10 へようこそ
JDK 10 へようこそ
 
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!
 
Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義
 
Retrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃん
Retrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃんRetrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃん
Retrofit2 &OkHttp 
でAndroidのHTTP通信が快適だにゃん
 
第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2第一回社内 Scala 勉強会(一部抜粋)その 2
第一回社内 Scala 勉強会(一部抜粋)その 2
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
基礎からのCode Contracts
基礎からのCode Contracts基礎からのCode Contracts
基礎からのCode Contracts
 
APIKit
APIKitAPIKit
APIKit
 
Java9新機能概要
Java9新機能概要Java9新機能概要
Java9新機能概要
 
これからのNashorn
これからのNashornこれからのNashorn
これからのNashorn
 
groovy 2.1.0 20130118
groovy 2.1.0 20130118groovy 2.1.0 20130118
groovy 2.1.0 20130118
 
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
【Spring fest 2019】徹底解剖Spring MVCアーキテクチャー
 

Viewers also liked

objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフトobjc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフトTaketo Sano
 
objc2swift (自動変換の野望)
objc2swift (自動変換の野望)objc2swift (自動変換の野望)
objc2swift (自動変換の野望)Taketo Sano
 
奥行きを意識したプロダクト-iOS9で変わる体験-
奥行きを意識したプロダクト-iOS9で変わる体験-奥行きを意識したプロダクト-iOS9で変わる体験-
奥行きを意識したプロダクト-iOS9で変わる体験-正典 三橋
 
iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930
iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930
iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930Ichiro Yamamoto
 
Xcode 7 の新しいところ #cm_ios9
Xcode 7 の新しいところ #cm_ios9Xcode 7 の新しいところ #cm_ios9
Xcode 7 の新しいところ #cm_ios9Tomohiro Kumagai
 
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知るKazuki Nakajima
 
ユーザーを待たせないためにできること
ユーザーを待たせないためにできることユーザーを待たせないためにできること
ユーザーを待たせないためにできることTomoaki Imai
 
iOS9/iPadとマルチタスキング
iOS9/iPadとマルチタスキングiOS9/iPadとマルチタスキング
iOS9/iPadとマルチタスキングAkinori Adachi
 
Xcode 7で始めるCI
Xcode 7で始めるCIXcode 7で始めるCI
Xcode 7で始めるCIyuki0211s
 
iOS 9 Bootcamp #6 UIKit
iOS 9 Bootcamp #6 UIKitiOS 9 Bootcamp #6 UIKit
iOS 9 Bootcamp #6 UIKitShingo Hiraya
 
objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望) objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望) Taketo Sano
 
エンジニアとデザイナーのあいだ
エンジニアとデザイナーのあいだエンジニアとデザイナーのあいだ
エンジニアとデザイナーのあいだU-dai Yokoyama
 
Composer並列化プラグイン #phpblt
Composer並列化プラグイン #phpblt Composer並列化プラグイン #phpblt
Composer並列化プラグイン #phpblt Hiraku Nakano
 
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/MinAdvanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/MinMasahiro Nagano
 
東急ハンズを支える技術
東急ハンズを支える技術東急ハンズを支える技術
東急ハンズを支える技術Tomoaki Imai
 
composerの遅さをまじめに考える #phpstudy
composerの遅さをまじめに考える #phpstudycomposerの遅さをまじめに考える #phpstudy
composerの遅さをまじめに考える #phpstudyHiraku Nakano
 

Viewers also liked (17)

objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフトobjc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
 
objc2swift (自動変換の野望)
objc2swift (自動変換の野望)objc2swift (自動変換の野望)
objc2swift (自動変換の野望)
 
shinobu.apk #1
shinobu.apk #1shinobu.apk #1
shinobu.apk #1
 
奥行きを意識したプロダクト-iOS9で変わる体験-
奥行きを意識したプロダクト-iOS9で変わる体験-奥行きを意識したプロダクト-iOS9で変わる体験-
奥行きを意識したプロダクト-iOS9で変わる体験-
 
iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930
iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930
iOS 9 Overview - iOS 9 Bootcamp in Tokyo - 20150930
 
Xcode 7 の新しいところ #cm_ios9
Xcode 7 の新しいところ #cm_ios9Xcode 7 の新しいところ #cm_ios9
Xcode 7 の新しいところ #cm_ios9
 
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る
 
ユーザーを待たせないためにできること
ユーザーを待たせないためにできることユーザーを待たせないためにできること
ユーザーを待たせないためにできること
 
iOS9/iPadとマルチタスキング
iOS9/iPadとマルチタスキングiOS9/iPadとマルチタスキング
iOS9/iPadとマルチタスキング
 
Xcode 7で始めるCI
Xcode 7で始めるCIXcode 7で始めるCI
Xcode 7で始めるCI
 
iOS 9 Bootcamp #6 UIKit
iOS 9 Bootcamp #6 UIKitiOS 9 Bootcamp #6 UIKit
iOS 9 Bootcamp #6 UIKit
 
objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望) objc2swift (続・自動変換の野望)
objc2swift (続・自動変換の野望)
 
エンジニアとデザイナーのあいだ
エンジニアとデザイナーのあいだエンジニアとデザイナーのあいだ
エンジニアとデザイナーのあいだ
 
Composer並列化プラグイン #phpblt
Composer並列化プラグイン #phpblt Composer並列化プラグイン #phpblt
Composer並列化プラグイン #phpblt
 
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/MinAdvanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
Advanced nginx in mercari - How to handle over 1,200,000 HTTPS Reqs/Min
 
東急ハンズを支える技術
東急ハンズを支える技術東急ハンズを支える技術
東急ハンズを支える技術
 
composerの遅さをまじめに考える #phpstudy
composerの遅さをまじめに考える #phpstudycomposerの遅さをまじめに考える #phpstudy
composerの遅さをまじめに考える #phpstudy
 

Similar to Swift2.x を Scala からみる

JavaLearning_1.pptx
JavaLearning_1.pptxJavaLearning_1.pptx
JavaLearning_1.pptxRyuuGaku
 
Swift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposiumSwift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposiumTomohiro Kumagai
 
Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511Takefumi MIYOSHI
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~Akira Inoue
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform信之 岩永
 
Isomorphic web development with scala and scala.js
Isomorphic web development  with scala and scala.jsIsomorphic web development  with scala and scala.js
Isomorphic web development with scala and scala.jsTanUkkii
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageTaku Miyakawa
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/AndroidセキュアコーディングMasaki Kubo
 
Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010stomita
 
形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfesta
形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfesta形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfesta
形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfestay_taka_23
 
Streaming API で実現する クラウド ⇔ イントラ連携
Streaming API で実現する クラウド ⇔ イントラ連携Streaming API で実現する クラウド ⇔ イントラ連携
Streaming API で実現する クラウド ⇔ イントラ連携Shinichi Tomita
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriYuta Okamoto
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaKazuhiro Sera
 
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜Takaaki Tanaka
 
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~Akira Inoue
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unithigaki
 

Similar to Swift2.x を Scala からみる (20)

MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
JavaLearning_1.pptx
JavaLearning_1.pptxJavaLearning_1.pptx
JavaLearning_1.pptx
 
Swift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposiumSwift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposium
 
Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511Synthesijer - HLS frineds 20190511
Synthesijer - HLS frineds 20190511
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
Isomorphic web development with scala and scala.js
Isomorphic web development  with scala and scala.jsIsomorphic web development  with scala and scala.js
Isomorphic web development with scala and scala.js
 
Rpscala2011 0601
Rpscala2011 0601Rpscala2011 0601
Rpscala2011 0601
 
実践 NestJS
実践 NestJS実践 NestJS
実践 NestJS
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
 
Java/Androidセキュアコーディング
Java/AndroidセキュアコーディングJava/Androidセキュアコーディング
Java/Androidセキュアコーディング
 
Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010
 
形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfesta
形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfesta形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfesta
形式手法と AWS のおいしい関係。- モデル検査器 Alloy によるインフラ設計技法 #jawsfesta
 
Streaming API で実現する クラウド ⇔ イントラ連携
Streaming API で実現する クラウド ⇔ イントラ連携Streaming API で実現する クラウド ⇔ イントラ連携
Streaming API で実現する クラウド ⇔ イントラ連携
 
Grails 2.0.0.M1の話
Grails 2.0.0.M1の話 Grails 2.0.0.M1の話
Grails 2.0.0.M1の話
 
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuriWhy Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuri
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
 
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
AndroidーiOS開発比較〜iOSエンジニアから見たAndroidのアレコレ〜
 
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ ~ Any browser. Any host. Any OS. Open Source. ~
 
Ruby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unit
 

More from Yuichi Adachi

Seminar on Quantum Computation & Quantum Information part28
Seminar on Quantum Computation & Quantum Information part28Seminar on Quantum Computation & Quantum Information part28
Seminar on Quantum Computation & Quantum Information part28Yuichi Adachi
 
Seminar on Quantum Computation & Quantum Information part19
Seminar on Quantum Computation & Quantum Information part19Seminar on Quantum Computation & Quantum Information part19
Seminar on Quantum Computation & Quantum Information part19Yuichi Adachi
 
Seminar on Quantum Computation & Quantum Information part15
Seminar on Quantum Computation & Quantum Information part15Seminar on Quantum Computation & Quantum Information part15
Seminar on Quantum Computation & Quantum Information part15Yuichi Adachi
 
Seminar on Quantum Computation & Quantum Information part14
Seminar on Quantum Computation & Quantum Information part14Seminar on Quantum Computation & Quantum Information part14
Seminar on Quantum Computation & Quantum Information part14Yuichi Adachi
 
VIPER アーキテクチャによる iOS アプリの設計
VIPER アーキテクチャによる iOS アプリの設計VIPER アーキテクチャによる iOS アプリの設計
VIPER アーキテクチャによる iOS アプリの設計Yuichi Adachi
 
[iOS8] 新たな線形代数ライブラリ Linear Algebra
[iOS8] 新たな線形代数ライブラリ Linear Algebra[iOS8] 新たな線形代数ライブラリ Linear Algebra
[iOS8] 新たな線形代数ライブラリ Linear AlgebraYuichi Adachi
 
Swiftの新機能 Optional
Swiftの新機能 OptionalSwiftの新機能 Optional
Swiftの新機能 OptionalYuichi Adachi
 
ユニットテスト初学者がKiwiFramework非同期テストで失敗した
ユニットテスト初学者がKiwiFramework非同期テストで失敗したユニットテスト初学者がKiwiFramework非同期テストで失敗した
ユニットテスト初学者がKiwiFramework非同期テストで失敗したYuichi Adachi
 

More from Yuichi Adachi (10)

Seminar on Quantum Computation & Quantum Information part28
Seminar on Quantum Computation & Quantum Information part28Seminar on Quantum Computation & Quantum Information part28
Seminar on Quantum Computation & Quantum Information part28
 
Seminar on Quantum Computation & Quantum Information part19
Seminar on Quantum Computation & Quantum Information part19Seminar on Quantum Computation & Quantum Information part19
Seminar on Quantum Computation & Quantum Information part19
 
Seminar on Quantum Computation & Quantum Information part15
Seminar on Quantum Computation & Quantum Information part15Seminar on Quantum Computation & Quantum Information part15
Seminar on Quantum Computation & Quantum Information part15
 
ゲンバのSwift
ゲンバのSwiftゲンバのSwift
ゲンバのSwift
 
Seminar on Quantum Computation & Quantum Information part14
Seminar on Quantum Computation & Quantum Information part14Seminar on Quantum Computation & Quantum Information part14
Seminar on Quantum Computation & Quantum Information part14
 
VIPER アーキテクチャによる iOS アプリの設計
VIPER アーキテクチャによる iOS アプリの設計VIPER アーキテクチャによる iOS アプリの設計
VIPER アーキテクチャによる iOS アプリの設計
 
[iOS8] 新たな線形代数ライブラリ Linear Algebra
[iOS8] 新たな線形代数ライブラリ Linear Algebra[iOS8] 新たな線形代数ライブラリ Linear Algebra
[iOS8] 新たな線形代数ライブラリ Linear Algebra
 
Swiftの新機能 Optional
Swiftの新機能 OptionalSwiftの新機能 Optional
Swiftの新機能 Optional
 
ユニットテスト初学者がKiwiFramework非同期テストで失敗した
ユニットテスト初学者がKiwiFramework非同期テストで失敗したユニットテスト初学者がKiwiFramework非同期テストで失敗した
ユニットテスト初学者がKiwiFramework非同期テストで失敗した
 
Applicative functor
Applicative functorApplicative functor
Applicative functor
 

Swift2.x を Scala からみる

  • 2. 2 安達 勇一 • 2013/12 入社 • TwitterID: @UsrNameu1 • Github: https://github.com/ UsrNameu1 • Blog: http://dev.classmethod.jp/ author/yad • ここ半年はサーバーサイドメイン
  • 3. Topics for today • ミックスイン • 正格評価・遅延評価 • 変位指定 3Ⓒ Classmethod, Inc.
  • 4. Topics for today • ミックスイン • 正格評価・遅延評価 • 変位指定 4Ⓒ Classmethod, Inc.
  • 5. ミックスイン • ミックスイン • 抽象インターフェイス • デフォルト実装 • ミックスイン対象制限 5Ⓒ Classmethod, Inc.
  • 6. ミックスイン 6Ⓒ Classmethod, Inc. • ミックスイン(mix-in)とは? クラスが「本来の型」に加えて、なんらかの任意の振 る舞いを提供していることを宣言するために、クラスが 実装する型 Bloch(2008)  Effective Java 2nd edition
  • 7. ミックスイン • ミックスイン • 抽象インターフェイス • デフォルト実装 • ミックスイン対象制限 7Ⓒ Classmethod, Inc.
  • 8. 抽象インターフェイス(Scala) 8Ⓒ Classmethod, Inc. • traitは抽象インターフェイスをサポートしている trait AbstractTrait { type DataType val constant: DataType var variable: DataType def method(): DataType } Scala code
  • 9. 抽象インターフェイス(Scala) 9Ⓒ Classmethod, Inc. • traitは抽象インターフェイスをサポートしている trait AbstractTrait { type DataType val constant: DataType var variable: DataType def method(): DataType } 抽象型メンバー、定数、変数、メソッドが定義できる Scala code
  • 10. 抽象インターフェイス(Swift) 10Ⓒ Classmethod, Inc. • protocolは抽象インターフェイスをサポートしている protocol AbstractProtocol { typealias DataType var constant: DataType { get } var variable: DataType { get set } func method() -> DataType init(t: DataType) subscript(i: Int) -> DataType { get } func + (lhs: DataType, rhs: DataType) -> DataType } Swift code
  • 11. 抽象インターフェイス(Swift) 11Ⓒ Classmethod, Inc. • protocolは抽象インターフェイスをサポートしている protocol AbstractProtocol { typealias DataType var constant: DataType { get } var variable: DataType { get set } func method() -> DataType init(t: DataType) subscript(i: Int) -> DataType { get } func + (lhs: DataType, rhs: DataType) -> DataType } 抽象型メンバー、プロパティ、メソッド、イニシャライザ サブスクリプト、演算子が定義できる Swift code
  • 12. ミックスイン • ミックスイン • 抽象インターフェイス • デフォルト実装 • ミックスイン対象制限 12Ⓒ Classmethod, Inc.
  • 13. デフォルト実装(Scala) 13Ⓒ Classmethod, Inc. • traitはデフォルト実装をサポートしている trait AbstractTrait { type DataType = String val constant: DataType = “aa” var variable: DataType = “aaa” def method(): DataType = { “aaaa” } } Scala code
  • 14. デフォルト実装(Scala) 14Ⓒ Classmethod, Inc. • traitはデフォルト実装をサポートしている trait AbstractTrait { type DataType = String val constant: DataType = “aa” var variable: DataType = “aaa” def method(): DataType = { “aaaa” } } デフォルトの実装をtraitの各メンバーに対して定義できる Scala code
  • 15. デフォルト実装(Swift 2.x) 15Ⓒ Classmethod, Inc. • protocol extensionはデフォルト実装をサポートしている extension AbstractProtocol { typealias DataType = String var constant: DataType { return “a” } func method() -> DataType { return “aa” } } Swift code
  • 16. デフォルト実装(Swift 2.x) 16Ⓒ Classmethod, Inc. • protocol extensionはデフォルト実装をサポートしている extension AbstractProtocol { typealias DataType = String var constant: DataType { return “a” } func method() -> DataType { return “aa” } } デフォルトの実装をprotocolの各メンバーに対して定義できる Swift code
  • 17. ミックスイン • ミックスイン • 抽象インターフェイス • デフォルト実装 • ミックスイン対象制限 17Ⓒ Classmethod, Inc.
  • 18. ミックスイン対象制限(Scala) 18Ⓒ Classmethod, Inc. • traitは自分型アノテーションで継承の対象になる型を 限定できる trait AbstractTrait { self: SomeClass => def method(): String = { “aaaa” } } Scala code
  • 19. ミックスイン対象制限(Scala) 19Ⓒ Classmethod, Inc. • traitは自分型アノテーションで継承の対象になる型を 限定できる trait AbstractTrait { self: SomeClass => def method(): String = { “aaaa” } } Scala code ミックスインの対象になる型をSomeClassに限定できる →AbstractTraitはSomeClassと  そのサブ型からしか継承できない
  • 20. ミックスイン対象制限(Swift 2.x) 20Ⓒ Classmethod, Inc. • protocol extensionのSelfへの制約によって デフォルト実装が使える継承の対象となる型を制限できる extension AbstractProtocol where Self: SomeClass { func method() -> String { return “aa” } } Swift code
  • 21. ミックスイン対象制限(Swift 2.x) 21Ⓒ Classmethod, Inc. • protocol extensionのSelfへの制約によって デフォルト実装が使える継承の対象となる型を制限できる extension AbstractProtocol where Self: SomeClass { func method() -> String { return “aa” } } デフォルトの実装を使える型はSomeClassとそのサブ型のみ Swift code
  • 22. ミックスイン対象制限(Swift 2.x) 22Ⓒ Classmethod, Inc. • protocol extensionのSelfへの制約によって デフォルト実装が使える継承の対象となる型を制限できる extension AbstractProtocol where Self: SomeClass { func method() -> String { return “aa” } } デフォルトの実装を使える型はSomeClassとそのサブ型のみ Swift code See also→ http://www.slideshare.net/UsrNameu1/swift2-protocol-extension
  • 23. ミックスインのまとめ 23Ⓒ Classmethod, Inc. Scala Swift 抽象インターフェイス デフォルト実装 ミックスイン対象型への制約 trait protocol trait protocol extension traitでの 自分型アノテーション protocol extensionでの Self への制約
  • 24. Topics for today • ミックスイン • 正格評価・遅延評価 • 変位指定 24Ⓒ Classmethod, Inc.
  • 25. 正格評価・ 遅延評価 • 正格評価・遅延評価 • lazy修飾子 • 遅延引数 • 遅延コレクション 25Ⓒ Classmethod, Inc.
  • 26. 正格評価・遅延評価 26Ⓒ Classmethod, Inc. • 評価(evaluation) とは? 式から値を計算し、取り出す操作
  • 27. 正格評価・遅延評価 27Ⓒ Classmethod, Inc. • 評価(evaluation) とは? 式から値を計算し、取り出す操作 let a = 1 + 1 Swift code
  • 28. 正格評価・遅延評価 28Ⓒ Classmethod, Inc. • 評価(evaluation) とは? 式から値を計算し、取り出す操作 let a = 1 + 1 1 + 1という式から2を計算し、取り出す Swift code
  • 29. 正格評価・遅延評価 29Ⓒ Classmethod, Inc. • 評価(evaluation) とは? 式から値を計算し、取り出す操作 let a = 1 + 1 1 + 1という式から2を計算し、取り出す a という名前の定数に代入する Swift code
  • 30. 正格評価・遅延評価 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
  • 34. 正格評価・ 遅延評価 • 正格評価・遅延評価 • lazy修飾子 • 遅延引数 • 遅延コレクション 34Ⓒ Classmethod, Inc.
  • 35. 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 が出力される
  • 44. 正格評価・ 遅延評価 • 正格評価・遅延評価 • lazy修飾子 • 遅延引数 • 遅延コレクション 44Ⓒ Classmethod, Inc.
  • 45. 遅延引数(Scala) 45Ⓒ Classmethod, Inc. • 名前渡しパラメーターは引数の評価を遅延する   val assertionsEnabled = true def byNameAssert(pred: => Boolean) = if (assertionsEnabled && !pred) throw new AssertionError byNameAssert(2 > 5) Scala code
  • 46. 遅延引数(Scala) 46Ⓒ Classmethod, Inc. • 名前渡しパラメーターは引数の評価を遅延する   val assertionsEnabled = true def byNameAssert(pred: => Boolean) = if (assertionsEnabled && !pred) throw new AssertionError byNameAssert(2 > 5) Scala code assertionsEnabled が真の時 初めて引数 pred を評価する
  • 47. 遅延引数(Scala) 47Ⓒ Classmethod, Inc. • 名前渡しパラメーターは引数の評価を遅延する   val assertionsEnabled = true def byNameAssert(pred: => Boolean) = if (assertionsEnabled && !pred) throw new AssertionError byNameAssert(2 > 5) Scala code assertionsEnabled が真の時 初めて引数 pred を評価する 評価は引数を渡すタイミングではなく、 byNameAssert内部の処理が走るタイミングで行われる
  • 48. 遅延引数(Swift) 48Ⓒ Classmethod, Inc. • @autoclosureは引数の評価を遅延する   func myAnd( lhs: Bool, @autoclosure _ rhs: () -> Bool ) -> Bool { if lhs { return rhs() } else { return false } } let result = myAnd(true, 1 < 2) Swift code
  • 49. 遅延引数(Swift) 49Ⓒ Classmethod, Inc. • @autoclosureは引数の評価を遅延する   func myAnd( lhs: Bool, @autoclosure _ rhs: () -> Bool ) -> Bool { if lhs { return rhs() } else { return false } } let result = myAnd(true, 1 < 2) Swift code lhs が真の時初めて引数 rhs を評価する
  • 50. 遅延引数(Swift) 50Ⓒ Classmethod, Inc. • @autoclosureは引数の評価を遅延する   func myAnd( lhs: Bool, @autoclosure _ rhs: () -> Bool ) -> Bool { if lhs { return rhs() } else { return false } } let result = myAnd(true, 1 < 2) Swift code lhs が真の時初めて引数 rhs を評価する 評価は引数を渡すタイミングではなく、 myAnd内部の処理が走るタイミングで行われる
  • 51. 正格評価・ 遅延評価 • 正格評価・遅延評価 • lazy修飾子 • 遅延引数 • 遅延コレクション 51Ⓒ Classmethod, Inc.
  • 52. 遅延コレクション(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も作成されない
  • 60. 遅延評価のまとめ 60Ⓒ Classmethod, Inc. Scala Swift lazy修飾子 遅延引数 遅延コレクション つけると評価は遅延 つけると評価は遅延 グローバル定数変数は つけなくても遅延 名前渡しパラメーター @autoclosure コレクションに対して .viewで生成 force で正格評価 コレクションに対して .lazyで生成 必要なときに評価
  • 61. Topics for today • ミックスイン • 正格評価・遅延評価 • 変位指定 61Ⓒ Classmethod, Inc.
  • 62. 変位指定 • リスコフ置換原則 • 共変・反変 • 共変 • 反変 62Ⓒ Classmethod, Inc.
  • 63. リスコフ置換原則 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
  • 64. リスコフ置換原則 64Ⓒ Classmethod, Inc. • リスコフ置換原則   T型のオブジェクトxに関して属性 Φ(x)が真 → T型の派生型であるS型のオブジェクトyに関して 属性Φ(y)が真であるべき
  • 65. リスコフ置換原則 65Ⓒ Classmethod, Inc. • リスコフ置換原則  SがTの派生型なら T型の値が使える箇所でS型の値も使える
  • 66. リスコフ置換原則 66Ⓒ Classmethod, Inc. • リスコフ置換原則  SがTの派生型なら T型の値が使える箇所でS型の値も使える 「派生型」として満たされるべき原則 (必ずしも「継承」を意味しない)
  • 67. 変位指定 • リスコフ置換原則 • 共変・反変 • 共変 • 反変 67Ⓒ Classmethod, Inc.
  • 68. 共変・反変 68Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
  • 69. 共変・反変 69Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する 型引数のない通常の型 
  • 70. 共変・反変 70Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する 型引数のない通常の型  T S 音楽は娯楽の「派生型」として置換可能
  • 71. 共変・反変 71Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する 型引数のない通常の型  →継承関係のみを気にすればうまくいく T S 音楽は娯楽の「派生型」として置換可能
  • 74. • ある型が別の型の派生型かどうかを判別する 型引数xのある型  74Ⓒ Classmethod, Inc. メタルの作曲家は娯楽の提供者の 「派生型」として置換可能 T S 共変・反変
  • 75. 共変・反変 75Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する 型引数xのある型 
  • 76. 共変・反変 76Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する 型引数xのある型 
  • 77. 共変・反変 77Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する 型引数xのある型  TS 有機物消費者は竹を食べるパンダの 「派生型」として置換可能
  • 78. 共変・反変 78Ⓒ Classmethod, Inc. • ある型が別の型の派生型かどうかを判別する 型引数xのある型  →型引数の継承関係でうまく判断できないケースがある TS 有機物消費者は竹を食べるパンダの 「派生型」として置換可能
  • 79. 共変・反変 79Ⓒ Classmethod, Inc. • 共変・反変で 型引数xのある型同士の派生型を判別する 共変(Covariant)型引数の場合  
  • 80. 共変・反変 80Ⓒ Classmethod, Inc. • 共変・反変で 型引数xのある型同士の派生型を判別する 共変(Covariant)型引数の場合 →型引数の派生順序を引き継ぐ   型引数xの派生順序 「xの提供者」の派生順序
  • 81. 共変・反変 81Ⓒ Classmethod, Inc. • 共変・反変で 型引数xのある型同士の派生型を判別する 反変(Contravariant)型引数の場合  
  • 82. 共変・反変 82Ⓒ Classmethod, Inc. • 共変・反変で 型引数xのある型同士の派生型を判別する 反変(Contravariant)型引数の場合 →型引数の派生順序が反転する   型引数xの派生順序 「xの消費者」の派生順序
  • 83. 共変・反変 83Ⓒ Classmethod, Inc. • 共変・反変で 型引数xのある型同士の派生型を判別する 反変(Contravariant)型引数の場合 →型引数の派生順序が反転する   型引数xの派生順序 「xの消費者」の派生順序 PECS (Producer extends Consumer super) と呼ばれる基準もある
  • 84. 共変・反変 84Ⓒ Classmethod, Inc. • 共変・反変で型引数xのある型同士の派生型を判別する 型引数が複数あり、共変・反変が共存する場合 ↓ ↑ T S U V
  • 85. 共変・反変 85Ⓒ Classmethod, Inc. • 共変・反変で型引数xのある型同士の派生型を判別する 型引数が複数あり、共変・反変が共存する場合 ↓ ↑ T S U V TはSの派生型 VはUの派生型
  • 86. 共変・反変 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]の派生型
  • 90. 変位指定 • リスコフ置換原則 • 共変・反変 • 共変 • 反変 90Ⓒ Classmethod, Inc.
  • 91. 共変(Scala) 91Ⓒ Classmethod, Inc. • +を型引数の前につけると共変となる  sealed abstract class List[+A] … var anyList: List[Any] = Nil val intList: List[Int] = List(2, 3, 4) anyList = intList Scala code
  • 92. 共変(Scala) 92Ⓒ Classmethod, Inc. • +を型引数の前につけると共変となる  sealed abstract class List[+A] … var anyList: List[Any] = Nil val intList: List[Int] = List(2, 3, 4) anyList = intList Scala code 派生順序は Any > Int
  • 93. 共変(Scala) 93Ⓒ Classmethod, Inc. • +を型引数の前につけると共変となる  sealed abstract class List[+A] … var anyList: List[Any] = Nil val intList: List[Int] = List(2, 3, 4) anyList = intList Scala code 派生順序は Any > Int 型引数の派生順序が保存され、 List[Int] は List[Any]の派生型として扱える
  • 94. 共変(Objective-C) 94Ⓒ Classmethod, Inc. • __covariantを型引数の前につけると共変となる  @interface NSArray<__covariant ObjectType>… NSArray<NSObject *> *anyArray = @[]; NSArray<NSNumber *> *numberArray = @[@2, @3, @4]; anyArray = numberArray; Objective-C code
  • 95. 共変(Objective-C) 95Ⓒ Classmethod, Inc. • __covariantを型引数の前につけると共変となる  @interface NSArray<__covariant ObjectType>… NSArray<NSObject *> *anyArray = @[]; NSArray<NSNumber *> *numberArray = @[@2, @3, @4]; anyArray = numberArray; Objective-C code 派生順序は NSObject > NSNumber
  • 96. 共変(Objective-C) 96Ⓒ Classmethod, Inc. • __covariantを型引数の前につけると共変となる  @interface NSArray<__covariant ObjectType>… NSArray<NSObject *> *anyArray = @[]; NSArray<NSNumber *> *numberArray = @[@2, @3, @4]; anyArray = numberArray; Objective-C code 派生順序は NSObject > NSNumber 型引数の派生順序が保存され、 NSArray<NSNumber *>* は NSArray<NSObject *>* の派生型として扱える
  • 97. 共変(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> の派生型として扱える 将来共変を表すためのキーワードが入るかも?(憶測
  • 101. 変位指定 • リスコフ置換原則 • 共変・反変 • 共変 • 反変 101Ⓒ Classmethod, Inc.
  • 102. 反変(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]の派生型として扱える
  • 105. 反変(Objective-C) 105Ⓒ Classmethod, Inc. • __contravariantを型引数の前につけると反変となる  @interface Consumer<__contravariant Type> : NSObject - (void)consume:(Type)obj; @end @implementation Consumer - (void)consume:(id)obj {} @end Objective-C code
  • 106. 反変(Objective-C) 106Ⓒ Classmethod, Inc. • __contravariantを型引数の前につけると反変となる  @interface Consumer<__contravariant Type> : NSObject - (void)consume:(Type)obj; @end @implementation Consumer - (void)consume:(id)obj {} @end Objective-C code 実装の引数にはidを渡す
  • 107. 反変(Objective-C) 107Ⓒ Classmethod, Inc. • __contravariantを型引数の前につけると反変となる   Consumer<NSObject *> *anyConsumer = [Consumer<NSObject *> new]; Consumer<NSNumber *> *numberConsumer = [Consumer<NSNumber *> new]; numberConsumer = anyConsumer; Objective-C code
  • 108. 反変(Objective-C) 108Ⓒ Classmethod, Inc. • __contravariantを型引数の前につけると反変となる   Consumer<NSObject *> *anyConsumer = [Consumer<NSObject *> new]; Consumer<NSNumber *> *numberConsumer = [Consumer<NSNumber *> new]; numberConsumer = anyConsumer; Objective-C code 派生順序は NSObject > NSNumber
  • 109. 反変(Objective-C) 109Ⓒ Classmethod, Inc. • __contravariantを型引数の前につけると反変となる   Consumer<NSObject *> *anyConsumer = [Consumer<NSObject *> new]; Consumer<NSNumber *> *numberConsumer = [Consumer<NSNumber *> new]; numberConsumer = anyConsumer; Objective-C code 派生順序は NSObject > NSNumber 型引数の派生順序が逆転、 Consumer<NSObject *>* は Consumer<NSNumber *>* の派生型として扱える
  • 110. 反変(Swift 2.1) 110Ⓒ Classmethod, Inc. • T -> S (関数の型)はTについて反変、Sについて共変   func testVariance(foo:(Int) -> Any){ foo(1) } func innerAnyInt(p1: Any) -> Int{ return 1 } func innerAnyAny(p1: Any) -> Any{ return 1 } func innerIntInt(p1: Int) -> Int{ return 1 } func innerIntAny(p1: Int) -> Any{ return 1 } Swift code http://www.uraimo.com/2015/09/29/Swift2.1-Function-Types-Conversion- Covariance-Contravariance/
  • 111. 反変(Swift 2.1) 111Ⓒ Classmethod, Inc. • T -> S (関数の型)はTについて反変、Sについて共変   func testVariance(foo:(Int) -> Any){ foo(1) } func innerAnyInt(p1: Any) -> Int{ return 1 } func innerAnyAny(p1: Any) -> Any{ return 1 } func innerIntInt(p1: Int) -> Int{ return 1 } func innerIntAny(p1: Int) -> Any{ return 1 } Swift code 引数にIntかその上位派生型、 返り値にAnyかその下位派生型をもつ関数を許容 http://www.uraimo.com/2015/09/29/Swift2.1-Function-Types-Conversion- Covariance-Contravariance/
  • 112. 反変(Swift 2.1) 112Ⓒ Classmethod, Inc. • T -> S (関数の型)はTについて反変、Sについて共変   func testVariance(foo:(Int) -> Any){ foo(1) } func innerAnyInt(p1: Any) -> Int{ return 1 } func innerAnyAny(p1: Any) -> Any{ return 1 } func innerIntInt(p1: Int) -> Int{ return 1 } func innerIntAny(p1: Int) -> Any{ return 1 } Swift code 引数にIntかその上位派生型、 返り値にAnyかその下位派生型をもつ関数を許容 http://www.uraimo.com/2015/09/29/Swift2.1-Function-Types-Conversion- Covariance-Contravariance/ これらの関数は引数がIntかその上位派生型Any 返り値がAnyかその下位派生型Int
  • 113. 反変(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 の派生型
  • 116. 変位指定のまとめ 116Ⓒ Classmethod, Inc. Scala ObjC Swift 共変 反変 [ +T ] [ -T ] <__covariant T> <__contravariant T> Array<T> が対応 T -> S の引数型 Tが対応
  • 117. • Effective Java 第二版 項目18 http://www.amazon.co.jp/dp/4621066056 • Scala スケーラブルプログラミング §19.3 http://www.amazon.co.jp/dp/4844330845 • Java Generics: What is PECS? http://stackoverflow.com/questions/2723397/java-generics- what-is-pecs 117Ⓒ Classmethod, Inc. References