Go でつくる汎用言語処理系 実装戦略

Dea1add99f4cf942792c0f185aa2f2fd?s=47 Linda_pp
March 24, 2017

Go でつくる汎用言語処理系 実装戦略

General-purpose Programming Language implemented with Go and LLVM.
Presentation at Go Con Spring 2017

Dea1add99f4cf942792c0f185aa2f2fd?s=128

Linda_pp

March 24, 2017
Tweet

Transcript

  1. Go Ͱͭ͘Δ൚༻ݴޠॲཧܥ ࣮૷ઓུ General-purpose Programming Language implemented with Go @

    Go Con 2017 Spring
  2. @Linda_pp @rhysd 

  3. ΞδΣϯμ • ؔ਺ܕݴޠ GoCaml • GoCaml ͷ࣮૷ with Go&LLVM •

    Զݴޠͷ࣮૷ઓུ 
  4. ؔ਺ܕݴޠ GoCaml 

  5. GoCaml ͱ͸ • ϛχϚϧͳ OCaml ͷαϒηοτ • ࣮૷4000ߦఔ౓ • ੩తܕ෇͚ɼܕਪ࿦

    • MinCaml (※) ͷ࣮૷ϕʔε • https://github.com/rhysd/gocaml ˞IUUQTHJUIVCDPNFTVNJJNJODBNM let rec gcd m n = if m = 0 then n else if m <= n then gcd m (n - m) else gcd n (m - n) in print_int (gcd 21600 337500) 
  6. GoCaml ͷจ๏ʢԋࢉʣ • ϓϩάϥϜ͸ʢunit ܕʹධՁ͞ΕΔʣ1ͭͷࣜ • γʔέϯεࣜɼ੔਺ԋࢉɼදࣔ (* GoCaml: e1;

    e2 *) 1; 2; 3; -(1 + 2) * 10; 3.14 *. 3.0 *. 3.0; print_bool true; () /* Go */ func main() { 1; 2; 3 -(1 + 2) * 10 3.14 * 3.0 * 3.0 fmt.Printf("%v", true) } 
  7. GoCaml ͷจ๏ʢม਺ʣ • ม਺ఆٛ (* GoCaml: let e1 in e2

    *) let r = 9.0 in let pi = 3.14 in let area = r *. r *. pi in print_float area; (* ࠶ఆٛʢshadowingʣ ΋ OK *) let r = 4 in let area = r * r in print_int area /* Go */ func main() { r := 9.0 pi := 3.14 area := r * r * pi fmt.Print(area) { r := 4 area := r * r fmt.Print(area) } } 
  8. GoCaml ͷจ๏ʢؔ਺ʣ (* GoCaml *) (* ؔ਺ఆٛ & ద༻*) let

    rec squre x = x *. x in squre 3.0; (* Ϋϩʔδϟ *) let PI = 3.14 in let rec f d = PI *. d *. d in (* ؔ਺͸஋ͱͯ͠΋࢖͑Δ *) let rec compose f g = let rec h x = f (g x) in h in let f = compose squre squre in /* Go */ func squre(x float64) float64 { return x * x } func main() { squre(3.0) PI := 3.14 circle := func(d float64) float64 { return PI * d * d } type F func(f float64) float64 compose := func(f F, g F) F { return func(x float64) float64 { return g(f(x)) } } f := compose(squre, squre) } 
  9. GoCaml ͷจ๏ʢtuple, arrayʣ (* GoCaml *) let arr = Array.make

    4 42 in print_int arr.(3) in arr.(3) <- 99; print_int arr.(3) let tpl = 1, true, "aaa" in let (i, b, s) = tpl in print_int i; print_int b; print_int s; /* Go */ func main() { arr := make([]int, 4) for i := range arr { arr[i] = 42 } fmt.Print(arr[3]) arr[3] = 99 fmt.Print(arr[3]) tpl := struct { i int b bool s string }{ 1, true, "aaa" } i, b, s := tpl.i, tpl.b, tpl.s fmt.Print(i) fmt.Print(b) fmt.Print(s) } 
  10. GoCaml ͷͦͷଞͷݴޠػೳ • C extension • GC (Boehm GC) •

    gdb ͰσόοάͰ͖Δ • ϦϙδτϦͷ examples σΟϨΫτϦʹ΋͏গ͠ෳ ࡶͳྫ͕͋Γ·͢ • brainfxxk, N-queens, Xorshift128+, … 
  11. GoCaml ͷ࣮૷ w/ Go & LLVM

  12. ίϯύΠϥ࣮૷ͷجຊํ਑ ιʔείʔυจࣈྻ → ࣮ߦܗࣜόΠφϦ ΁ ͷม׵ ந৅౓ɿେ → খ Ұؾʹม׵͢Δͷ͸೉͍͠ͷͰɼঃʑʹந৅౓Λམͱͨ͠σʔλߏ଄Λఆٛ͠ɼ

    ঃʑʹந৅౓ΛԼ͍͛ͯ͘ ιʔείʔυ → ߏจ໦ → ܕ෇͖தؒදݱ → LLVM IR → ΞηϯϒϦ → ػցޠ 
  13. GoCaml ͷίϯύΠϥ࣮૷ ιʔε ίʔυ τʔΫ ϯྻ ந৅ߏ จ໦ தؒද ݱ

    --7. *3 Ξηϯ ϒϦ T ΦϒδΣ Ϋτ P ࣮ߦϑΝ Πϧ ϥϯλ ΠϜ P ϥϯλ ΠϜ D 
  14. GoCaml ͷίϯύΠϥ࣮૷ ιʔε ίʔυ τʔΫ ϯྻ ந৅ߏ จ໦ தؒද ݱ

    --7. *3 Ξηϯ ϒϦ T ΦϒδΣ Ϋτ P ࣮ߦϑΝ Πϧ ϥϯλ ΠϜ P ϥϯλ ΠϜ D (PͰࣗલ࣮૷ --7. $ίϯύΠϥ ϦϯΧ ࣈ۟ղੳ ߏจղੳ ͍Ζ͍Ζ 
  15. LLVM (http://llvm.org/) ͱ͸ • ίϯύΠϥͷόοΫΤϯυ෦෼ΛϞδϡʔϧԽͯ͠ఏ ڙ͢ΔϥΠϒϥϦ܈ • GoCaml Ͱ͸ LLVM

    IR ͱݺ͹ΕΔ LLVM ಠࣗͷதؒݴ ޠ͔Β࠷దԽ&ωΠςΟϒίʔυΛੜ੒͢Δͷʹ࢖͏ • ࣮૷͸ C++ Ͱ C ͔Β࢖͑Δ API ͱɼ֤ݴޠ͔Β࢖͑ ΔόΠϯσΟϯάʢެࣜʹ͸ Python, OCaml, Goʣ͕ ͋Δ 
  16. ࣈ۟ղੳ • ྫ͑͹ “let a = 42 in a +

    b” Λ “let”, “a”, “=“, “42”, “in”, “a”, “+”, “b” ʹ෼ ղ͢Δॲཧ • ݹయతʹɼจࣈྻΛ1จࣈͣͭݟ͍ͯͬͯରԠ͢ΔτʔΫϯΛੜ੒͢ Δ • Lexer ͸ Goroutine Ͱ࣮ߦ͞ΕɼτʔΫϯ͸ channel Λ௨ͯ͡ύʔα ʹૹΒΕΔ • Go ͷ text/template ͷ࣮૷Λࢀߟʹ • https://github.com/golang/go/blob/master/src/text/template/parse/lex.go ιʔε ίʔυ τʔΫ ϯྻ ࣈ۟ղੳ 
  17. ߏจղੳ • τʔΫϯྻ͔ΒϓϩάϥϜΛ໦ߏ଄Ͱද͢ந৅ߏจ໦ʹม׵͢Δ • Go ެࣜπʔϧͷ goyacc Λ࢖ͬͯ YACC ͰύʔαΛఆٛ͠ɼGo

    ͷίʔυΛੜ੒͢Δ • https://godoc.org/golang.org/x/tools/cmd/goyacc • YACC ͷจ๏ΛֶͿͷ͸ RHG ͷ͕͓͢͢Ί • http://i.loveruby.net/ja/rhg/book/yacc.html MFUBJOB  MFUB JOU WBSB JOU τʔΫ ϯྻ ந৅ߏ จ໦ ߏจղੳ 
  18. ந৅ߏจٛͷఆٛ • ϊʔυͷΠϯλʔϑΣʔε Node ͱɼ֤ϊʔ υͷ۩ମతͳܕΛߏ଄ମͰఆٛ • go/ast ͱ΄΅ಉ͡ʢ https://golang.org/pkg/

    go/ast/ ʣ 
  19. package main import ( "github.com/rhysd/gocaml/ast" "github.com/rhysd/gocaml/lexer" "github.com/rhysd/gocaml/token" "github.com/rhysd/gocaml/parser" ) func

    (c *Compiler) Parse(src *Source) (*ast.AST, error) { // ࣈ۟ղੳΛߦ͏ Lexer ͷΠϯελϯε l := lexer.NewLexer(src) // Τϥʔϋϯυϥ l.Error = func(msg string, pos token.Position) { panic("error") } // Goroutine Λ࢖࣮ͬͯߦɼl.Tokens channel ʹτʔΫϯ͕ૹΒΕͯ͘Δ go l.Lex() // ύʔα͸ channel ͝͠ʹτʔΫϯΛड͚औͬͯߏจ໦Λͭ͘Δ ast, err := parser.Parse(l.Tokens) if err != nil { return nil, err } return ast, nil } 
  20. தؒදݱ΁ͷม׵ • ͕͜͜ࠓճͷ࣮૷ͷதͰ͸Ұ൪ॏ͍ • ߏจ໦͔Βதؒݴޠ΁ͷม׵͸Ϊϟοϓ͕େ ͖͍ͷͰঃʑʹந৅౓Λམͱ͍ͯ͘͠ BEGIN: program a$t1 =

    int 42 ; type=int $k4 = int 10 ; type=int $k5 = binary + a$t1 $k4 ; type=int $k6 = appx print_int $k5 ; type=() END: program ந৅ߏ จ໦ தؒද ݱ ͍Ζ͍Ζ MFUB JOU WBSB JOU 
  21. தؒදݱ΁ͷม׵ ߏจ໦ Ћม׵ ܕਪ࿦ ʢܕνΣοΫʣ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ Ϋϩʔδϟ ม׵ 

    ந৅ߏ จ໦ தؒද ݱ
  22. ߏจ໦ΛᢞΊΔʢvisitorʣ • ߏจ໦ͷ֤ϊʔυΛ८ΔͨΊʹ visitor ύλʔϯΛ࢖͏ ʢਂ͞༏ઌʣ • visit ͷڍಈΛ੍ޚͰ͖ΔΑ͏ʹ͢Δʢvisit Λଧͪ੾Δ

    ͳͲʣ • ܕਪ࿦΍ߏจ໦ͷղੳɼҙຯνΣοΫɼதؒݴޠ΁ͷ ม׵͸͜ΕΛ༻͍Δ • go/ast ͷ ast.Visit ͱಉ͡ 
  23. ߏจ໦ΛᢞΊΔʢvisitorʣ // Visitor ͷΠϯλʔϑΣʔεɽ͜ΕΛ࣮૷ͨ͠ܕ͸ߏจ໦Λ traverse Ͱ͖Δ type Visitor interface {

    // ߏจ໦ͷϊʔυΛड͚औͬͯʮࢠͷ visit ʹ࢖͏ visitorʯΛ໭Γ஋Ͱฦ͢ // nil ͳΒͦ͜Ͱ visit ऴྃ Visit(n Node) Visitor } // Visitor Λߏจ໦ʹద༻ func Visit(v Visitor, n Node) { if v = v.Visit(n); v == nil { return } // ࢠʹ࠶ؼతʹద༻ switch n := n.(type) { case *Add: // ଍͠ࢉϊʔυͷͱ͖ Visit(v, n.Left) Visit(v, n.Right) case *If: // ... // શͯͷࢠ͕͋ΔϊʔυͷࢠΛ visit } } 
  24. αม׵ ֤γϯϘϧʢ֎෦γϯϘϧҎ֎ʣʹ ID Λৼͬ ͯม਺໊ΛҰҙʹ͢Δɽ͜ΕͰείʔϓΛج ຊతʹؾʹ͠ͳͯ͘ྑ͘ͳΔ ߏจ໦ Ћม׵ // Go

    ٖࣅίʔυ func do_something () { x := 42 y := "aaa" { x := true } } // Go ٖࣅίʔυ func do_something$1 () { x$2 := 42 y$3 := "aaa" x$4 := true } 
  25. ܕਪ࿦ • γϯϓϧͳ Hindley-Mlner ܕਪ࿦ΞϧΰϦζϜ • ߏจ໦ͷ֤ϊʔυʹܕΛ͚͍ͭͯ͘ • visit ͨ࣌͠఺Ͱܕ͕ෆ໌ͳͱ͜Ζ͸ܕม਺Λಋೖ͠ɼʮݱ࣌఺Ͱ͸ෆ໌ʯͱͯ͠

    ͓͘ɽ࠷ऴతʹͦͷม਺ͷ஋͕෼͔Ε͹ OKɽ • ܕม਺ʹ͍ͭͯͷ࿈ཱํఔࣜΛཱͯͯͦΕΛղ͘ײ͡ʢʮղ͘ʯॲཧΛ unification ͱ͍͏ʣ • ྫ͑͹഑ྻΞΫηε e1.(e2) Ͱ͋Ε͹ e1 ͷܕ͸഑ྻʢཁૉܕͷܕ͸ෆ໌ʣɼ e2 ͷܕ͸ intɼධՁ݁Ռ͸ e1 ͷཁૉܕʢ͜ͷ࣌఺Ͱ͸۩ମతʹͦΕ͕Կ͔͸ ෼͔Βͳ͍ʣͱ͍ͬͨ͜ͱ͕෼͔ΔͷͰɼͦΕΛίʔυʹམͱ͍ͯ͘͠ Ћม׵ ܕਪ࿦ ʢܕνΣοΫʣ 
  26. // Go ٖࣅίʔυ func lessFirst(a, b) { x := a[0]

    y := b[0] return x < y } func main() { p := []int{1} lessFirst(p, p) } • lessFirst : ? -> ? -> ? 
  27. • lessFirst : (? array) -> ? -> ? •

    x : ? // Go ٖࣅίʔυ func lessFirst(a, b) { x := a[0] y := b[0] return x < y } func main() { p := []int{1} lessFirst(p, p) } 
  28. • lessFirst : (? array) -> (? array) -> ?

    • x : ? • y : ? // Go ٖࣅίʔυ func lessFirst(a, b) { x := a[0] y := b[0] return x < y } func main() { p := []int{1} lessFirst(p, p) } 
  29. • lessFirst : (? array) -> (? array) -> bool

    • x : int ͔ bool ͔ float • y : int ͔ bool ͔ float // Go ٖࣅίʔυ func lessFirst(a, b) { x := a[0] y := b[0] return x < y } func main() { p := []int{1} lessFirst(p, p) } 
  30. • lessFirst : (? array) -> (? array) -> bool

    • x : int ͔ bool ͔ float • y : int ͔ bool ͔ float • main : () -> ? • p : (int array) // Go ٖࣅίʔυ func lessFirst(a, b) { x := a[0] y := b[0] return x < y } func main() { p := []int{1} lessFirst(p, p) } 
  31. • lessFirst : (int array) -> (int array) -> bool

    • x : int ͔ bool ͔ float • y : int ͔ bool ͔ float • main : () -> () • p : (int array) // Go ٖࣅίʔυ func lessFirst(a, b) { x := a[0] y := b[0] return x < y } func main() { p := []int{1} lessFirst(p, p) } 
  32. ܕਪ࿦ͷϝϦοτɾσϝϦοτ • ܕ͕߹Θͳ͍ or ܕม਺͕࢒ͬͯ͠·ͬͨ࣌͸ Τϥʔʹͳ Δ • ܕਪ࿦ʹΑΓɼܕΛҰ੾ॻ͔ͳͯ͘ྑ͍ʢෳࡶͳؔ਺ͷγ άωνϟͳͲʣ

    • ܕ͕߹Θͳ͍Τϥʔ͕ग़ͨͱ͖ʹਓؒʹͱͬͯΘ͔ΓͮΒ ͍ • ࠶ؼతͳܕʢؔ਺ͷҾ਺ʹͦͷؔ਺ࣗ਎Λ༩͑ͨ࣌ͳͲʣ ͕ਪ࿦Ͱ͖ͳ͍ͷͰ޻෉͕ඞཁ 
  33. தؒදݱͷఆٛ ܕਪ࿦ ʢܕνΣοΫʣ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ CJOU C JG # #

    C   C BQIJ#  #  B  BQQQSJOU@JOU let b = 1 in let a = if b > 0 then b + 10 - 4 else b - 10 in print_int (a * 2) # # # # 
  34. தؒදݱͷఆٛ ܕਪ࿦ ʢܕνΣοΫʣ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ CJOU C JG # #

    C   C BQIJ#  #  B  BQQQSJOU@JOU • ໋ྩ • {register} = rhs • Ϩδελ΁ͷ୅ೖ͸Ұ౓ ͖ΓʢSingle Static Assignmentʣ • ӈลʹ͸1ͭͷૢ࡞ͷΈ ͕هड़Ͱ͖Δʢਖ਼نܗʣ # # # # 
  35. தؒදݱͷఆٛ ܕਪ࿦ ʢܕνΣοΫʣ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ CJOU C JG # #

    C   C BQIJ#  #  B  BQQQSJOU@JOU • جຊϒϩοΫ • ໋ྩྻΛ૒ํ޲Ϧε τͱͯ࣋ͭ͠ • ଞͷϒϩοΫͱ༗޲ ඇ८ճάϥϑ (DAG) Ͱͭͳ͕Δ # # # # 
  36. • Visitor Ͱߏจ໦ΛḷΓͳ͕Β໋ྩྻΛϊʔυ ͝ͱʹ࡞੒͍ͯ͘͠ • if ࣜͰͷ෼ذ΍ؔ਺ͷຊମͳͲͰ৽͍͠ϒϩο ΫΛͭ͘Δ தؒදݱϑΥʔϚοτ ΁ม׵

    ܕਪ࿦ ʢܕνΣοΫʣ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ 
  37. Ϋϩʔδϟม׵ • தؒදݱʹม׵ͨ͠௚ޙͰ͸·ͩؔ਺ఆٛࣜ ͕ωετ͍ͯ͠Δ͕ɼLLVM IR ΍ΞηϯϒϦ ͸ؔ਺Λ΋ͪΖΜωετͰ͖ͳ͍ • ωετͨؔ͠਺ΛτοϓϨϕϧʹҠಈ͢Δॲ ཧ͕ඞཁ

    → Ϋϩʔδϟม׵ • ࣮͸Ұ൪େม தؒදݱ΁ͷϑΥʔ Ϛοτม׵ Ϋϩʔδϟ ม׵ 
  38. Ϋϩʔδϟม׵ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ Ϋϩʔδϟ ม׵ // Go ٖࣅίʔυ func main()

    { func square(x int) int { return x * x } square(10) } // ! square ΛτοϓϨϕϧʹҠಈ͢Δͷ͸؆୯ func square(x int) int { return x * x } func main() { square(10) } 
  39. Ϋϩʔδϟม׵ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ Ϋϩʔδϟ ม׵ // Go ٖࣅίʔυ func main()

    { PI := 3.14 func circle(x float64) float64 { return x * x * PI } circle(3.0) } // ! ΫϩʔδϟͩͱͲ͏ͳΔʁ // PI ΛͲ͏ʹ͔఻ୡ͢Δඞཁ͕͋Δ func circle(x float64) float64 { return x * x * PI } func main() { PI := 3.14 circle(3.0) } 
  40. Ϋϩʔδϟม׵ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ Ϋϩʔδϟ ม׵ // Go ٖࣅίʔυ func main()

    { PI := 3.14 func circle(x float64) float64 { return x * x * PI } circle(3.0) } // ! ؔ਺಺ʹΩϟϓνϟ͞ΕΔ஋ΛӅΕҾ਺ͱͯ͠౉͢ඞཁ͕͋Δ type Captures struct { PI float64 } func circle(cap Captures, x float64) float64 { PI := cap.PI return x * x * PI } func main() { PI := 3.14 circle(Captures{PI}, 3.0) } 
  41. • ໋ྩྻΛḷΓɼ࠶ؼతʹؔ਺ఆ͕ٛΩϟϓνϟʢ=ࣗ༝ม਺ʣΛ࣋ͭ ͔ௐ΂Δ • Ωϟϓνϟ͕͋Ε͹ͦͷؔ਺͸Ϋϩʔδϟͱͯ͠ݺͼग़͠ݩͰΩϟϓ νϟΦϒδΣΫτΛ࡞੒ • ݺͼग़ͨؔ͠਺͕͢ͰʹΫϩʔδϟͰͳ͍ͱ෼͔͍ͬͯΔؔ਺͸Ωϟ ϓνϟΦϒδΣΫτΛ࡞੒͠ͳ͍Α͏ʹ͢ΔʢKnown Function

    Optimizationʣ • ۩ମతͳ࣮૷ͱͯ͠͸ɼ͋Δؔ਺͕͋ͬͨͱ͖ʹ·ͣ͸ͦͷؔ਺͕ Known Ͱ͋ΔͱԾఆͯ͠ body Λ࠶ؼతʹḷΓɼ΋͠Ωϟϓνϟ͕ݟ͔ͭΕ͹લఏ͕ؒҧ͍ͬͯͨͷͰঢ়ଶΛ໭ͯ͠࠶౓ḷΓ௚͢ Ϋϩʔδϟม׵ தؒදݱ΁ͷϑΥʔ Ϛοτม׵ Ϋϩʔδϟ ม׵ 
  42. LLVM IR ͷੜ੒ தؒද ݱ --7. *3 • LLVM ͷ

    Go binding ϥΠϒϥϦΛ࢖ͬͯதؒදݱ͔Β LLVM IR Λੜ੒͢ΔɽجຊϒϩοΫͷதͷ໋ྩྻΛḷΓɼର Ԡ͢Δ LLVM IR ͷ໋ྩΛ llvm.IRBuilder Λ࢖ͬͯੜ੒͍ͯ͠ ͘ • ͍ͭͰʹ LLVM IR ϨϕϧͰͷ࠷దԽ΋૸ΒͤΔɽΠϯϥΠ ϯԽ΍ෆཁίʔυͷআڈͳͲ͔ͳΓͷ࠷దԽΛͯ͘͠ΕΔ • ຊ౰͸࠷దԽͱίʔυੜ੒͕Ұ൪ॏ͍ͱ͜Ζ͕ͩɼ͋Δఔ ౓ LLVM ʹ೚ͤΒΕΔ 
  43. LLVM IR ͷֶश • LLVM C ͷ Go binding ʹ͍ͭͯ஌Δʹ͸

    • LLVM ΛόοΫΤϯυͱͨ͠ Go ίϯύΠϥ LLGO ͕ࢀߟʹͳΔɽgo/* Λ࢖ͬ ͯதؒදݱΛߏங͠ɼGo binding ͰόΠφϦʹམͱ͍ͯ͠ΔɽJIT Λ࢖ͬͨ REPL ΋͋Δ • https://godoc.org/llvm.org/llvm/bindings/go/llvmʢLLVM ຊՈͷ Doxygen ʹൺ΂ͯʣ͔ͳΓಡΈ΍͍͢ɽ͕ɼࡌͬͯͳ͍΋ͷ΋͋ΔͷͰ஫ҙ • LLVM IR ʹ͍ͭͯ஌Δʹ͸ • Clang ͷు͘ IR ΛோΊΔ: `clang -S -emit-llvm` • ϦϑΝϨϯεϚχϡΞϧΛಡΉ http://llvm.org/docs/LangRef.html 
  44. Go Ͱॻ͍ͯΈͨײ૝ • ࢥͬͨ΄Ͳॻ͖ʹ͘͘ͳ͍ɽଟগίϐϖతίʔυͰ΋ Go ͔ͩΒ…ͱ ཧੑΛࣺͯͯॻ͚Δʢ࣮૷ߦͰݟͯ΋ OCaml ͷ2ഒఔ౓ʣ •

    ֤ϑΣʔζͰ͔ͬ͠ΓςετΛॻ͍͍ͯ͘ͷ͕ॏཁͳͷͰɼGo ͷς ετจԽ͸ྑ͍ • ஈ֊తʹม׵͍֤ͯ͘͠ϑΣʔζΛผύοέʔδʹ͢Δ͜ͱͰ͏͔ͬ Γ૬ޓࢀরͯ͠͠·͏ͷΛ๷͛Δ • ύʔαδΣωϨʔλ΍ LLVM ͷαϙʔτ͕ެࣜͰఏڙ͞Ε͍͍ͯͯΔ • Ӭଓతσʔλߏ଄͕ແ͍ͷͰɼ࠶ؼతʹ visit ͯ͠ undo ͢ΔΈ͍ͨͳ ॲཧ͕ॻ͖ʹ͍͘ 
  45. Զݴޠͷ࣮૷ઓུ 

  46. GoCaml ࣮૷ͷܦҢ Ҏલ C++ ͰίϯύΠϥΛॻ͍͍͕ͯͨ಴࠳ͯ͠͠·ͬͨ https://github.com/rhysd/Dachs ݪҼ͸ 1. ߏจ໦͔ΒҰؾʹ IR

    ʹམͱͦ͏ͱͯ͠ม׵ॲཧ͕ෳࡶʹͳ Γ͗ͨ͢ 2. ߏจ౶ҥͳͲɼ࠷ॳ͔ΒػೳΛ੝Γ͗ͨ͢ 3. Ϗϧυ͕஗͍ʢ4෼Ҏ্ʣ 
  47. ԶݴޠʢDachsʣΛ෮׆ͤ͞Δ 1. தؒݴޠΛಋೖͨ͠ίϯύΠϥΛॻ͍ͯΈΔʢGoCamlʣ 2. GoCam ͷίʔυϕʔεΛͳΔ΂͘ྲྀ༻͠ͳ͕ΒϛχϚϧͳݴޠͱ ͯ͠ Dachs Λͭ͘ΔʢجຊܕɼϙΠϯλͷ௿ڃͳૢ࡞΍ߏ଄ମఆ ٛɼC

    ֦ுͳͲʣ 3. ഑ྻ΍ϋογϡͳͲͷجຊతͳσʔλߏ଄͸ Dachs ͷϥΠϒϥϦ ͱͯ͠ॻ͘ 4. ηϧϑϗετ͢Δ 5. ΑΓෳࡶͳݴޠػೳΛ࣮૷͍ͯ͘͠ 
  48. ͋ΔݴޠͰͦͷݴޠͷॲཧܥΛ࣮૷ ͢Δʢηϧϑϗετʣͷར఺ͱܽ఺ • υοάϑʔσΟϯά • ૣظ͔Βࣗ෼͕࢖͍͍ͨݴޠΛࣗ෼Ͱͭͬͯࣗ͘෼Ͱ࢖͑Δ • શͯࣗલͰ࣮૷͠ͳ͚Ε͹ͳΒͳ͍ʢςετϑϨʔϜϫʔΫɼσ όοΨͳͲʣ •

    όά͕ग़ͨ࣌ͷσόοά͕೉͘͠ͳΔ͔΋ʢͦͷίʔυʹ͋Δͷ ͔ɼͦͷίʔυΛίϯύΠϧͨ͠ίϯύΠϥͷίʔυʹ͋Δͷ͔ɼͦ ͷίʔυΛίϯύΠϧͨ͠ίϯύΠϥͷίʔυΛίϯύΠϧͨ͠ίʔ υʹ͋Δͷ͔…ʣ • جຊతʹ͸ 1ͭ໨ͱ2ͭ໨ͷར఺͕࠷ߴͳͷͰηϧϑϗετ͍ͨ͠ 
  49. Go Ͱηϧϑϗετ͢ΔίϯύΠ ϥΛॻ͘ར఺ • ηϧϑϗετ͢Δࡍ͸طଘͷ࣮૷ΛϗετݴޠΛࣗ ෼ࣗ਎Ͱஔ͖׵͍͑ͯ͘ • ڧྗͳݴޠػೳ/ϥΠϒϥϦ͕࢖͑ΔϗετݴޠͰ ࠷ॳʹ࣮૷͢Δͱɼஔ͖׵͑Δͷ͕೉͘͠ͳΔ͸ͣ •

    Go ͸ඇৗʹ؆ૉͳݴޠ࢓༷Λ͍࣋ͬͯΔͷͰɼη ϧϑϗετ͢Δࡍʹݴޠͷஔ͖׵ָ͕͑ʹͳΓͦ͏ 
  50. ·ͱΊ • ίϯύΠϥ͸ஈ֊తͳσʔλͷม׵Ͱ͋Δ • Go ͱ LLVM ͰίϯύΠϥΛॻ͍ͯΈͨݶΓͰ ͸ॻ͖΍͘͢ɼґଘ΋গͳ͘Ͱ͖ͦ͏ •

    ૣظʹηϧϑϗετ͢Δʹ͸ɼίϯύΠϥͷ ॳظ࣮૷͸ Go Ͱॻ͍͓ͯ͘ͱྑͦ͞͏ʢ͜ Ε͔Βʣ 
  51. ʢऄ଍ʣൃදऀ঺հ • C++, Ruby, TypeScript, Vim script • C++ ͰίϯύΠϥΛॻ͍͍ͯͨΓɼCrystal

    ͷॲཧܥΛ͍ͬͯ͡ΈͨΓ • Electron + TypeScript + React ͰσεΫτοϓΞϓϦΛॻ͍ͨΓ • Vim ϓϥάΠϯΛ60ݸ͙Β͍ॻ͍ͯͨΓ • ࠷ۙ͸ Go ͰίϯύΠϥΛॻ͍ͨΓͯ͠·͢ • ιϑτ΢ΣΞΛͭ͘Δͷָ͕͍͠ @Linda_pp @rhysd