Slide 1

Slide 1 text

Format Your Elixir Code Now Jake Worth, Hashrocket

Slide 2

Slide 2 text

2

Slide 3

Slide 3 text

"Elixir master now includes a code formatter that automatically formats your code according to a consistent style. We want to convert Elixir's codebase to use the formatter on all files. We understand this means a lot of code churn now but, on the positive side, it means we can automatically enforce and/or format future contributions, making it easier for everyone to contribute to Elixir."1 1 José Valim, Github Elixir-Lang Issue #6643, https://github.com/elixir-lang/elixir/issues/6643. 3

Slide 4

Slide 4 text

Refactor Stats » 425 files changed » 214 pull requests » 84 committers » 368 commits » 4 days to complete! 4

Slide 5

Slide 5 text

@jwworth Hashrocket 5

Slide 6

Slide 6 text

6

Slide 7

Slide 7 text

A Changing Community » Before v1.6: style is subjective » After v1.6: style conforms to a community style guide 7

Slide 8

Slide 8 text

Questions » What is autoformatting? » Why should I care? » What is it going to do to my code? 8

Slide 9

Slide 9 text

Format your code now. It's where Elixir is headed. 9

Slide 10

Slide 10 text

Agenda 1. History of Autoformatting 2. Arguments For/Against 3. Practical Applications 10

Slide 11

Slide 11 text

Slides » https://speakerdeck.com/jwworth (PDF) 11

Slide 12

Slide 12 text

1. History of Autoformatting 12

Slide 13

Slide 13 text

Autoformat: to cause the layout of a document to be created or edited without further effort by the execution of a program.2 2 Your Dictionary, http://www.yourdictionary.com/, s.v. "Autoformat". 13

Slide 14

Slide 14 text

Linting vs. Autoformatting Tool Target Action Linter Code smells Recommends changes Autoformatter Inconsistent style Recommends + changes code 14

Slide 15

Slide 15 text

GNU Indent » Unix utility that formats C and C++ » Oldest copyright 1989 15

Slide 16

Slide 16 text

Theory: Autoformatting solves a modern problem 16

Slide 17

Slide 17 text

Go + Autoformatting » Go created in 2009 » gofmt released in 2013 » Overview: https:// blog.golang.org/go-fmt-your- code 17

Slide 18

Slide 18 text

Autoformatted Go Easier to write: never worry about minor formatting concerns while hacking away 18

Slide 19

Slide 19 text

Autoformatted Go Easier to read: when all code looks the same you need not mentally convert others' formatting style into something you can understand 19

Slide 20

Slide 20 text

Autoformatted Go Easier to maintain: mechanical changes to the source don't cause unrelated changes to the file's formatting; diffs show only the real changes 20

Slide 21

Slide 21 text

Autoformatted Go Uncontroversial: never have a debate about spacing or brace position ever again! 21

Slide 22

Slide 22 text

Elixir + Autoformatting » Elixir created in 2011 » mix format released in Elixir 1.6 (January 2018) » Overview: José Valim's ElixirConf 2017 keynote 22

Slide 23

Slide 23 text

23

Slide 24

Slide 24 text

We don't talk about these anymore 24

Slide 25

Slide 25 text

2. Arguments For/ Against 25

Slide 26

Slide 26 text

Arguments For/Against For Against Productivity But My Preferences! Consistency Friendliness to Newcomers Execution 26

Slide 27

Slide 27 text

For: Productivity Bikeshedding [originally BSD, now common] Technical disputes over minor, marginal issues conducted while more serious ones are being overlooked. The implied image is of people arguing over what color to paint the bicycle shed while the house is not finished.4 » Most style preferences don't matter 4 The Jargon File (version 4.4.7), http://www.catb.org/, s.v. "Bikeshedding". 27

Slide 28

Slide 28 text

For: Consistency » Elixir should have "a consistent style" » Distinct style guides separate us » We need "collective ownership" of the community's code 28

Slide 29

Slide 29 text

29

Slide 30

Slide 30 text

Eliminate Trivial Decisions 30

Slide 31

Slide 31 text

For: Friendliness to Newcomers » New devs shouldn't have to learn "how things are done here" on every team » Elixir code should be exemplary » Feedback on your code need not always come from a human 31

Slide 32

Slide 32 text

For: Execution Elixir Autoformatter's Guidelines:5 1. It does not change code semantics by default 2. Minimizes configuration 3. No special cases 5 José Valim, "Elixir Conf Keynote 2017", https://www.youtube.com/watch?v=Wa7Ipc0yo (Accessed 7 Feb 2018) 32

Slide 33

Slide 33 text

