$30 off During Our Annual Pro Sale. View Details »

Elixirでプログラミング言語を作ろう #tokyoex / Let's Make Your Own Language in Elixir

Elixirでプログラミング言語を作ろう #tokyoex / Let's Make Your Own Language in Elixir

Kentaro Kuribayashi

November 20, 2021
Tweet

More Decks by Kentaro Kuribayashi

Other Decks in Technology

Transcript

  1. ElixirͰϓϩάϥϛϯάݴޠΛ࡞Ζ͏
    ܀ྛ ݈ଠ࿠ / GMO Pepabo, Inc.
    2021.11.20 tokyo.ex Reboot
    1

    View Slide

  2. 2
    ࣗݾ঺հ
    GMOϖύϘגࣜձࣾ
    ιϑτ΢ΣΞΤϯδχΞ
    ܀ྛ ݈ଠ࿠ a.k.a. ͋ΜͪΆ
    ● GMOϖύϘऔక໾CTO
    ● JAISTത࢜લظ՝ఔ
    ● Twitter : @kentaro
    ElixirConf US 2021Ͱൃදͨ͠Γ͠·ͨ͠ɻ


    → ձࣾͷςοΫϒϩά / YouTubeͷಈը

    View Slide

  3. ͜ͷτʔΫʹࢸ͖͔͚ͬͨͬ
    3
    ● ͖͔͚ͬ͸ɺWEB+DB PRESS Vol.125
    ʢӈਤʣͷಛूΛಡΜͩ͜ͱ
    ● पғʢࣾ಺ʣͰ΋ಠࣗݴޠΛ࡞ΔࢼΈ͕
    ੝Γ্͕͍ͬͯΔ
    ɹˠ RBSʢԾʣʢby @udzuraʣ
    ɹˠ EVMͰಈ͘εϚʔτίϯτϥΫτهड़ݴޠΛ
    ࡞Γ͍ͨʢby @akht_ikdʣ
    ࣗ࡞ݴޠͷ੝Γ্͕Γ
    ӈਤͷग़ॴɿWEB+DB PRESS Vol.125ʛٕज़ධ࿦ࣾ

    View Slide

  4. 4
    ElixirͰϓϩάϥϛϯάݴޠͷࣗ࡞Λ࢝Ί·ͨ͠
    ग़ॴɿkentaro/rorty: Yet Another Language Implementation using Elixir.
    Elixir 100%ʂ

    View Slide

  5. 5
    ͲΜͳݴޠ͔ʁʢ۩৅ߏจ͔Βʣ
    def factorial(n) {
    if (n < 2) {
    1
    } else {
    n * factorial(n - 1)
    }
    }
    puts(factorial(5))
    ࣜϕʔεɺ৚݅෼ذɾ܁Γฦ͠ɺؔ਺ݺͼग़͠ɺσʔλ͸੔਺ͱจࣈྻ
    for (i in 1 to 100) {
    if (i % 15 == 0) {
    puts("FizzBuzz")
    } else {
    if (i % 5 == 0) {
    puts("Buzz")
    } else {
    if (i % 3 == 0) {
    puts("Fizz")
    } else {
    puts(i)
    }
    }
    }
    }
    ※ ্ه͸ߨԋऀ͕࡞ͬͨݴޠʹΑΔίʔυྫͰ͋ΓɺWEB+DB PRESS Vol.125ͷಛूهࣄͰղઆ͞Ε͍ͯΔݴޠʢToysʣͱ͸΍΍ҟͳΔɻ

    View Slide

  6. 6
    WEB+DB PRESSಛूͷըظతͳͱ͜Ζ
    ۩৅ߏจ͔ΒͰ͸ͳ͘ந৅ߏจ͔Βݴޠ࣮૷Λ࢝ΊΔ
    ۩৅ߏจ
    ந৅ߏจ
    ҙຯ࿦
    Α͋͘Δઆ໌ͷྲྀΕ
    ந৅ߏจ
    ۩৅ߏจ
    ҙຯ࿦
    ຊಛूͷઆ໌ͷྲྀΕ ͜ͷྲྀΕͷϝϦοτ


    ʮΠϯλϓϦλͷຊ࣭͸ந
    ৅ߏจ໦ʯʢp.21ʣ


    ۩৅ߏจ͔ΒೖΔͷ͸ɺ΍
    Δ΂͖͜ͱ͕ෳࡶͰɺ࠳ં
    ͠΍͍͢ɻ


    ந৅ߏจ͔ΒೖΔํ͕ɺී
    ஈͷϓϩάϥϛϯάʹۙ͘
    ͯͱ͖ͬͭ΍͍͢ʢͱࢥ͏ʣ
    ग़ॴɿWEB+DB PRESS Vol.125 p.21Λݩʹ࡞ਤͨ͠ɻ

    View Slide

  7. 7
    ·ͣ࡞Γ࢝ΊΔՕॴ
    1.࢛ଇԋࢉΛදݱ͠ಘΔந৅ߏจ໦Λɺ
    Structͱͯ͠ఆٛ͢Δ
    2.ந৅ߏจ໦Λड͚औͬͯɺ࠶ىతʹղ
    ऍɾ࣮ߦ͢Δʢӈਤͷinterpretؔ
    ਺ʣ
    3.ࣜʹؚ·ΕΔૢ࡞ͷछผʹԠͯ͡ॲཧ
    ͠Θ͚Δ
    4.ͦͷૢ࡞ʹରԠ͢ΔElixirͷૢ࡞Λ࣮ߦ
    ͢Δ
    ந৅ߏจ໦ͷσʔλߏ଄ͱɺͦΕΛ࣮ߦ͢ΔΠϯλϓϦλ͔Β࡞Γ࢝ΊΔ
    def interpret(%Rorty.Ast.Expression.Binary{} = expr) do
    case expr.operator do
    Rorty.Operator.Add ->
    interpret(expr.left) + interpret(expr.right)
    Rorty.Operator.Divide ->
    interpret(expr.left) / interpret(expr.right)
    Rorty.Operator.Multiply ->
    interpret(expr.left) * interpret(expr.right)
    Rorty.Operator.Subtract ->
    interpret(expr.left) - interpret(expr.right)
    end
    end
    ࠶ؼ࣮ߦ

    View Slide

  8. 8
    ந৅ߏจͷछྨΛ૿΍͍ͯ͘͠
    1.લड़ͷ௨Γɺinterpretؔ਺͸࠶
    ىతʹந৅ߏจ໦Λղऍɾ࣮ߦ͢
    Δ
    ɹʢӈਤͷ࠷্෦ͷinterpretؔ਺Λࢀরʣ
    1.ifจͷཏྻͰ͸ͳ͘ɺύλϯϚο
    νΛ࢖ͬͯɺࣜͷछผʹԠͨ͡ॲ
    ཧΛɺએݴతʹهड़͍ͯ͘͠ͱ
    ElixirͬΆ͍
    ૿͑ଓ͚Δந৅ߏจͷछྨʹରͯ͠ElixirΒ͘͠ύλϯϚονͰରԠ

    View Slide

  9. 9
    ۩৅ߏจΛ࡞͍ͬͯ͘
    ● ந৅ߏจΛ࡞͍ͬͯ͘ͱɺͦΕΛ࢖ͬͨϓϩάϥϜͦͷ΋ͷΛಈ͔͍ͨ͠ؾ࣋ͪʹͳͬͯ͘
    ΔͷͰɺ͋Δఔ౓ͷͱ͜ΖͰ۩৅ߏจʹͱΓ͔͔Δ
    ○ ࣮ࡍʹ͸ɺ࢛ଇԋࢉͷந৅ߏจΛ࡞ͬͨΒɺରԠ͢Δ۩৅ߏจΛఆٛ͠·ͨ͠
    ● ۩৅ߏจͷهड़ʹ͸PEGΛར༻ʢଞͷબ୒ࢶ͸BNFͱYeccɺNimbleParsec౳ʣɻ
    ● ͦͷར఺͸ҎԼͷ௨Γ
    ͋Δఔ౓ந৅ߏจ͕Ͱ͖ͨΒɺύʔαδΣωϨʔλͰ۩৅ߏจΛ࡞Δ
    ग़ॴɿWEB+DB PRESS Vol.125 p.30
    1. ߏจղੳͱࣈ۟ղੳΛ۠ผ͠ͳ͍ʢ͠ͳͯ͘Α͍ʣ
    2. BNF͔Β୯७ʹߏจղੳثΛ࡞ͬͨ৔߹ͷ໘౗͍͘͞໰୊ʹ൥Θ͞Εͳ͍
    3. PEG͔ΒߏจղੳثΛ࡞Δͷ͸؆୯Ͱ͋Δ

    View Slide

  10. 10
    PEGΛElixirͰ࢖͏ʹ͸
    PEGͷElixirʹΑΔ࣮૷͕͋Δʢ΍΍ݹ͍͚Ͳʣ
    ग़ॴɿjtmoulia/neotomex: A PEG parser/transformer with a pleasant Elixir DSL.

    View Slide

  11. 11
    Neotomexೖ໳
    PEGʹΑΔจ๏هड़ΛElixirͷDSLͰॻ͚Δʂʢ਺ࣈΛύʔε͢Δྫʣ
    defmodule Number do
    use Neotomex.ExGrammar
    @root true
    define :number, "digit+" do
    digits -> digits |> Enum.join |> String.to_integer
    end
    define :digit, "[0-9]"
    end
    42 = Number.parse! "42"
    ग़ॴɿjtmoulia/neotomex: A PEG parser/transformer with a pleasant Elixir DSL.

    View Slide

  12. 12
    DSLʹΑΔจ๏ఆ͔ٛΒAST΁
    1.PEGͷจ๏͕DSLԽ͞Ε͍ͯΔͷ
    ͰɺͦΕʹԊͬͯݴޠͷจ๏ͱϚο
    νͨ࣌͠ͷૢ࡞Λॻ͍͍ͯ͘
    2.طʹ࡞ͬͨந৅ߏจʹϚον͢ΔΑ
    ͏จ๏Λఆٛͯ͠ɺ۩৅ߏจΛந৅
    ߏจʹม׵͍ͯ͘͠
    PEG-LikeͳDSLͰจ๏Λهड़͠ɺ۩৅ߏจΛந৅ߏจʹม׵͍ͯ͘͠
    @root true
    define :additive, "multitive <'+'> additive / multitive" do
    int when is_struct(int, Rorty.Ast.Expr.IntegerLiteral) -
    > int
    [x, y] -> Rorty.Ast.add(x, y)
    end
    # ʢলུʣ
    define :decimal, "[0-9]+" do
    digits ->
    Enum.join(digits)
    |> String.to_integer()
    |> Rorty.Ast.integer()
    end
    ۩৅ߏจΛந৅ߏจ
    ʹม׵͢Δ

    View Slide

  13. 13
    ग़དྷ্͕ͬͨ΋ͷΛ૊Έ߹ΘͤΔ
    ۩৅ߏจʹΑΓهड़͞ΕͨιʔείʔυΛந৅ߏจʹม׵ͯ͠ɺղऍɾ࣮ߦ
    def run(src) do
    {result, _} =
    src
    |> parse()
    |> Rorty.Interpreter.interpret(%Rorty.Env{})
    result
    end
    def parse(src) do
    try do
    src |> String.trim() |> Rorty.Grammar.parse!()
    rescue
    e in Neotomex.Grammar.ParseError ->
    e |> handle_exception()
    end
    end

    View Slide

  14. 14
    What's Next?
    ● Erlang VMʢBEAMʣ্Ͱಈ͘ݴޠ͸BEAM Languagesͱݺ͹ΕΔ
    ● ୅දతͳBEAM Languages͸Erlang/OTP΍Elixir
    ● ଞɺLispʹӨڹΛड͚ͨ΋ͷ΍੩తܕ෇͚ͷ΋ͷͳͲɺগͳ͘ͱ΋33Ҏ্͕͋Δ
    ͜͜Ͱ঺հͨࣗ͠࡞ݴޠ΋ɺElixirͰ࣮ߦ͍ͯ͠ΔͷͰBEAM্Ͱಈ͍ͯ͸͍ΔͷͰɺ
    BEAM Languagesͱ͍͑͹͍͑Δ͚Ͳ……ɻ
    → ͡Ό͋ɺͪΌΜͱͨ͠BEAM Languagesͱ΍ΒΛ࡞ͬͯΈΑ͏͡Όͳ͍͔
    ؆қͳΠϯλϓϦλݴޠ͔ΒYet Another BEAM Language΁
    ग़ॴɿllaisdy/beam_languages: Languages, and about languages, on the BEAM

    View Slide

  15. 15
    BEAM Languagesͷ࣮૷ํࣜ͋Ε͜Ε
    ҰޱʹBEAM Languagesͱ͍ͬͯ΋͍ΖΜͳ΍Γํ͕͋Δ
    ग़ॴɿImplementing languages on the BEAM by Robert Virding & Mariano Guerra | #OpenErlang webinar

    View Slide

  16. 16
    BEAM Languages΁޲͚ͯ
    1.ࣗ࡞ݴޠͷASTΛElixirͷAST΁τϥϯε
    ύΠϧ͢Δʢӈ্ʣ
    2.τϥϯεύΠϧͨ݁͠ՌΛɺ
    Code.eval_quoted/3Ͱ࣮ߦ
    ElixirͷASTΛ࢖͏ͱɺࣗ࡞ݴޠͷந৅ߏจΛElixir
    ʹௐ੔͠ͳ͚Ε͹ͳΒͳ͍͠ɺElixirͷҙຯ࿦ʹറΒ
    Εͯɺ݁ہElixirͷαϒηοτΛ࡞Δ͜ͱʹͳͬͯ͠
    ·͏ɻ
    → ࠓޙͲ͏͢Δ͔͸໎ͬͯΔͱ͜Ζ
    ·ͣ͸ࣗ࡞ݴޠͷASTΛElixirͷAST΁τϥϯεύΠϧͯ͠Έͨ
    defmodule Rorty.Transpiler do
    def transpile(exprs) do
    exprs |> Enum.map(fn expr ->
    Rorty.Protocol.ElixirAst.to_elixir_ast(expr)
    end)
    end
    end
    def run(src, transpile: true) do
    {result, _} =
    src
    |> parse()
    |> transpile()
    |> Code.eval_quoted([], __ENV__)
    result
    end

    View Slide

  17. 17
    ·ͱΊ
    ● ϓϩάϥϛϯάݴޠͷ࡞Γํʹ͍ͭͯઆ໌͍ͯ͠Δॻ੶΍هࣄ͸ͨ͘͞Μ͋Δ͕ɺ
    WEB+DB PRESS Vol.125ͷಛू͸ɺͦͷઆ໌ͷελΠϧʹ͓͍ͯग़৭
    ○ ந৅ߏจˠ۩৅ߏจͱ͍͏આ໌ͷྲྀΕ
    ○ ࣈ۟ղੳͱ͔BNFͱ͔ͦ͏͍͏࿩Λ͠ͳ͍
    ● جຊతʹɺͦ͜Ͱॻ͔Ε͍ͯΔ͜ͱΛຊτʔΫͰઆ໌ͨ͠Α͏ʹElixirతʹಡΈସ͑ͯ
    ࣮૷͍ͯ͘͠ͱɺϓϩάϥϛϯάݴޠͬΆ͍΋ͷ͕Ͱ͖Δ
    ● ͜ͷઌ͸ɺૉ๿ͳΠϯλϓϦλ͔ΒBEAM Languages΁ঢ՚͍͖͍ͤͯͨ͞ͱ͜Ζ
    ElixirͰϓϩάϥϛϯάݴޠΛ࡞Ζ͏ʂ

    View Slide

  18. 18
    ϓϩάϥϛϯάݴޠͷࣗ࡞͸ָ͍͠
    ग़ॴɿhttps://twitter.com/kentaro/status/1454798625603612682

    View Slide

  19. 19
    Thank You!
    Thank You!

    View Slide