Share
Embed
Transcript
39 slides
-
@Linda_pp @rhysd • ࣗ࡞ݴޠͷίϯύΠϥΛͭͬͨ͘Γ • Electron ͰσεΫτοϓΞϓϦΛͭͬͨ͘Γ • Vim
script Ͱ Vim ϓϥάΠϯΛͭͬͨ͘Γ͠ ͯ·͢ -
ίϯύΠϥΛʰҭͯΔʱ • طଘݴޠͷ αϒηοτ ͱͯ͠࠷ ݶͷػೳΛ ࣮ • ΄͍͠ػೳ Λ֦ுͱ͠
࣮ͯ͢Δ • ΦϦδφϧ ͷߏจʹஔ ͖͑ͯԶ ݴޠʹ͢Δ -
GoCaml ͱ • https://github.com/rhysd/gocaml • ϛχϚϧͳ OCaml ͷαϒηοτ • ࣮4000ߦఔ
• ੩తܕ͚ɼܕਪɼCݴޠ֦ு • MinCaml (※) ͷ࣮ϕʔε • ৄ͘͠ GoCon ͷࢿྉΛޚཡ͍ͩ͘͞ɿhttp://bit.ly/2wmG6Us ˞IUUQTHJUIVCDPNFTVNJJNJODBNM -
GoCamlΛʰҭͯΔʱ • MinCaml Λ ࢀߟʹͯ͠ ࠷ݶͷػ ೳ࣮ • ΄͍͠ػೳΛ ֦ுɾ࣮͢
Δʢଟ૬ܕɼ நσʔλܕɼ ύλʔϯϚο νʣ • ΦϦδφϧ ͷߏจʹஔ ͖͑Δɹ ʢ·ͩʣ -
let rec fizzbuzz max = let rec fb n =
if n % 15 = 0 then println_str "fizzbuzz" else if n % 3 = 0 then println_str "fizz" else if n % 5 = 0 then println_str "buzz" else println_int n in let rec go n = if n = max then () else (fb n; go (n+1)) in go 1 in let max = 100 in fizzbuzz max ؔఆٛࣜ MFUSFDGYFJOF ωετͨؔ͠ఆٛ ϧʔϓແ͍ͷͰ࠶ ؼؔΛ͏ ݅ذͷJGࣜ JGFUIFOFFMTFF ؔݺͼग़͠ GFFʜ มఆٛ MFUYFJOF ͦͷଞɼྻɼλϓϧɼ PQUJPOܕͳͲʜ Ϋϩʔδϟ -
ͳͥطଘݴޠͷαϒηοτͱ͠ ͯ·࣮ͣ͢Δͷ͔ • ߏจͷσβΠϯΛઌʹΖ͏ͱͯͭ͠·͔ͣͳ͍ • ߏจղੳίϯύΠϥͷೖΓޱͰ͔͠ͳ͍ͷʹɼͦ͜ʹ ؾΛऔΒΕ͕ͪ • ʮͲ͏͍͏ߏจ͕ྑ͍ͷ͔࣮ࡍʹॻ͍ͯಈ͔ͯ͠Έͳ͍ ͱͳ͔ͳ͔͔Βͳ͍
㲗 ίϯύΠϥΛ࣮͠ͳ͍ͱಈ͔ ͤͳ͍ʯͱ͍͏δϨϯϚΛղফ͢Δ • ·ͣಈ͘ίϯύΠϥΛ࣮͔ͯ͠Βɼಈ͔͠ͳ͕Βޙ͔ ΒࣗͷݴޠͷߏจΛσβΠϯ͍ͯ͘͠ํ -
ͳͥطଘݴޠͷαϒηοτͱ͠ ͯ·࣮ͣ͢Δͷ͔ • طଘݴޠطʹಈ͍͍ͯΔ࣮͕͋Δ • ઈରʹ࣮Ͱ͖Δ҆৺ײ͕͋Δ • ύʔαͷ࣮Λ·ͣྲྀ༻Ͱ͖Δ • ࣮ʹ٧·ͬͨ࣌ʹطଘݴޠͷॲཧܥʢGoCaml
ͷ߹ OCamlʣͷڍಈɾ࣮ΛࢀߟʹͰ͖Δ • ಈ͘࠷ݶͷ࣮Λૣ࣮֬͘ʹͭ͘Δͱ͜ΖΛୈҰʹ͢ Δ -
GoCaml ͷίϯύΠϥ֓ཁ ιʔε ίʔυ τʔΫ ϯྻ நߏ จ தؒද ݱ
--7. *3 Ξηϯ ϒϦ T ΦϒδΣ Ϋτ P ࣮ߦϑΝ Πϧ ϥϯλ ΠϜ P ϥϯλ ΠϜ D ϦϯΧ ࣈ۟ղੳ ߏจղੳ Ћม ܕਪ ,ਖ਼نԽ Ϋϩʔδϟม (PͰࣗલ࣮ --7.͕όοΫΤϯυ $Ͱ࣮ MJCHD ৄ͘͠IUUQCJUMZXN(6T ࠷దԽ -
ߏจ Ћม ܕਪ ʢܕνΣοΫʣ தؒදݱͷϑΥʔ Ϛοτม Ϋϩʔδϟ ม ιʔείʔυΛߏจʹύʔε͢Δ ʢgoyaccʣ
શͯͷγϯϘϧʹҰҙͷ ID ΛৼΔɽείʔ ϓΛղܾ ୯૬ܕͷγϯϓϧͳܕγεςϜɽHMܕਪ ΞϧΰϦζϜΛͬͯਪ ߏ͔ΒSSAʢ୯Ұೖʣܗࣜͷ໋ྩྻ ม͢Δ ωετͨؔ͠ɾΫϩʔδϟͷղܾ -
GoCaml ୈ1ஈ֊ͷ࣮ • ϕʔεͱͳΔ࠷ݶͷػೳΛ࣋ͬͨݴޠΛૣ࣮֬͘ʹͭ͘Δ • MinCaml ڭҭ༻ݴޠͳͷͰ࣮͕γϯϓϧͰࢀߟʹ͍͢͠ɽόοΫ ΤϯυLLVMΛ͏ • ΞϧϑΝมɼܕਪɼΫϩʔδϟมɼதؒݴޠมɼLLVM
IRมͳ Ͳͷ֤ஈ֊Ͱ͔ͬ͠ΓςετΛॻ͘ʢ4000ߦͷίʔυϕʔεʹରͯ͠477 ςετέʔεʣ • ಈ͘Α͏ʹͳͬͨΒ࣮ࡍʹॻ͍ͯΈͯυοάϑʔσΟϯά͢Δ ʢquicksort, brainfxxk, n-queens, xorshift128+, …) • ৄ͘͠ GoCon2017 ͷεϥΠυ: http://bit.ly/2wmG6Us -
ଟ૬ͳܕγεςϜͱ ͲΜͳܕʹஔ͖͑ͯྑ͍ϓϨʔεϗϧμ ͳܕΛѻ͑ΔܕγεςϜ (* ܕ 'a -> 'a: 'a ʹҙͷܕ͕ೖΔ
*) let rec id x = x in (* 'a ʹ int ΛೖΕΔ *) print_int (id 10); (* 'a ʹ bool ΛೖΕΔ *) print_bool (id false); (* ܕ 'a option *) let o = None in (* 'a ʹ int ΛೖΕΔ *) match o with Some(i) -> print_int i | None -> (); (* 'a ʹ bool ΛೖΕΔ *) match o with Some(b) -> print_bool b | None -> (); ͭͷ͕ෳͷܕΛ࣋ͯΔΑ͏ʹͳΔ bBbB ˣ JOUJOU CPPMCPPM ʜ -
ଟ૬తͳܕγεςϜͷ࣮ • ܕਪث͕ଟ૬తͳܕΛਪͰ͖ΔΑ͏ʹ֦ு • MinCaml ͷܕਪ୯૬ܕ • ଟ૬ͳܕͷͷίʔυੜΛͰ͖ΔΑ͏ʹ֦ு • LLVM
IR ʹଟ૬ܕແ͍ • ͳΜΒ͔ͷํ๏Ͱଟ૬తͳΛੜ͞ΕΔΞη ϯϒϦίʔυͰදݱ͢Δඞཁ͕͋Δ -
ଟ૬తͳܕਪΞϧΰϦζϜΛ ௐࠪ • Algorithm W • Ұ൪ΦʔιυοΫε • ܕू߹ͱଋറ͞ΕͨܕมͷஔදΛͬͯ୯ҰԽ͢Δ •
Algorithm M • ߏΛϘτϜΞοϓʹḷͬͯਪ͢Δ Algorithm W Λτοϓμϯʹվྑ ͨ͠ͷɽޮΤϥʔϝοηʔδ͕վળʢW ͷٯͳͷͰ Mʣ • Level-based Algorithm W • ܕมʹϨϕϧʢfreshnessʣΛಋೖ͢Δ͜ͱͰ Algorhtim W ͷΞϧΰϦζϜ Λγϯϓϧʹ͠ɼޮతʹ͢ΔɽOCaml Ͱ࠾༻͞Ε͍ͯΔ -
Level-based Algorithm W • let ࣜͰͷมଋറͰͷΈ͕ଟ૬ʹͳΔ͜ͱ ʹண͠ɼ͋Δܕม͕ʮͲΕ͚ͩ࠷ۙͷ let ࣜͰଋറ͞Εͨͷ͔ʯΛද͢Ϩϕϧͱ͍͏ Λ֤ܕมʹ࣋ͨͤΔɽ͕େ͖͍΄Ͳ࠷
ۙଋറ͞Εͨͷ • paper: http://gallium.inria.fr/~remy/ftp/eq- theory-on-types.pdf -
Level-based Algorithm W let rec make_pair x = let rec
f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () NBLF@QBJSҾΛYΛͱΓɼʮҾ ZΛऔͬͯYͱZͷϖΞΛฦ͢ ؔʯΛฦ͢ YΛΩϟϓνϟͨ͠ΫϩʔδϟΛͭ ͘ΓɼͦΕΛฦ͢ NBLF@QBJSΛճผͷܕͷҾͰݺͼ ग़ͯ͠ΈΔ -
Level-based Algorithm W • ຌྫ • ɹ :ண͍ͯ͠ΔՕॴ • ?a(n):
Ϩϕϧ n ͷܕมɽ ·ͩܕ͕֬ఆ͍ͯ͠ͳ͍ ʢະଋറʣ • ‘a: ଋറࡁΈͷܕมʢ ҙͷܕ͕ೖΕΔʣ let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () -
Level-based Algorithm W let rec make_pair x = let rec
f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM $VSSFOU-FWFM ࠷ॳϨϕϧ͔Βελʔτ -
Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:
?a(1) let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM $VSSFOU-FWFM MFUࣜͰ৽͍͠ม͕ಋೖ͞ΕΔͱɼଋറ ͞ΕΔࣜͷதͰϨϕϧ্͕͕Δ ͜ͷ࣌ͰNBLF@QBJSҾͷؔ ͱ͍͏͜ͱ͔͔͠Βͳ͍ -
Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:
?a(1) • f: ?c(2) -> ?d(2) • y: ?c(2) let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM -
Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:
?a(1) • f: ?c(2) -> ?a(1) * ?c(2) • y: ?c(2) let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM ࣜ Y Z ͔ΒΓYͱZͷλϓϧ ͩͱ͔Δˠ E B D ʢ୯ҰԽʣ -
൚ԽʢGeneralizationʣ มΛఆٛͨ͠ let ࣜͷϨϕϧΑΓେ͖͍Ϩϕϧͷ ܕมҙͷܕ͕ೖΔଟ૬ܕͱͯ֬͠ఆͤ͞Δ ?c(2) -> ?a(1) * ?c(2)ɹɹɹ'c
-> ?a(1) * 'c ʢݱࡏͷϨϕϧ: 1ʣ -
Level-based Algorithm W • make_pair: ?a(1) -> ?b(1) • x:
?a(1) • f: ‘c -> ?a(1) * 'c • y: 'c let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM MFUࣜʹଋറ͞Ε͍ͯΔࣜͷܕਪ͕ऴ Θͬͨ࣌ʹɼରͷมͷܕΛ൚Խ͢Δ Gҙͷܕ D ͷҾΛͭऔΓɼͦ ͷܕͷͱະͷܕͷͷϖΞʢ B bDʣΛฦ͢ -
Level-based Algorithm W • make_pair: ?a(1) -> ('c -> ?a(1)
* 'c) • x: ?a(1) • f: 'c -> ?a(1) * 'c • y: 'c let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM ࣜG͔ΒNBLF@QBJSͷΓͷܕG ͱಉ͡ܕͩͱ͔Δ C bD B bD ʢ୯ҰԽʣ -
Level-based Algorithm W • make_pair: 'a -> ('c -> 'a
* 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM NBLF@QBJSͷܕΛ൚Խ͢ΔɽҰ൪֎ଆ ͷMFUSFDࣜͷϨϕϧͳͷͰશͯ ͷະ֬ఆͳܕมΛଟ૬ܕʹ֬ఆ͢Δ -
ΠϯελϯεԽ ʢinstantiation) ଟ૬ܕͷมෳͷܕΛऔΔ͜ͱ͕Ͱ͖Δɽଟ૬ܕͷม͕ ࢀর͞ΕΔͨͼʹ৽͍͠ܕมΛಋೖ͢Δ 2ߦͰม id ͷࢀরͷܕ ?b -> ?bɼint
ΛҾʹͨ͠ݺ ͼग़͠Ͱ int -> int ʹͳΔɽ 3ߦͰม id ͷࢀরͷܕ ?c -> ?cɼbool ΛҾʹͨ͠ݺ ͼग़͠Ͱ bool -> bool ʹͳΔɽ let rec id x = x in (* 'a -> 'a *) id 10; (* int -> int *) id true; (* bool -> bool *) -
Level-based Algorithm W • make_pair: 'a -> ('c -> 'a
* 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM F G F G bB bDbB bD ΛΠϯελϯεԽ ҾJOUͳͷͰ F JOU ͰɼΓܕ͔ΒQBJSͷܕ G JOU G ɽ͜Ε Λ൚Խ -
Level-based Algorithm W • make_pair: 'a -> ('c -> 'a
* 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f • p: int * bool let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM H JOU H bGJOU bGΛΠϯελϯεԽ ҾCPPMͳͷͰ F CPPMͰɼΓܕ͔ΒQͷܕ JOU CPPMɽࠓճະ֬ఆͷ ܕม͕ແ͍ͷͰ൚Խෆཁ -
Level-based Algorithm W • make_pair: 'a -> ('c -> 'a
* 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f • p: int * bool • pair2: ‘i -> float * ‘i let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM I J I J ಉ༷ʹbB bDbB bD ΛΠϯελϯεԽ ͭͷNBLF@QBJSݺͼ ग़͔͠Β -
Level-based Algorithm W • make_pair: 'a -> ('c -> 'a
* 'c) • x: 'a • f: 'c -> 'a * 'c • y: 'c • pair: 'f -> int * ‘f • p: int * bool • pair2: ‘i -> float * ‘i • p: float * string let rec make_pair x = let rec f y = (x, y) in f in let pair = make_pair 42 in let p = pair true in let pair2= make_pair 3.0 in let p = pair2 "aaa" in () MFWFM MFWFM MFWFM $VSSFOU-FWFM K qPBU K bGJOU bGΛΠϯελϯεԽ QBJSݺͼग़͔͠Β -
ଟ૬ܕܕਪͷ࣮·ͱΊ • จͷࢀর࣮Λݟͳ͕Β࣮ʢଞʹ occur check ͰϨ ϕϧΛௐઅ͢ΔͳͲͷॲཧ͕͋Δʣ • ଞͷܕਪͷ࣮ͷςετσʔλΛྲྀ༻͢Δ •
ޒेཛྷઌੜͷ՝ͷςετέʔεͳͲ(※1) • ͳ͔ͥ ML ͕ଟ͍ͷͰͦͷ··͑Δ • ࠷ॳͷஈ֊Ͱ͔ͬ͠ΓςετΛॻ͍͓ͯ͘ͱ֦ுָʹͳ Δ IUUQTXXXGPTLVJTLZPUPVBDKQdJHBSBTIJDMBTTJTMFXUFTUDBTFTIUNM -
δΣωϦΫεͷίʔυੜͷ࣮ Λௐࠪ • શͯͷΛ1ϫʔυͰදݱ͢ΔʢOCaml, SML/NJ ͳͲʣ • int float
ͦͷ··ɼͦΕҎ֎ͷώʔϓͳͲʹͱͬͯϙΠϯλͰѻ͏ • ਖ਼֬ͳ GC ͷͨΊɼϙΠϯλ͔ͦ͏Ͱͳ͍͔அ͢ΔͷʹԼҐ̍ϏοτʹλάΛೖΕΔ ඞཁ͕͋Δ • ଟ૬ͳ͕औΔܕ͝ͱʹίʔυΛෳ͢Δʢmlton, Crystal, C++ (, Rust) ͳͲʣ • i.e. id: ‘a -> ‘a ͕ int -> int ͰΠϯελϯεԽ͞Ε͍ͯΔͳΒ id_int: int -> int Λੜ • ࣮ߦ࣌ͷΦʔόʔϔουগͳ͍͕ίʔυαΠζ͕രൃ͠͏ΔɽׂίϯύΠϧ͕͍͠ • ܕΫϥεΛఆٛ͠ɼܕΫϥε͝ͱͷ࣮ΛؔͷࣙॻͰ͢ʢHaskell (,Rust) ͳͲʣ • ࣙॻ͔Βݺͼग़ؔ͢ΛҾ͍ͯ͘ΔΦʔόʔϔου͕͋Δ͕ɼ͍ؔΠϯϥΠϯԽʹ ΑΓίʔυෳͱಉ͡ޮՌ͕ظͰ͖Δ -
ίʔυෳʹΑΔδΣωϦΫ ε࣮ʢ୯૬Խʣ ΠϯελϯεԽ͝ͱʹͬͨܕΛ໊લͷඌ ʹ͚ͭͯඃΒͳ͍Α͏ʹ͢Δ let rec id x = x
in let f = id in id 10; id "foo"; f 3.0; f true; let rec id_int x = x in let rec id_string x = x in let rec id_float x = x in let rec id_bool x = x in let f_float = id_float in let f_bool = id_bool in id_int 10; id_string "foo"; f_float 3.0; f_bool true; -
GoCaml ͷߏจΛஔ͖͑Δ • Ҏલ C++ Ͱ͍ͭͬͯͨ͘ݴޠ Dachs ͷߏจΛ revise ͯ͠࠷ऴతʹஔ͖͍͑ͨ
• ࢼ࡞ɿhttps://github.com/rhysd/Dachs/blob/ master/next/compiler/syntax/grammar.go.y • Ruby inspired ͳߏจʢʴ JavaScript ͷ Object ͷΑ͏ͳϨ ίʔυܕͷߏจʣ -
·ͱΊ • ֤ஈ֊Ͱ͔ͬ͠ΓςετΛॻ͍ͯɼςετ͕௨ΔίϯύΠ ϥ͕ಈ͘ঢ়ଶΛҡ֦࣋ͯ͠ுɾ࣮͍ͯ͘͠ • ࣮ࡍʹͭ͘ΓதͷίϯύΠϥΛͬͯίʔυΛॻ͍ͯΈΔ • ΄͍͠ػೳ Λ֦ுͱ͠ ࣮ͯ͢Δ
• ΦϦδφϧ ͷߏจʹஔ ͖͑ͯԶ ݴޠʹ͢Δ • طଘݴޠͷ αϒηοτ ͱͯ͠࠷ ݶͷػೳΛ ࣮