/
main.tex
1345 lines (1144 loc) · 39.8 KB
/
main.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\usepackage{luatexja}
\usepackage[hiragino-pron, nfssonly, deluxe, expert]{luatexja-preset}
\usepackage{pgfpages}
\usepackage{fontspec}
\usepackage{epigraph}
\usepackage{etoolbox}
\usepackage{tikz}
\usepackage{framed}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{listings}
\usepackage{libertine}
\usepackage{bxcoloremoji}
\usepackage{xcolor}
\usepackage{multirow}
\usepackage{diagbox}
\usepackage{caption}
\usepackage{xsavebox}
\definecolor{links}{HTML}{2A1B81}
\hypersetup{colorlinks,linkcolor=,urlcolor=links}
\usetheme{Boadilla}
\usecolortheme{seahorse}
% \usefonttheme{serif}
\setbeamercolor{page number in head/foot}{bg=blue!10}
\makeatother
\setbeamertemplate{footline}
{
\leavevmode%
\hbox{%
\begin{beamercolorbox}[wd=.4\paperwidth,ht=2.25ex,dp=1ex,center]{author in head/foot}%
\usebeamerfont{author in head/foot}\insertshortauthor\hspace*{1ex}(\insertshortinstitute)
\end{beamercolorbox}%
\begin{beamercolorbox}[wd=.3\paperwidth,ht=2.25ex,dp=1ex,center]{title in head/foot}%
\usebeamerfont{title in head/foot}\insertshorttitle
\end{beamercolorbox}%
\begin{beamercolorbox}[wd=.2\paperwidth,ht=2.25ex,dp=1ex,center]{date in head/foot}%
\insertshortdate
\end{beamercolorbox}%
\begin{beamercolorbox}[wd=.1\paperwidth,ht=2.25ex,dp=1ex,center]{page number in head/foot}%
\insertframenumber{} / \inserttotalframenumber\hspace*{1ex}
\end{beamercolorbox}}%
\vskip0pt%
}
\makeatletter
\beamertemplatenavigationsymbolsempty
\setbeamertemplate{bibliography item}{\insertbiblabel}
\setbeamersize{description width=1cm}
\setbeamertemplate{items}[circle]
\setbeamertemplate{section in toc}[circle]
\setbeamertemplate{subsection in toc}{%
\leavevmode\leftskip=2em
{%
\usebeamerfont*{itemize item}%
\usebeamercolor{subsection number projected}%
\color{bg}%
\raise1.25pt\hbox{\donotcoloroutermaths$\bullet$}}%
\hskip1.5ex\inserttocsubsection\par}
\setbeamercolor{title}{bg=white}
\setbeamertemplate{title page}
{%
\vbox{}
\vfill
\begingroup
\centering
\hrulefill
\vskip1em\par
\begin{beamercolorbox}[sep=8pt,center,shadow=false,rounded=true]{title}
\usebeamerfont{title}\inserttitle\par%
\ifx\insertsubtitle\@empty%
\else%
\vskip0.25em%
{\usebeamerfont{subtitle}\usebeamercolor[fg]{subtitle}\insertsubtitle\par}%
\fi%
\end{beamercolorbox}%
\hrulefill
\vskip1em\par
\begin{beamercolorbox}[sep=8pt,center,shadow=false,rounded=true]{author}
\usebeamerfont{author}\insertauthor
\end{beamercolorbox}
\begin{beamercolorbox}[sep=8pt,center,shadow=false,rounded=true]{institute}
\usebeamerfont{institute}\insertinstitute
\end{beamercolorbox}
\begin{beamercolorbox}[sep=8pt,center,shadow=false,rounded=true]{date}
\usebeamerfont{date}\insertdate
\end{beamercolorbox}\vskip0.5em
{\usebeamercolor[fg]{titlegraphic}\inserttitlegraphic\par}
\endgroup
\vfill
}
\setbeamertemplate{blocks}[rounded][shadow=false]
\setbeamertemplate{note page}{\pagecolor{yellow!5}\insertnote}
% ============ ここを消すとNote消える ================
% \mode<handout>{%
% \setbeameroption{show notes on second screen=right}%
% }
% ============ ここを消すとNote消える ================
\renewcommand{\kanjifamilydefault}{\gtdefault}
\resetcounteronoverlays{lstlisting}
\definecolor{bluegray}{rgb}{0.4, 0.6, 0.8}
\DeclareCaptionFormat{listing}{{\color{bluegray}\lstlistingname}#2#3}
\captionsetup[lstlisting]{format=listing, font={footnotesize}}
\setmonofont[Ligatures=TeX]{CMU Typewriter Text}
\newcommand{\xcolon}{:}
\title[Generics in protocol/extension]{%
{\bfseries\rmfamily\mcfamily\huge
Generics in protocol/extension%
}%
}
\author[Hikaru Yoshimura]{%
Hikaru \textsc{Yoshimura}(吉村 優)
}
\date[try! Swift Tokyo, March 21, 2019]{%
\href{https://www.tryswift.co/events/2019/tokyo/en/}{try! Swift Tokyo on \oldstylenums{March 21, 2019}} \\
{\scriptsize (\href{https://github.com/y-yu/try-swift-slide}{\texttt{y-yu/try-swift-slide@\GITAbrHash}})}%
}
\institute[Recruit Markting Partners Co., Ltd.]{%
Recruit Markting Partners Co., Ltd.\\
\href{mailto:yyu@mental.poker}{yyu@mental.poker}
}
\input{./lib/quotebox.tex}
\input{./lib/footnotemark.tex}
\input{./lib/ballon.tex}
\input{./lib/listings.tex}
\input{./lib/stack.tex}
\input{vc.tex}
\setbeamertemplate{items}[circle]
\newcommand\ballcircle[1]{%
{%
\usebeamercolor{enumerate item}%
\tikzset{beameritem/.style={circle,inner sep=0,minimum size=2ex,text=enumerate item.bg,fill=enumerate item.fg,font=\footnotesize}}%
\tikz[baseline=(n.base)]\node(n)[beameritem]{#1};%
}
}
\newcommand\ballref[1]{%
\ballcircle{\ref{#1}}
}
\newcommand\ce[1]{%
\coloremoji{#1}
}
\newenvironment{notes}
{%
\begin{xlrbox}{NotesBox}
\begin{minipage}{.95\textwidth}
\small\rmfamily\mcfamily
\begin{itemize}
\setlength{\itemindent}{0em}
}{%
\end{itemize}
\end{minipage}
\end{xlrbox}
\note{\theNotesBox}}
\makeatletter
\newsavebox\temp@simple@callout@box
\newcommand{\simplecallout}[3]{%
\sbox{\temp@simple@callout@box}{\mbox{#3}}%
\begin{center}%
\begin{tikzpicture}%
\calloutquote[width=1.1\wd\temp@simple@callout@box,position={(#1.5,-0.2)},fill=#2,rounded corners]{
#3%
}%
\end{tikzpicture}%
\end{center}
}
\makeatother
\begin{document}
\begin{frame}
\vspace{5ex}
\centering
\maketitle
\begin{notes}
\item \textcolor{red}{この右側のページはコメントが書いてあります}
(最終的には消えます)
\item スライドが16:9になりました!
\item 基本的にスライドは英語で、発表は日本語です
\item 右側に英語の用語の日本語訳も書きます
\item ちょっと文字が多すぎるかもしれない。
ただスライドにないことを喋るのは大変だけど、
あることを当日に飛ばすのはまだ容易なので、
つくれるだけ作って練習しつつどうにかしようかな
\item Transcript:
このトークでは「どうやったらGenericsをprotocol/extension」で利用できるか?
についてHListというデータ構造の結合を例として解説する。
まずは問題について詳しく述べて、そしてSwiftのprotocol/extensionについて
Javaのインターフェースと比較しながら述べていく。
そして実はprotocol/extensionはオーバーロードのような機能があることを
利用して問題をなんとか解決する。
最後に現在のSwiftでは難しかったところについて述べて
参考文献を紹介する。
\end{notes}
\end{frame}
\begin{frame}
\frametitle{Table of Contents}
\tableofcontents
\begin{notes}
\item Transcript:
今日の流れ
\end{notes}
\end{frame}
\section{Self-introduction}
\begin{frame}
\frametitle{Self-introduction}
\begin{columns}
\begin{column}{0.3\textwidth}
\begin{center}
\begin{figure}
\includegraphics[width=0.85\textwidth]{img/face.jpg}
\end{figure}
\end{center}
\begin{table}[h]
\begin{tabular}{ll}
Twitter & \href{https://twitter.com/\_yyu\_}{@\_yyu\_} \\
Qiita & \href{https://qiita.com/yyu}{yyu} \\
GitHub & \href{https://github.com/y-yu}{y-yu} \\
\end{tabular}
\end{table}
\end{column}
\begin{column}{0.7\textwidth}
\pause
\begin{itemize}
\item University of Tsukuba (Bachelor of CS)
\begin{itemize}
\item Programming Logic Group
\end{itemize}
\item Scala engineer at
\href{http://www.recruit-mp.co.jp/}{Recruit Marketing Partners Co., Ltd.}
\item I'm interested in
\begin{itemize}
\item Cryptography
\item Functional Programming
\item Quantum Information
\item Typesetting (\LaTeX)
\end{itemize}
\end{itemize}
\end{column}
\end{columns}
\begin{notes}
\item 用語
\begin{description}
\item[Logic] 論理
\item[Scala] スカラ
\item[Cryptography] 暗号
\item[Functional Programming] 関数プログラミング
\item[Quantum Information] 量子情報
\item[\LaTeX] ラテック・ラテフ(欧米圏ではラテックらしい)
\end{description}
\item もし発表で「量子」と言ったら、それは``quantum''でおねがいしたいです。
たとえば「量子コンピュータ」は``quantum computer''とかです
\item Transcript:
筑波大学でプログラム・ロジックグループという研究室に所属し、
型システムの研究を行った。そして現在はリクルートマーケティングパートナーズにて
Scalaのサーバーサイドエンジニアをしている。
業務では関数型プログラミングをしている。
また、暗号や量子コンピュータにも興味がある。
そしてこのスライドを作るためにも利用した
組版ソフト\LaTeX を使って本を作成するといったこともしている。
\end{notes}
\end{frame}
\section{Problem}
\begin{frame}[fragile]
\frametitle{Problem}
\begin{itemize}
\item First we are thinking about these data structures: \lstinline|Tuple| and \lstinline|List|
\end{itemize}
\begin{columns}
\begin{column}{0.5\textwidth}
\begin{lstlisting}[style=swift]
struct Tuple<A, B> {
let left: A
let right: B
init(_ l: A, _ r: B) {
this.left = l
this.right = r
}
}
\end{lstlisting}
\end{column}
\begin{column}{0.5\textwidth}
\begin{lstlisting}[style=swift]
enum List<A> {
indirect case Cons(
h: A,
t: List<A>
)
case Nil
}
\end{lstlisting}
\end{column}
\end{columns}
\pause
\begin{itemize}
\item<+-> \lstinline|Tuple| represents \emph{exact two} values
for each type \lstinline|A| and \lstinline|B|
\item<+-> And \lstinline|List| represents fixed type \lstinline|A| values
whose number is \emph{more than or equal 0}
\end{itemize}
\uncover<+->{
\simplecallout{-}{blue!20}{Can we make a List which have some type values?}
}
\begin{notes}
\item 用語
\begin{description}
\item[data structure] データ造構
\item[Tuple] タプル(組)
\item[List] リスト
\item[type] 型
\item[Cons] コンス(専門用語)
\item[Nil] ニル(専門用語)
\end{description}
\item Transcript:
タプルはちょうど1つづつAとBの型を持つ値を表し、
そしてリストは1つの型Aをもつ0個以上の値を表す。
ただ、我々は違う型の値が何個でもはいる型をつくれないだろうか?
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{Heterogeneous List}
\begin{itemize}
\item We are looking at \lstinline|HList| as follows
\end{itemize}
\begin{lstlisting}[style=swift]
protocol HList {
associatedtype Head
associatedtype Tail: HList
}
\end{lstlisting}
\pause
\begin{itemize}
\item<+-> \lstinline|HList| has two \lstinline|associatedtype|: \lstinline|Head| and \lstinline|Tail|
\end{itemize}
\begin{notes}
\item 用語
\begin{description}
\item[HList] Hリスト(Heterogeneous List)
\item[type member] 型メンバー
\end{description}
\item HeadとTailも専門用語かも?
\item Transcript:
ここで今日は``HList''というデータ構造を紹介する。
HListは``Head''と``Tail''という2つの型メンバー(associatedtype)を
持つ。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{Heterogeneous List}
\begin{itemize}
\item<+-> And there are two structs: \lstinline|HCons| and \lstinline|HNil|
\end{itemize}
\begin{columns}
\begin{column}{0.45\textwidth}
\begin{lstlisting}[style=swift]
public enum Nothing { }
struct HNil: HList {
typealias Head = Nothing
typealias Tail = HNil
init() { }
static var hNil = HNil()
}
\end{lstlisting}
\end{column}
\begin{column}{0.55\textwidth}
\begin{lstlisting}[style=swift]
struct HCons<H, T: HList>: HList {
typealias Head = H
typealias Tail = T
let head: Head
let tail: Tail
init(_ h: Head, _ t: Tail) {
self.head = h
self.tail = t
}
}
\end{lstlisting}
\end{column}
\end{columns}
\uncover<+->{
\simplecallout{}{red!30}{Is it the same to \lstinline|List|?}
}
\uncover<+->{
\simplecallout{-}{green!30}{No, it's not just \lstinline|List|}
}
\begin{notes}
\item 用語
\begin{description}
\item[(H)Cons] (H)コンス
\item[struct] 構造体
\end{description}
\item Consは「コンス」という用語でOK
\item Transcript:
そして、次のような2つの構造体である``HCons''と``HNil''があり、
これらはこの図のようになっている。
これは一見するとリスト(List)のように見えるが、実は単なるリストではない。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{Heterogeneous List}
\begin{itemize}
\item<+-> \lstinline|HList| can have some values
and their type order
\end{itemize}
\begin{columns}
\begin{column}{0.3\textwidth}
\begin{uncoverenv}<+->
\begin{lstlisting}[style=swift]
let a = HCons(
1,
HCons(
true,
HCons(
"string",
HNil.hnil()
)
)
)
\end{lstlisting}
\end{uncoverenv}
\end{column}
\begin{column}{0.7\textwidth}
\begin{uncoverenv}<+->
\begin{lstlisting}[style=swift]
a: HCons<Int, HCons<Bool, HCons<String, HNil>>>
\end{lstlisting}
\end{uncoverenv}
\end{column}
\end{columns}
\begin{itemize}
\item<+-> \lstinline|List| cannot have more than 1 type, but \lstinline|HList| have any of the number of types
\end{itemize}
\uncover<+->{
\simplecallout{}{green!30}{Today, we'll consider the \lstinline|append| method of two \lstinline|HList|s}
}
\begin{notes}
\item 型はまあいいかな?(Nilがちょっと心配?)
\item ここでトークではHListのappendについて考えると導入する
\item Transcript:
HListはいくつかの値と、その値の型の順序を持つことができる。
たとえば、左の図のようにIntの1、Boolのtrue、そして文字列の"string"が並んだような
データ構造も表わすことができる。
これはSwiftの現在の処理系でコンパイルすることができ、
右図のような型がきちんとつく。
Listは1つ以上の型を持つことはできないが、
一方でHListは何種類でも型を持つことができる。
今日は、2つのHList(のインスタンス)が与えられたときに、
それらのappend(結合)を考えていきたい。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{\texttt{append} for \texttt{List}s}
\begin{itemize}
\item<+-> For now, in the case of the ordinary \lstinline|List|
\end{itemize}
\begin{uncoverenv}<+->
\begin{lstlisting}[style=swift]
func append<A>(_ a: List<A>, _ b: List<A>) -> List<A> {
switch a {
case let .Cons(h, t):
return .Cons(h, append(t, b))
case .Nil:
return b
}
}
\end{lstlisting}
\end{uncoverenv}
\begin{itemize}
\item<+-> But, \lstinline|HList| may have more than 1 type,
so it's not easy...\ce{😇}
\end{itemize}
\uncover<+->{
\simplecallout{-}{blue!20}{What should we use to implement it?}
}
\uncover<+->{
\simplecallout{}{green!30}{It's difficult for Java
but Swift has \lstinline|protocol| and \lstinline|extension|}
}
\begin{notes}
\item 用語
\begin{description}
\item[protocol] プロトコル
\item[extension] エクステンション
\end{description}
\item appendのことをトーク中は``concat(concatination)''のように言うかも
\item Transcript:
まずは普通のListについて考える。
普通のListの結合(append)はこのように再帰的(recursive)に実装できる。
このListのappendは1つ型パラメータAを使っているが、
しかしHListはいくつも型がある。
こういうときどうやって実装したらよいだろうか?
Javaでは難しいが、Swiftには``protocol/extension''があるので、
これが達成できる。
\end{notes}
\end{frame}
\section{protocol/extension}
\begin{frame}[fragile]
\frametitle{\texttt{protocol}/\texttt{extension}}
\pause
\begin{itemize}
\item<+-> Swift \lstinline|protocol| sometimes could be said
``it's similler to \lstinline|interface| of Java''
\end{itemize}
\begin{uncoverenv}<+->
\begin{columns}
\begin{column}{0.55\textwidth}
\begin{lstlisting}[style=java, caption={Java interface}]
interface JsonWrite<A> {
public JSON toJson(A a);
}
class User(???) implements JsonWrite<User> {
public JSON toJson(User a) {
???
}
}
\end{lstlisting}
\end{column}
\begin{column}{0.45\textwidth}
\begin{lstlisting}[style=swift, caption={Swift protocol}]
protocol JsonWrite {
associatedtype A
func toJson(_ a: A) -> JSON
}
class User: JsonWrite {
typealias A = User
func toJson(_ a: A) -> JSON {
???
}
}
\end{lstlisting}
\end{column}
\end{columns}
\end{uncoverenv}
\uncover<+->{
\simplecallout{}{green!30}{It's not at all...}
}
\begin{notes}
\item 用語
\begin{description}
\item[interface] インターフェース
\item[JSON] JSON(ジェイソン)
\item[Haskell] ハスケル
\end{description}
\item Transcript:
ここでSwiftが持つprotocol/extensionについて考える。
これは僕がSwiftを好きに思う理由の1つで、とてもおもしろい機能である。
HaskellやScalaにも、このような機能があるがJavaにはないと思う。
ただ、しばしば「SwiftのprotocolはJavaのinterfaceに似ている」と
言われることがある。たしかに次のようなJSONに変換できるような
protocolである``JsonWrite''を考えると、今``User''が
``JsonWrite''を実装する(implement)、または適合する(conform)ことを
JavaとSwiftでそれぞれ同じように書ける。
これだけだと確かに似ているが、ただそれだけではない。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{\texttt{protocol}/\texttt{extension}}
\begin{itemize}
\item<+-> If we need to extend a fixed data type such a \lstinline|Integer|
\item<+-> However in Java, we cannot extend a fixed data type so
we can't help but to use the \emph{Adapter pattern}
\end{itemize}
\begin{columns}
\begin{column}{0.6\textwidth}
\begin{uncoverenv}<.->
\begin{lstlisting}[style=java, caption={Adapter pattern in Java}]
class RichInteger implements JsonWrite<Integer> {
public Integer n;
public RichInteger(Integer i) {
this.n = i
}
public JSON toJson(Integer a) {
???
}
}
\end{lstlisting}
\end{uncoverenv}
\end{column}
\begin{column}{0.4\textwidth}
\begin{uncoverenv}<+->
\begin{lstlisting}[style=swift, caption={\texttt{extension} in Swift}]
extension Int: JsonWrite {
typealias A = Int
func toJson(_ a: Int) -> JSON {
???
}
}
\end{lstlisting}
\end{uncoverenv}
\end{column}
\end{columns}
\begin{itemize}
\item<.-> But Swift has \lstinline|extension|,
which find the function by the given types
\end{itemize}
\begin{notes}
\item 用語
\begin{description}
\item[Adapter pattern] アダプターパターン
\end{description}
\item Transcript:
もし、すでに固まってしまったIntegerのようなデータ構造をJSONに変換
したくなったとき、どうしたらよいだろうか。
このような固定されたデータ構造は、たとえばプログラミング言語のコアや
あるいは他人のライブラリーなどで定義された型であって、
我々の努力で今つくったJsonWriteを使ってもらうのは不可能である。
こういうとき、JavaではAdapter patternという手法で次のような
RichIntegerのような型を新たにつくって対処することがしばしばある。
これはこれで動作はするが、しかし我々の関心はIntegerから
RichIntegerへ移動してしまった。これによりプログラムの複雑さが不必要に
高まってしまう。一方でSwiftはextensionにより、この問題をスマートに解決できる。
すでにフィックスされた型に対して、アドホックに機能を付け加えることが容易にできる。
これはextensionが「型から機能を探してくる」という能力を持っているからである。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{\texttt{protocol}/\texttt{extension}}
\uncover<+->{
\simplecallout{}{red!30}{What is the meaning of finding functions by the types?}
}
\begin{itemize}
\item<+-> For example, let's think about \emph{overloading} like following
\end{itemize}
\begin{uncoverenv}<.->
\begin{columns}
\begin{column}{0.5\textwidth}
\begin{lstlisting}[style=swift]
1 + 1 // 2
\end{lstlisting}
\end{column}
\begin{column}{0.5\textwidth}
\begin{lstlisting}[style=swift]
"hot" + "dog" // "hotdog"
\end{lstlisting}
\end{column}
\end{columns}
\end{uncoverenv}
\begin{itemize}
\item<+-> Operator \lstinline|+| has two behaviors:
\begin{itemize}
\item \lstinline|(Int, Int) -> Int|
\item \lstinline|(String, String) -> String|
\end{itemize}
\item<+-> So Swift looks up a suitable function by
the arguments' types
\item<+-> \lstinline|extension| is simillar like overloading
\end{itemize}
\begin{notes}
\item 用語
\begin{description}
\item[overload] オーバーロード
\item[operator] 演算子
\item[argument] 引数
\end{description}
\item Transcript:
「型から機能を探してくる」とはどういうことだろうか。
これの簡単な例として``overload''がある。
おなじ``+''という関数または演算子だが、
引数によって左の例では加算となり、右の例では文字列の連結(concatination)となる。
これは+に引数の型に応じて少なくとも2つの振る舞いがあり、
もし引数の型がIntとIntならば足し算としてIntを返し、
そしてもしStringとStringならば文字列の連結としてStringを返す。
つまり、Swiftが適切な機能を引数の型から探してきてくれる。
extensionはこれに似た振る舞いをする。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{\texttt{protocol}/\texttt{extension}}
\begin{itemize}
\item<+-> We can write \lstinline|+| function using
\lstinline|protocol| and \lstinline|extension|
\end{itemize}
\begin{uncoverenv}<.->
\begin{lstlisting}[style=swift]
protocol Plusable {
associatedtype A
func +(_ a: A, _ b: A) -> A
}
\end{lstlisting}
\begin{columns}
\begin{column}{0.5\textwidth}
\begin{lstlisting}[style=swift]
extension Int: Plusable {
typealias A = Int
func +(_ a: A, _ b: A) -> A {
// `Int.plus` maybe not exist...
return Int.plus(a, b)
}
}
\end{lstlisting}
\end{column}
\begin{column}{0.5\textwidth}
\begin{lstlisting}[style=swift]
extension String: Plusable {
typealias A = String
func +(_ a: A, _ b: A) -> A {
return a.stringByAppendingString(b)
}
}
\end{lstlisting}
\end{column}
\end{columns}
\end{uncoverenv}
\begin{itemize}
\item<+-> Overloading can be done by \lstinline|protocol| and \lstinline|extension|
\end{itemize}
\begin{notes}
\item Transcript:
オーバーロードのようなことができると示すために、
この+をprotocol/extensionで書いてみる。
``Plusable''というprotocolをつくり、それのextensionとして
IntとStringにそれぞれ+演算子を定義する。
このように、オーバーロードがすることはprotocol/extensionで
同じように行うことができる。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{\texttt{protocol}/\texttt{extension}}
\begin{itemize}
\item<+-> \lstinline|extension| can use another
\lstinline|extension| defined by a \lstinline|protocol|
\end{itemize}
\begin{uncoverenv}<.->
\begin{lstlisting}[style=swift]
extension Array: JsonWrite where Element: JsonWrite {
typealias A = Array<Element>
func toJson(_ a: Array<Element>): JSON {
???
}
}
\end{lstlisting}
\end{uncoverenv}
\uncover<+->{
\simplecallout{}{green!30}{%
Can we make the \lstinline|append| for \lstinline|HList|s
by \lstinline|extension|?}
}
\begin{notes}
\item Transcript:
さらにextensionは他のprotocolで定義されたextensionを
使うこともできる。
たとえばここでは``Array''にさきほどのJsonWriteを適合させている。
ただし``where''句をともなって、Arrayの型パラメータAが
JsonWriteに適合しているならば、Array<A>もJsonWriteに
適合するといったことが書ける。
このextensionを使えばHListのappendを作れるのでは?
\end{notes}
\end{frame}
\section{Implementation}
\begin{frame}[fragile]
\frametitle{Implementation}
\begin{itemize}
\item<+-> This is a \lstinline|append| for two normal \lstinline|List|s
\end{itemize}
\begin{uncoverenv}<.->
\begin{lstlisting}[style=swift]
func append<A>(_ a: List<A>, _ b: List<A>) -> List<A> {
switch a {
case let .Cons(h, t):
return .Cons(h, append(t, b))
case .Nil:
return b
}
}
\end{lstlisting}
\end{uncoverenv}
\begin{itemize}
\item<+-> This \lstinline|append| has two cases depending on
the first argument
\begin{itemize}
\item If it is \lstinline|Cons(h, t)|,
then the \lstinline|append| calls itself
passing \lstinline|t| as the first argument recursively
\item If it is \lstinline|Nil|,
then the function returns the second argument
\end{itemize}
\item<+-> This \lstinline|append| is using \emph{run time} dispatching,
but we want to dispatch in \emph{compile time}
\end{itemize}
\begin{notes}
\item 用語
\begin{description}
\item[recursively] 再帰的に
\item[run time] ランタイム
\item[compile time] コンパイルタイム
\end{description}
\item Transcript:
もう一度、普通のリストのappendを見てみると、
これは最初の引数によって2つに場合分けしている。
もしそれがCons(h, t)ならば、appendを再帰的に呼び出し
一方でNilならば第二引数をそのまま返す。
つまりリストの長さによって挙動を変更しているが、
リストの長さはランタイムの情報である。
ただ、HListは型が要素の順番に並んでいるので、
型として長さを持っている。型はコンパイルタイムの情報なので、
コンパイルタイムに挙動を変更しなければならない。
ここでextensionを利用する。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{Implementation}
\begin{itemize}
\item<+-> We are making a \lstinline|protocol| for the \lstinline|HList|s \lstinline|append| as follows
\end{itemize}
\begin{uncoverenv}<.->
\begin{lstlisting}[style=swift]
protocol HAppend {
associatedtype Left: HList
associatedtype Right: HList
associatedtype Result: HList
static func append(_ l1: Left, _ l2: Right) -> Result
}
\end{lstlisting}
\end{uncoverenv}
\begin{itemize}
\item<+-> Then we'll think about its \lstinline|extension|
\end{itemize}
\begin{notes}
\item Transcript:
ということで、まずは``HAppend''というHListのappendのprotocolを定義する。
これはLeftとRightという2つのHListを取り、それを結合した結果の
ResultというHListを返す関数appendをあらわすprotocolである。
これのextensionがどうなるかを今後は考えていく。
\end{notes}
\end{frame}
\begin{frame}[fragile]
\frametitle{Implementation}
\begin{itemize}
\item<+-> First we can create a pettern for that the
first argument is \lstinline|HNil|
\end{itemize}
\begin{uncoverenv}<.->
\begin{lstlisting}[style=swift]
class App1<A: HList> {
init() {}
}
extension App1: HAppend {
typealias Left = HNil
typealias Right = A
typealias Result = A
static func append(_ l1: HNil, _ l2: A) -> A {
return l2
}
}
\end{lstlisting}
\end{uncoverenv}
\begin{itemize}
\item<+-> It just returns the second argument
\end{itemize}
\begin{notes}
\item Transcript:
ということで、まずは簡単そうなHNilのケースから考えよう。
HList版appendの最初の引数は、associatedtype Leftで
与えられるので、それがHNilであった場合を考える。
これは単に第二引数のHListをそのまま返せばいいが、
ただここで問題となるのは第二引数を表すHListの型が手元にない。
extensionが型パラメータを取れたらいいが、それはできないので、
適当な型App1を作って対処することにする。
\end{notes}
\end{frame}
\begin{frame}[fragile]