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

Dive into Elixir v1.6 Code Formatter

Dive into Elixir v1.6 Code Formatter

Speaking about that Elixir code formatter is safe.

M3 Tech Talk #87 2018/02/16 #m3dev

Takayuki Matsubara

February 16, 2018
Tweet

More Decks by Takayuki Matsubara

Other Decks in Programming

Transcript

  1. Deep Dive into
    Elixir v1.6
    Code Formatter
    In 7 Minutes

    View Slide

  2. Who am I?
    me
    |> name # Takayuki "Taka" Matsubara
    |> job # Software Engineer
    |> work_at # M3, Inc.
    |> like # Ruby, Elixir and OSS
    |> twitter # ma2ge
    |> github # ma2gedev
    |> oss # PowerAssertEx, bundle-star, breadcrumble,
    # chrono_logger, faraday-encoding

    View Slide

  3. PowerAssertEx ⭐ 153
    github.com/ma2gedev/power_assert_ex

    View Slide

  4. My Keyboard

    View Slide

  5. Deep Dive into
    Elixir v1.6
    Code Formatter
    In 7 Minutes

    View Slide

  6. Deep Dive into
    Elixir v1.6
    Code Formatter
    In 7 Minutes

    View Slide

  7. Dive into Elixir
    v1.6 Code
    Formatter !

    View Slide

  8. Code Formatter
    • like gofmt
    • https:/
    /golang.org/cmd/gofmt/

    View Slide

  9. Formatting code in
    Elixir
    • The mix format command formats your code
    # Elixir lang example
    ## before
    IO .
    puts ("Elixir is Nice")
    ## after `mix format`
    IO.puts("Elixir is Nice")

    View Slide

  10. But is it safe to
    format?

    View Slide

  11. In Elixir

    View Slide

  12. It's safe with --check-equivalent option
    $ mix format --check-equivalent
    check if the file after formatting has the same AST. If
    the ASTs are not equivalent, it is a bug in the code
    formatter. This option is recommended if you are
    automatically formatting files.
    — https:/
    /hexdocs.pm/mix/1.6.1/
    Mix.Tasks.Format.html

    View Slide

  13. Why is it safe?
    What is same AST
    mean?

    View Slide

  14. What is AST?
    • AST is Abstract Syntax Tree !
    • Elixir's internal representation of code
    • Elixir parses code into AST before executing your
    program
    • Same AST means that code behavior is also same
    Code ! -> AST " -> ... -> Execute #

    View Slide

  15. Detail of formatting process with --check-equivalent option
    1. generate formatted code from original code
    • ! -> "
    2. generate AST both the codes
    • ! -> #
    • " -> #
    3. then compare
    • # ≒ #

    View Slide

  16. Let's experiment

    View Slide

  17. Example code
    # before
    defmodule My do; def coooolest do; "one-liner"; end; end
    # after `mix format`
    defmodule My do
    def coooolest do
    "one-liner"
    end
    end

    View Slide

  18. :elixir.string_to_quoted!/4
    • this function generates AST from the code

    View Slide

  19. Original code's AST
    iex(1)> string1 = "defmodule My do; def coooolest do; \"one-liner\"; end; end"
    "defmodule My do; def coooolest do; \"one-liner\"; end; end"
    iex(2)> :elixir.string_to_quoted!(to_charlist(string1), 1, "nofile", [])
    {
    :defmodule,
    [line: 1],
    [
    {:__aliases__, [line: 1], [:My]},
    [do: {:def, [line: 1], [{:coooolest, [line: 1], nil}, [do: "one-liner"]]}]
    ]
    }

    View Slide

  20. Formatted code's AST
    iex(1)> string2 = """
    ...(1)> defmodule My do
    ...(1)> def coooolest do
    ...(1)> "one-liner"
    ...(1)> end
    ...(1)> end
    ...(1)> """
    "defmodule My do\n def coooolest do\n \"one-liner\"\n end\nend\n"
    iex(2)> :elixir.string_to_quoted!(to_charlist(string2), 1, "nofile", [])
    {
    :defmodule,
    [line: 1],
    [
    {:__aliases__, [line: 1], [:My]},
    [do: {:def, [line: 2], [{:coooolest, [line: 2], nil}, [do: "one-liner"]]}]
    ]
    }

    View Slide

  21. Compare both of ASTs
    • The diff shows almost same but [line: X] is
    indifferent !
    • But this is metadata so it does not affect behavior "
    # diff
    + [do: {:def, [line: 2], [{:coooolest, [line: 2], nil}, [do: "one-liner"]]}]
    - [do: {:def, [line: 1], [{:coooolest, [line: 1], nil}, [do: "one-liner"]]}]

    View Slide

  22. Code formatting is safe with --check-equivalent option
    $ mix format --check-equivalent

    View Slide

  23. Recap
    • Elixir's code formatter can compare formatted code
    with original one at AST level so its safely to use

    View Slide

  24. Thanks !
    M3 Tech Talk #87 2018/02/16 #m3dev
    @ma2ge

    View Slide