Protocol-Oriented Integers に想うジェネリックプログラミングの未来

>100 Views

October 03, 17

スライド概要

Protocol-Oriented Integers を目にして感じたことを 15 分の資料に綴ってみました。すごくざっくりとした説明で掴みきれないところもあると思うのですけど、今までとはちょっと違う視点でジェネリクスを見つめ直すきっかけになってくれたら幸いです。

※ Docswell での公開に移行する直前の Slideshare での閲覧数は 3,275 でした。

profile-image

正統派趣味人プログラマー。プログラミングとは幼馴染です。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

1SPUPDPM0SJFOUFE*OUFHFSTʹ૝͏ δΣωϦοΫϓϩάϥϛϯάͷະདྷ ‫۽‬୩༑޺ !FT@LVNBHBJ Զίϯ7PM%BZ5SBDL$ 4XJGUͰ1SPUPDPM0SJFOUFE*OUFHFST͕ొ৔͠ɺϓϩάϥϛϯάͷࡏ Γํ͕৽‫ہ‬໘Λܴ͑Α͏ͱ͍ͯ͠ΔΑ͏ʹ‫͢·͡ײ‬ɻಛผͩͬͨδΣω ϦοΫͷੈք͕೔ৗతʹͳΔ͔΋͠Εͳ͍ɻৼΓฦΕ͹$PMMFDUJPOͱ ͔'MPBUJOH1PJOUͱ͔ɺͦΕΛ‫͡ײ‬Δ৔໘ͬͯલ͔ΒࡏͬͨΜͰ͢ΑͶɻ ͦΜͳ͜ͱʹ૝͍Λ஘ͤͳ͕Βɺ؆୯ʹͰ͸͋Γ·͚͢ΕͲ1SPUPDPM 0SJFOUFE*OUFHFST͕ඳ͘ੈքΛΈΜͳͱோΊΒΕͨΒ‫͢Ͱ͍͠خ‬ɻ

2.

1SPUPDPM0SJFOUFE *OUFHFSTʹ૝͏δΣωϦοΫϓϩάϥϛϯάͷະདྷ

3.

‫۽‬୩༑޺ 5PNPIJSP,VNBHBJ ⾣ 4XJGU‫͕ޠݴ‬௒େ޷͖Ͱ͢ʂ ⾣ ΈΜͳͰָ͠Ήษ‫ڧ‬ձ͕େ޷͖Ͱ͢ʂ ⾣ ϓϩάϥϛϯάͷָ͠͞Λ఻͍͖͍͑ͯͨɻ w ωοτϥδΦ w ษ‫ڧ‬ձͷ஍ํ։࠵ w ಉਓࢽଈചձ

4.

4XJGU 1SPUPDPM0SJFOUFE*OUFHFSTొ৔

5.

1SPUPDPM0SJFOUFE*OUFHFSTొ৔  ੔਺‫ܕ‬ΛϓϩτίϧͰද‫ݱ‬ʢϓϩτίϧࢦ޲੔਺ʣ  ‫ʹܕ‬റΒΕͳ͍੔਺ૢ࡞͕Մೳʹͳͬͨ

6.

1SPUPDPM0SJFOUFE*OUFHFSTొ৔ ੔਺‫ܕ‬ΛϓϩτίϧͰද‫ݱ‬ 4JHOFE*OUFHFS 6OTJHOFE*OUFHFS ූ߸෇͖੔਺ ූ߸ͳ͠੔਺ 4JHOFE/VNFSJD #JOBSZ*OUFHFS 'JYFE8JEUI*OUFHFS ‫ݻ‬ఆ෯੔਺ Ϗοτද‫͞ݱ‬Εͨ਺ ූ߸෇͖਺ $VTUPN4USJOH$POWFSUJCMF ஋ΛςΩετද‫ݱ‬Մೳ /VNFSJD )BTIBCMF &RVBUBCMF ϋογϡΛऔಘՄೳ ౳Ձൺֱ͕Մೳ ਺ &YQSFTTJCMF#Z*OUFHFS-JUFSBM 4USJEFBCMF େখൺֱ͕Մೳ $PNQBSBCMF େখൺֱ͕Մೳ ੔਺ϦςϥϧͰද‫ݱ‬Մೳ

