『プロトコル拡張を、それに準拠する将来の型で制約して、既定の実装を添えよう』という話を発端にした考察
- es_kumagai
- 1894
- 7
- 2
- 0
【続編】もしも `extension PROTOCOL where Self: T` を親子のクラスにそれぞれ適用したら採用される実装はどっち gist.github.com/4011c9f77019e3… #swift pic.twitter.com/UvMB9j2vs1
2016-02-16 11:37:42@es_kumagai @niwatako さんのプロトコル拡張の問題の例です。 gist.github.com/sinsoku/275acf… #yidev
2016-03-05 23:29:16@es_kumagai @niwatako 若干、元のコードから変更してますが、同じ問題を再現できているはず。何か違う箇所などあれば @niwatako さんコメントください。
2016-03-05 23:30:42@niwatako @sinsoku_listy おお、ありがとうございます。こちらはあの後 @eduraaa さんと、構造的な観点での妥当な理屈をおそらくみつけました。
2016-03-06 00:54:33@niwatako @sinsoku_listy @eduraaa あ、でも挙げてくれた最後の行を説明するにはもうちょっと考える必要があるかも知れません。もう少し整理してみますね。
2016-03-06 01:04:46@eduraaa 今日もとことんありがとうございました! 先ほどのコードを送りますね。最後ちょっと追記してあります。 gist.github.com/1521da74adf007… #swift pic.twitter.com/20iSMMh2fd
2016-03-06 03:37:46@eduraaa 追記したところ、たぶんさっきの理屈で通用しそうな気がしてるんですけど、さっきの中では挙げなかったところ&少し複雑な感じがするので、また今日のおさらいしながら話せたらもっと理解が深まりそう。
2016-03-06 03:57:01プロトコル拡張の制約や実装は、型に対してもプロトコルに対してもたぶん静的、プロトコル関係の機能呼び出しはたぶん静的、型関係の機能呼び出しはたぶん動的。どちらも規則的、ただしたぶん、この文頭に書いたの辺りのギャップが、どの実装を適用するかと、どの実装を実行するかの差を生じさせてる。
2016-03-06 05:07:04それと、型に実装を求めるものなのか、それともプロトコルの世界観で規定できる振る舞いなのか。前者は protocol に宣言を伴うのに対して、後者はそれを伴わない。
2016-03-06 05:10:06それと縛り方 … ああ、ここがやっぱり少し認識が不足しているかも。両方が実装されることは間違いない。そしてたとえば A の実装を消して曖昧解消、そちら側の実行で 'A' is not a subtype of 'B' になったとき。
2016-03-06 05:47:48Self : B は … とりあえず両方が実装されて、内部で self.dynamicType is B が実行される(エラーから処理を連想)のか、それとも B が P に必ず準拠するから実装されるが、実行時は dynamicType が A なのでミスマッチを起こすのか。
2016-03-06 05:52:54ああ、このあたりは Playground のコード色付けが変化しなかっただけで、プロジェクトで試すとビルドエラーか。そうするとここは案外、そんなに大事なところではないかもしれない。その直前の、型に担わすか担わさないか、そこのところまでで大丈夫かもしれない。
2016-03-06 06:24:41@es_kumagai さんに教えていただいた、"プロトコルを準拠すると宣言した型に対して強く結び付く" というお話しに関連しそうな例が作れました gist.github.com/e32bb6ff45536d… #swift pic.twitter.com/Uej1nN5RZU
2016-03-06 13:11:35P を A ではなく B に準拠させて、でも、protocol extension で Self に A と B をそれぞれ指定した実装をしたとき gist.github.com/30c62862820b34… #swift pic.twitter.com/Y6HxRAilxK
2016-03-06 13:15:20そして、似た構造をプロトコルの世界だけで組み立てたもの。クラスのと比べ始めてしまうと混乱するけど、見て欲しいのは単に extension 行の異様な雰囲気。 gist.github.com/6f4c4e6d8209f3… #swift pic.twitter.com/6yLnbfIq2Y
2016-03-06 13:51:38こんなところからもプロトコルの継承とオブジェクトの継承の、それぞれの意味する方向性の違いみたいなものが垣間見えるような気がして興味深い。 #swift
2016-03-06 13:54:44ん、さっきの自分の例、つまり「なんで A1 と A2 ではなく、わざわざ両方 A0 に持たせるの」と呟きたい例なんですけど、昨日のプレイグラウンドのエラーがビルド時なのも踏まえると、プロトコル拡張でwhereにクラスを指定したときの動きが少し感じられる気がしてきた。 #swift
2016-03-06 14:17:29そして、また混乱してきた。プロトコルに宣言を入れた場合とそうでない場合の、プロトコル拡張での定義にそれぞれ別の名前が欲しいかもしれない。ここに同じ言葉を当てて考えているとうっかり混乱してしまう気がする。 #swift
2016-03-06 14:26:02まどろっこしい言葉ばかりしか見つけられないですけれど、前者は「オブジェクトの世界を見据えたプロトコル拡張」「オブジェクト指向的なプロトコル拡張」「(宣言部に注目して)機能実装の要求あり」みたいな感じ、 #swift
2016-03-06 14:59:05それと「ミックスイン」か。後者は「プロトコルの世界観だけでのプロトコル拡張」「プロトコル指向的なプロトコル拡張」「(宣言部に注目して)機能実装をとりわけ求めない」みたいな感じ。 #swift
2016-03-06 15:07:35それと根本的なところでこれも忘れがちなのが、この話は型の世界観での話ではなく、プロトコルの世界観での話。ここもうまく言葉で加味できたら、考え中に混乱する可能性を抑えられるかもしれない。 #swift
2016-03-06 15:08:14