Against: But My Preferences! » Elixir's formatter always removes "trailing commas" » "No trailing comma (ever)."6 6 José Valim, 'Elixir Style Guide Pull Request #46', https://github.com/lexmag/elixir-style-guide/pull/46. 33

Slide 34

Slide 34 text

Trailing Comma Controversy [ 1, 2 ] [ 1, 2, ] 34

Slide 35

Slide 35 text

Trailing Comma Controversy [ 1, 2 ] [ 1, 2, ] 35

Slide 36

Slide 36 text

I came, I saw, I conquered. 36

Slide 37

Slide 37 text

I came, I saw, I conquered,. 37

Slide 38

Slide 38 text

Trailing Comma Controversy [ 1, 2 ] ‑ [ 1, 2, 3 ] 38

Slide 39

Slide 39 text

Trailing Comma Controversy [ 1, 2 ] ‑ [ 1, 2, 3 ] 39

Slide 40

Slide 40 text

Trailing Comma Controversy [ 1, 2, ] ‑ [ 1, 2, 3, ] 40

Slide 41

Slide 41 text

Trailing Comma Controversy [ 1, 2, ] ‑ [ 1, 2, 3, ] 41

Slide 42

Slide 42 text

Against: But My Preferences! Potential Benefit: If successful, it ends persistent debates 42

Slide 43

Slide 43 text

Any code of your own that you haven't looked at for six or more months might as well have been written by someone else. — Eagleson's Law 43

Slide 44

Slide 44 text

3. Practical Applications 44

Slide 45

Slide 45 text

45

Slide 46

Slide 46 text

46

Slide 47

Slide 47 text

TIL Stats » 90 Total (non-dependency) Elixir files » 31 files (35%) passed the formatter » Conclusion: churn is coming 47

Slide 48

Slide 48 text

# lib/tilex_web/controllers/post_controller.ex plug :load_channels when action in [:new, :create, :edit, :update] 48

Slide 49

Slide 49 text

# lib/tilex_web/controllers/post_controller.ex plug :load_channels when action in [:new, :create, :edit, :update] ‑ plug(:load_channels when action in [:new, :create, :edit, :update]) 49

Slide 50

Slide 50 text

# lib/tilex_web/controllers/post_controller.ex page = params |> Map.get("page", "1") |> String.to_integer 50

Slide 51

Slide 51 text

# lib/tilex_web/controllers/post_controller.ex page = params |> Map.get("page", "1") |> String.to_integer ‑ page = params |> Map.get("page", "1") |> String.to_integer() 51

Slide 52

Slide 52 text

# lib/tilex_web/controllers/post_controller.ex render(conn, "search_results.html", posts: posts, posts_count: posts_count ) 52

Slide 53

Slide 53 text

‑ render( conn, "search_results.html", posts: posts, posts_count: posts_count ) 53

Slide 54

Slide 54 text

# lib/tilex_web/controllers/post_controller.ex post = case current_user.admin do false -> current_user |> assoc(:posts) |> Repo.get_by!(slug: slug) true -> Repo.get_by!(Post, slug: slug) end 54

Slide 55

Slide 55 text

‑ post = case current_user.admin do false -> current_user |> assoc(:posts) |> Repo.get_by!(slug: slug) true -> Repo.get_by!(Post, slug: slug) end 55

Slide 56

Slide 56 text

# lib/tilex_web/router.ex @auth_controller Application.get_env(:tilex, :auth_controller) @cors_origin Application.get_env(:tilex, :cors_origin) 56

Slide 57

Slide 57 text

# lib/tilex_web/router.ex @auth_controller Application.get_env(:tilex, :auth_controller) @cors_origin Application.get_env(:tilex, :cors_origin) ‑ @auth_controller Application.get_env(:tilex, :auth_controller) @cors_origin Application.get_env(:tilex, :cors_origin) 57

Slide 58

Slide 58 text

# config/config.exs config :guardian, Guardian, allowed_algos: ["HS512"], # optional 58

Slide 59

Slide 59 text

# config/config.exs config :guardian, Guardian, allowed_algos: ["HS512"], # optional ‑ config :guardian, Guardian, # optional allowed_algos: ["HS512"], 59

Slide 60

Slide 60 text

CI Integration # .circleci/config.yml steps: - mix format --check-formatted 60

Slide 61

Slide 61 text

Text Editor Integrations Vim: " ~/.vimrc autocmd BufWritePost *.exs,*.ex silent :!mix format --check-equivalent % 61

Slide 62

Slide 62 text

Conclusion: Format Your Code 62

Slide 63

Slide 63 text

@jwworth Hashrocket 63