7.
[beta]
1SPUPDPM0SJFOUFE*OUFHFSTొ৔

‫ʹܕ‬റΒΕͳ͍੔਺ૢ࡞͕Մೳʹ
⾣

ͨͱ͑͹l‫ܕ‬͸ͳΜͰ΋͍͍͚ΕͲɺ਺zͱ͍͏ද‫ݱ‬

⾣

਺ͱ͍͏֓೦ͰίʔυΛ૊ΈཱͯΔ

func sum<T : Numeric>(of values: Array<T>) -> T {
return values.reduce(0) { $0 + $1 }
}
// Int の配列でも、Float の配列でも、使える
let integers = [5, 5, 5, 5]
let floats = [2.5, 2.5, 2.5, 2.5] as [Float]

sum(of: integers)
sum(of: floats)

// 20
// 10

8.

(FOFSJDT

9.

δΣωϦοΫϓϩάϥϛϯά  ‫ʹܕ‬റΒΕͳ͍ϓϩάϥϛϯά  ‫ܕ‬Λ௒͑ͨίʔυͷ൚༻Խ͕ՄೳʹͳΔʁ  δΣωϦοΫ͸্‫͚޲ऀڃ‬ͷߴ౳ٕ๏ʁ

10.
[beta]
δΣωϦοΫϓϩάϥϛϯά

‫ʹܕ‬റΒΕͳ͍ϓϩάϥϛϯά
⾣

‫ܕ‬͸ͳΜͰ΋͍͍ͱ͍͏ߟ͑ํ

⾣

਺ͱ͍͏֓೦ͰίʔυΛ૊ΈཱͯΔ
‫ܕ‬͸ͳΜͰ΋͍͍͚ΕͲ
$PMMFDUJPOʹ૬౰͢Δ΋ͷͶ

ͦΜͳ$PMMFDUJPOΛ
ड͚औͬͯʜ

$PMMFDUJPO͕ѻ͏
ཁૉΛฦ͠·͔͢ΒͶ

func average <C: Collection> (of values: C ) -> C.Element
where C.Element : BinaryInteger {
ͨͩ͠ɺ͜Ε͸$PMMFDUJPO͕ѻ͏ཁૉ͕
#JOBSZ*OUFHFSʹ‫ͯͬݶ‬੒ΓཱͭίʔυͰ͢
͋ͱ͸ɺ֓೦ͷൣᙝͰ
ίʔυΛ૊Έཱͯͯߦ͘ʜ

return values.reduce(into: 0, +=) / C.Element(values.count)
}

11.

δΣωϦοΫϓϩάϥϛϯά ‫ܕ‬Λ௒͑ͨίʔυͷ൚༻Խ͕ՄೳʹͳΔʁ ⾣ ࠓ·Ͱ͸ΦʔόʔϩʔυͰද‫͍ͨͯ͠ݱ‬ίʔυ͕൚༻తʹॻ͚Δ ⾣ ଘࡏҙٛ͸lίʔυͷ൚༻ԽzͳͷͩΖ͏͔ʁ GVODTVN PGWBMVFT"SSBZ*OU *OU GVODTVN PGWBMVFT"SSBZ*OU *OU GVODTVN PGWBMVFT"SSBZ*OU *OU GVODTVN PGWBMVFT"SSBZ*OU *OU GVODTVN PGWBMVFT"SSBZ*OU *OU GVODTVN PGWBMVFT"SSBZ6*OU 6*OU GVODTVN PGWBMVFT"SSBZ6*OU 6*OU GVODTVN PGWBMVFT"SSBZ6*OU 6*OU GVODTVN PGWBMVFT"SSBZ6*OU 6*OU GVODTVN PGWBMVFT"SSBZ6*OU 6*OU GVODTVN PGWBMVFT"SSBZ%PVCMF %PVCMF GVODTVN PGWBMVFT"SSBZ'MPBU 'MPBU GVODTVN5/VNFSJD PGWBMVFT"SSBZ5 5 ଘࡏҙٛʹlίʔυͷ൚༻Խz͕͋Δͷ͸ ฆΕ΋ͳ͘ɺਖ਼͍͜͠ͱͳͷ͚ͩΕͲʜ

12.
[beta]
δΣωϦοΫϓϩάϥϛϯά

਎ۙʹ΋ࡏΔδΣωϦοΫ
⾣

ඪ४ϥΠϒϥϦʔͰ΋δΣωϦοΫ͸࢖ΘΕ͍ͯΔ

⾣

഑ྻͷม‫׵‬ΠχγϟϥΠβʔ͸਎ۙͳଘࡏ

extension Array {
// 変換元は、要素の型が同じならどんな Sequence でも良い
init<S:Sequence>(_ s: S) where Element == S.Element

}
// どんな Sequence も配列型に変換できる
Array ( [1, 5, 8, 3, 7, 3] )
Array ( [1, 5, 8, 3, 7, 3][2 ..< 5] )
Array ( 1 ..< 20)
Array ( zip([1, 3, 5], [2, 4, 6]))

// Array
// ArraySlice
// CountableRange
// Zip2Sequence<Array, Array>

13.
[beta]
δΣωϦοΫϓϩάϥϛϯά

͜ΕͩͬͯδΣωϦοΫද‫ݱ‬ͷͻͱͭ
// この書き方はパッと思いつかなくても、

func sum<T : Numeric>(of values: Array<T>) -> T {
return values.reduce(into: 0, +=)
}

ද‫ݱ‬ͷຊ࣭͸
ͲͪΒ΋ಉ͡

// こちらなら自然と書ける人も多いはず(上記より Swift らしいと思う)

extension Array where Element : Numeric {
func sum() -> Element {
return reduce(into: 0, +=)
}
}

14.

δΣωϦοΫϓϩάϥϛϯά δΣωϦοΫ͸্‫͚޲ऀڃ‬ͷߴ౳ٕ๏ʁ ⾣ ֓೦Ͱ֓೦ΛίʔσΟϯά͢Δख๏ w ର৅ΛlΓΜ͝zͰ͸ͳ͘l਺͑ΒΕΔ΋ͷ̍ͭzͱଊ͑ͨΑ͏ͳ΋ͷ w ͨͱ͑͹lΓΜ͕̎ͭ͝zͰ͸ͳ͘l zͱ͍͏ද‫ํݱ‬๏ ⾣ ͻͱͭͷύϥμΠϜͱଊ͑ͯ͸Ͳ͏ͩΖ͏ w ΦϒδΣΫτࢦ޲ͰlΫϥε͸೉͍͔͠Βzͱආ͚Δ͜ͱ͸͠ͳ͍ w ೉͘͠ࢥ͑Δ΋ͷ΋ɺड͚ೖΕΔͱͦͷจԽ‫Ͱݍ‬͸Ҋ֎ී௨ͩͬͨΓ͢Δ ⾣ ΋͔ͯ͠͠ɺ͜Ε͕lϓϩτίϧࢦ޲zͱ͍͏ύϥμΠϜʁ w Ԡ༻ٕज़ͱͯ͠ొ৔ͨ͠ͷ͸ؒҧ͍ͳ͍ͱࢥ͏ w ͨͩ͠ࠓɺͦͷৗࣝΛ௒͑ͨੈքΛඳ͜͏ͱ͍ͯ͠ΔΑ͏ʹࢥ͑Δ w ߴ౳ٕ๏Ͱ͸ͳ͘‫ͱૅج‬ଊ͑Δͱ৽͍͠ະདྷ͕୓͚ͦ͏ͳ༧‫͕͢ײ‬Δ

15.

ϓϩτίϧࢦ޲ͷະདྷ΁ ண࣮ʹาΈΛਐΊΔ4XJGU

16.

ϓϩτίϧࢦ޲ϓϩάϥϛϯάͷະདྷ΁ 4XJGU ⾣ ϓϩτίϧͰ‫ܕ‬Λઆ໌͢Δͱ͍͏ੈք‫؍‬ ⾣ ੑ࣭ΛϓϩτίϧͰ‫ن‬ఆ͠ɺͦΕͰ‫ܕ‬Λઆ໌͢Δ struct Array : MutableCollectionType, Sliceable, "SSBZ‫ܕ‬ɺ ArrayLiteralConvertible { ͭ·Γ഑ྻ͸ʜ ಺༰ΛมߋՄೳͳ ཁૉͷू߹Ͱ͋Γɺ ෦෼ཁૉͰ ੾Γग़͠Մೳͳ΋ͷͰɺ ഑ྻϦςϥϧ͔Β ม‫׵‬Մೳͳ΋ͷɻ ۩ମతʹ࣮૷Λ‫ͯ͘ͳݟ‬΋ Կ͕Ͱ͖Δ͔૝૾Ͱ͖Δ }

17.
[beta]
ϓϩτίϧࢦ޲ϓϩάϥϛϯάͷະདྷ΁

4XJGU
⾣

ϓϩτίϧ֦ுͱ͍͏ੈք‫؍‬

⾣

ओମΛ۩৅ੈք͔Βந৅ੈք΁ͱҠߦʢύϥμΠϜγϑτͷ‫ݪى‬ʁʣ

// Swift 1 は“写像(map)”が主体
func map<C:CollectionType, T>(source: C,
transform: (C.Generator.Element) -> T) -> [T]
lࣸ૾͕ίϨΫγϣϯΛड͚औΔz
ͱ͍͏Ձ஋‫؍‬

// Swift 2 は“コレクション”が主体
extension CollectionType {

lίϨΫγϣϯ͕ࣸ૾ͱ͍͏֓೦Λ࣋ͭz
ͱ͍͏Ձ஋‫؍‬

func map<T>(transform: (Generator.Element) -> T) -> [T]
}

18.

ϓϩτίϧࢦ޲ϓϩάϥϛϯάͷະདྷ΁ 4XJGU  ුಈখ਺఺਺Λ֓೦Ͱද‫ݱ‬ w 'MPBUJOH1PJOUϓϩτίϧ  ‫Ͱܕ‬͸ͳ͘ϓϩτίϧ͚ͩͰ ුಈখ਺఺਺ΛૢΕΔΑ͏ʹͳͬͨ

19.

ϓϩτίϧࢦ޲ϓϩάϥϛϯά ුಈখ਺఺਺Λ֓೦Ͱද‫ݱ‬ #JOBSZ'MPBUJOH1PJOU &YQSFTTJCMF#Z'MPBU-JUFSBM *&&&ͷ'MPBUJOH1PJOU #JOBSZ5ZQFʹ‫ݻ‬༗ͷఆٛ ුಈখ਺఺਺ϦςϥϧͰ ද‫ݱ‬Մೳ 'MPBUJOH1PJOU 4JHOFE/VNFSJD *&&&ͷ࠷΋‫ج‬ຊ෦෼ DMBVTF Λఏ‫͢ڙ‬Δ ූ߸෇͖਺ &YQSFTTJCMF#Z*OUFHFS-JUFSBM ੔਺ϦςϥϧͰද‫ݱ‬Մೳ )BTIBCMF /VNFSJD ϋογϡΛऔಘՄೳ ਺ 4USJEFBCMF େখൺֱ͕Մೳ $PNQBSBCMF &RVBUBCMF େখൺֱ͕Մೳ ౳Ձൺֱ͕Մೳ

20.
[beta]
ුಈখ਺఺਺Λ֓೦Ͱද‫ݱ‬

ුಈখ਺఺਺ͱ͍͏֓೦ͰίʔυΛඳ͚Δ
⾣

%PVCMF΋'MPBU΋lුಈখ਺఺਺zͱ‫ׅͯͬ‬ѻ͑Δ

⾣

ͨͩ͠ීஈɺුಈখ਺఺਺ͷ‫ܕ‬Λҙࣝ͢Δ৔໘͸‫ۃ‬Ίͯ‫ك‬

func areaOfCircle<T:FloatingPoint>(withRadius radius: T) -> T {
return radius * radius * T.pi
}
areaOfCircle(withRadius: 2 as Double)
areaOfCircle(withRadius: 2 as Float)
areaOfCircle(withRadius: 2 as Float80)

// 12.566370614359172
// 12.56637
// 12.566370614359172464

21.

ϓϩτίϧࢦ޲ϓϩάϥϛϯά 4XJGU  ੔਺Λ֓೦Ͱද‫ݱ‬ w #JOBSZ*OUFHFSϓϩτίϧ w /VNFSJDϓϩτίϧ ʢ͓ͦΒ͘ະ‫׬‬੒ʣ  ੔਺ͱ͍͏ɺ ‫ݱ‬୅ϓϩάϥϛϯάͷ‫͕֓װج‬೦Ͱද‫͞ݱ‬Εͨ

22.
[beta]
4XJGU

੔਺͕֓೦Ͱද‫͞ݱ‬Εͨ
⾣

ͲͪΒ͕ద੾ͳද‫͑ݴͱݱ‬ΔͩΖ͏ɻ

⾣

ΈΜͳͷ‫ݟ‬ղ͕Ұக͢Δͷ͸4XJGU͘Β͍ʁʢ૝૾ʣ

extension String {
// 現在主流の API ද‫ݱ‬
func repeated(_ count: Int) -> String
// Protocol-Oriented Integers を用いた API ද‫ݱ‬
func repeated<T:BinaryInteger>(_ count: T) -> String

}
"*".repeated(5)

// "*****"

23.
[beta]
4XJGU

ͦΕͰ΋ූ߸ͱ͍͏֓೦ͷ֞ࠜ͸େ͖͍
⾣

‫܁‬Γฦ͢਺͸Ҏ্͕ී௨

⾣

͔ͩΒͱ6OTJHOFE*OUFHFSʹറΔͱ‫ܕ‬ม‫͕׵‬ඞཁʹͳΔ

extension String {
func repeated<T:UnsignedInteger>(_ count: T) -> String
}
FSSPSBSHVNFOUUZQF*OUEPFTOPUDPOGPSNUPFYQFDUFEUZQF6OTJHOFE*OUFHFS

"*".repeated(5)

24.

4XJGU δΣωϦοΫΛ‫ج‬ຊͱ‫͡ײ‬Δͱࢹ఺͕มΘΔ ϓϩτίϧࢦ޲ͷຊ֨తͳນ։͚ͳͷ͔΋͠Εͳ͍

25.

2"

26.

NPPLNPPLSBEJP NPPL ‫۽‬୩ͱ៸໘͕ϓϩάϥϛϯάίʔυͷ಺͔Β ௌ͑ͯ͘͜Δ੠ʹࣖΛ܏ָ͚ͯ͠ΉϥδΦ ͖Ε͍ͳϓϩάϥϜίʔυʹ͸ɺॻ͍ͨਓͷ૝͍͕ͨ͘͞ΜࠐΊΒΕ͍ͯ·͢ɻͦΜͳίʔυ ʹ·͙ͬ͢ҙࣝΛ޲͚ͨͱ͖ɺͦͷ૝͍ͷ੠͕ௌ͖͑ͯ͜·͢ɻͦΕ͸ͱͯ΋ඒͯ͘͠ɺௌ͘ ΄ͲʹࠍΕࠍΕͱͯ͠͠·͏΄ͲɻϓϩάϥϜ͕૗ͰΔૉఢͳ੠ΛɺҰॹʹָ͠Έ·͠ΐ͏ɻ  ຖ݄ୈ̎ɾୈ̐ ݄༵೔ ʹ഑৴ IUUQLFQDNPPLNPPLSBEJPDPN ⾣ ୈ࿩  1SPQFSUZͷੈք‫؍‬Λ௫ΜͰΈͨͯ͘ ⾣ ୈ࿩  ‫ޠݴ‬ͷັྗΛ‫ޠ‬Β͏ձ ⾣ ୈ࿩  JOUFSGBDFͱQSPUPDPM ⾣ ୈ࿩  ͋ͷ೔Έͨ"OZͱ!PCKDΛɺ΋͏͍ͪͲɻ ⾣ ୈ࿩  !PCKD ⾣ ୈ࿩  "OZ ⾣ ୈ࿩  δΣωϦοΫϓϩάϥϛϯά

27.

&OKPZ4XJGU 5IBOLZPV ‫۽‬୩༑޺ !FT@LVNBHBJ