{"id":13429687,"url":"https://github.com/christopheradams/elixir_style_guide","last_synced_at":"2025-12-17T15:41:28.441Z","repository":{"id":1013397,"uuid":"13060236","full_name":"christopheradams/elixir_style_guide","owner":"christopheradams","description":"A community driven style guide for Elixir","archived":false,"fork":false,"pushed_at":"2024-05-10T03:55:51.000Z","size":214,"stargazers_count":4417,"open_issues_count":8,"forks_count":301,"subscribers_count":116,"default_branch":"master","last_synced_at":"2025-11-30T21:40:33.215Z","etag":null,"topics":["elixir","elixir-lang","style-guide","styleguide"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/christopheradams.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-09-24T09:35:30.000Z","updated_at":"2025-11-25T10:32:23.000Z","dependencies_parsed_at":"2024-06-20T15:53:08.954Z","dependency_job_id":null,"html_url":"https://github.com/christopheradams/elixir_style_guide","commit_stats":{"total_commits":239,"total_committers":57,"mean_commits":4.192982456140351,"dds":0.4769874476987448,"last_synced_commit":"dc29a216a5bc4d27b03e9c858205fb61c3e181ba"},"previous_names":["niftyn8/elixir_style_guide"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/christopheradams/elixir_style_guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopheradams%2Felixir_style_guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopheradams%2Felixir_style_guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopheradams%2Felixir_style_guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopheradams%2Felixir_style_guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christopheradams","download_url":"https://codeload.github.com/christopheradams/elixir_style_guide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopheradams%2Felixir_style_guide/sbom","scorecard":{"id":281100,"data":{"date":"2025-08-11","repo":{"name":"github.com/christopheradams/elixir_style_guide","commit":"1f2fdf68fe54af49a92bf7c1e876dd7fc8c8b149"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":4,"reason":"Found 14/29 approved changesets -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T15:53:25.845Z","repository_id":1013397,"created_at":"2025-08-17T15:53:25.845Z","updated_at":"2025-08-17T15:53:25.845Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27784450,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-17T02:00:08.291Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","elixir-lang","style-guide","styleguide"],"created_at":"2024-07-31T02:00:43.740Z","updated_at":"2025-12-17T15:41:28.420Z","avatar_url":"https://github.com/christopheradams.png","language":"Elixir","readme":"# [The Elixir Style Guide][Elixir Style Guide]\n\n## Table of Contents\n\n* __[Prelude](#prelude)__\n* __[About](#about)__\n* __[Formatting](#formatting)__\n  * [Whitespace](#whitespace)\n  * [Indentation](#indentation)\n  * [Parentheses](#parentheses)\n* __[The Guide](#the-guide)__\n  * [Expressions](#expressions)\n  * [Naming](#naming)\n  * [Comments](#comments)\n    * [Comment Annotations](#comment-annotations)\n  * [Modules](#modules)\n  * [Documentation](#documentation)\n  * [Typespecs](#typespecs)\n  * [Structs](#structs)\n  * [Exceptions](#exceptions)\n  * [Collections](#collections)\n  * [Strings](#strings)\n  * _Regular Expressions_\n  * [Metaprogramming](#metaprogramming)\n  * [Testing](#testing)\n* __[Resources](#resources)__\n  * [Alternative Style Guides](#alternative-style-guides)\n  * [Tools](#tools)\n* __[Getting Involved](#getting-involved)__\n  * [Contributing](#contributing)\n  * [Spread the Word](#spread-the-word)\n* __[Copying](#copying)__\n  * [License](#license)\n  * [Attribution](#attribution)\n\n## Prelude\n\n\u003e Liquid architecture. It's like jazz — you improvise, you work together, you\n\u003e play off each other, you make something, they make something.\n\u003e\n\u003e —Frank Gehry\n\nStyle matters.\n[Elixir] has plenty of style but like all languages it can be stifled.\nDon't stifle the style.\n\n## About\n\nThis is community style guide for the [Elixir programming language][Elixir].\nPlease feel free to make pull requests and suggestions, and be a part of\nElixir's vibrant community.\n\nIf you're looking for other projects to contribute to please see the\n[Hex package manager site][Hex].\n\n\u003ca name=\"translations\"\u003e\u003c/a\u003e\nTranslations of the guide are available in the following languages:\n\n* [Chinese Simplified]\n* [Chinese Traditional]\n* [French]\n* [Japanese]\n* [Korean]\n* [Portuguese]\n* [Russian]\n* [Spanish]\n* [Thai]\n\n## Formatting\n\nElixir v1.6 introduced a [Code Formatter] and [Mix format] task.\nThe formatter should be preferred for all new projects and source code.\n\nThe rules in this section are applied automatically by the code formatter, but\nare provided here as examples of the preferred style.\n\n### Whitespace\n\n* \u003ca name=\"trailing-whitespace\"\u003e\u003c/a\u003e\n  Avoid trailing whitespace.\n  \u003csup\u003e[[link](#trailing-whitespace)]\u003c/sup\u003e\n\n* \u003ca name=\"newline-eof\"\u003e\u003c/a\u003e\n  End each file with a newline.\n  \u003csup\u003e[[link](#newline-eof)]\u003c/sup\u003e\n\n* \u003ca name=\"line-endings\"\u003e\u003c/a\u003e\n  Use Unix-style line endings (\\*BSD/Solaris/Linux/OSX users are covered by\n  default, Windows users have to be extra careful).\n  \u003csup\u003e[[link](#line-endings)]\u003c/sup\u003e\n\n* \u003ca name=\"autocrlf\"\u003e\u003c/a\u003e\n  If you're using Git you might want to add the following configuration\n  setting to protect your project from Windows line endings creeping in:\n  \u003csup\u003e[[link](#autocrlf)]\u003c/sup\u003e\n\n  ```sh\n  git config --global core.autocrlf true\n  ```\n\n* \u003ca name=\"line-length\"\u003e\u003c/a\u003e\n  Limit lines to 98 characters.\n  Otherwise, set the `:line_length` option in your `.formatter.exs` file.\n  \u003csup\u003e[[link](#line-length)]\u003c/sup\u003e\n\n* \u003ca name=\"spaces\"\u003e\u003c/a\u003e\n  Use spaces around operators, after commas, colons and semicolons.\n  Do not put spaces around matched pairs like brackets, parentheses, etc.\n  Whitespace might be (mostly) irrelevant to the Elixir runtime, but its proper\n  use is the key to writing easily readable code.\n  \u003csup\u003e[[link](#spaces)]\u003c/sup\u003e\n\n  ```elixir\n  sum = 1 + 2\n  {a, b} = {2, 3}\n  [first | rest] = [1, 2, 3]\n  Enum.map([\"one\", \u003c\u003c\"two\"\u003e\u003e, \"three\"], fn num -\u003e IO.puts(num) end)\n  ```\n\n* \u003ca name=\"no-spaces\"\u003e\u003c/a\u003e\n  Do not use spaces after non-word operators that only take one argument; or\n  around the range operator.\n  \u003csup\u003e[[link](#no-spaces)]\u003c/sup\u003e\n\n  ```elixir\n  0 - 1 == -1\n  ^pinned = some_func()\n  5 in 1..10\n  ```\n\n* \u003ca name=\"def-spacing\"\u003e\u003c/a\u003e\n  Use blank lines between `def`s to break up a function into logical\n  paragraphs.\n  \u003csup\u003e[[link](#def-spacing)]\u003c/sup\u003e\n\n  ```elixir\n  def some_function(some_data) do\n    some_data |\u003e other_function() |\u003e List.first()\n  end\n\n  def some_function do\n    result\n  end\n\n  def some_other_function do\n    another_result\n  end\n\n  def a_longer_function do\n    one\n    two\n\n    three\n    four\n  end\n  ```\n\n* \u003ca name=\"defmodule-spacing\"\u003e\u003c/a\u003e\n  Don't put a blank line after `defmodule`.\n  \u003csup\u003e[[link](#defmodule-spacing)]\u003c/sup\u003e\n\n* \u003ca name=\"long-dos\"\u003e\u003c/a\u003e\n  If the function head and `do:` clause are too long to fit on the same line, put\n  `do:` on a new line, indented one level more than the previous line.\n  \u003csup\u003e[[link](#long-dos)]\u003c/sup\u003e\n\n  ```elixir\n  def some_function([:foo, :bar, :baz] = args),\n    do: Enum.map(args, fn arg -\u003e arg \u003c\u003e \" is on a very long line!\" end)\n  ```\n\n  When the `do:` clause starts on its own line, treat it as a multiline\n  function by separating it with blank lines.\n\n  ```elixir\n  # not preferred\n  def some_function([]), do: :empty\n  def some_function(_),\n    do: :very_long_line_here\n\n  # preferred\n  def some_function([]), do: :empty\n\n  def some_function(_),\n    do: :very_long_line_here\n  ```\n\n* \u003ca name=\"add-blank-line-after-multiline-assignment\"\u003e\u003c/a\u003e\n  Add a blank line after a multiline assignment as a\n  visual cue that the assignment is 'over'.\n  \u003csup\u003e[[link](#add-blank-line-after-multiline-assignment)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  some_string =\n    \"Hello\"\n    |\u003e String.downcase()\n    |\u003e String.trim()\n  another_string \u003c\u003e some_string\n\n  # preferred\n  some_string =\n    \"Hello\"\n    |\u003e String.downcase()\n    |\u003e String.trim()\n\n  another_string \u003c\u003e some_string\n  ```\n\n  ```elixir\n  # also not preferred\n  something =\n    if x == 2 do\n      \"Hi\"\n    else\n      \"Bye\"\n    end\n  String.downcase(something)\n\n  # preferred\n  something =\n    if x == 2 do\n      \"Hi\"\n    else\n      \"Bye\"\n    end\n\n  String.downcase(something)\n  ```\n\n* \u003ca name=\"multiline-enums\"\u003e\u003c/a\u003e\n  If a list, map, or struct spans multiple lines, put each element, as well as\n  the opening and closing brackets, on its own line.\n  Indent each element one level, but not the brackets.\n  \u003csup\u003e[[link](#multiline-enums)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  [:first_item, :second_item, :next_item,\n  :final_item]\n\n  # preferred\n  [\n    :first_item,\n    :second_item,\n    :next_item,\n    :final_item\n  ]\n  ```\n\n* \u003ca name=\"multiline-list-assign\"\u003e\u003c/a\u003e\n  When assigning a list, map, or struct, keep the opening bracket on the same\n  line as the assignment.\n  \u003csup\u003e[[link](#multiline-list-assign)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  list =\n  [\n    :first_item,\n    :second_item\n  ]\n\n  # preferred\n  list = [\n    :first_item,\n    :second_item\n  ]\n  ```\n\n* \u003ca name=\"multiline-case-clauses\"\u003e\u003c/a\u003e\n  If any `case` or `cond` clause needs more than one line (due to line length,\n  multiple expressions in the clause body, etc.), use multi-line syntax for all\n  clauses, and separate each one with a blank line.\n  \u003csup\u003e[[link](#multiline-case-clauses)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  case arg do\n    true -\u003e IO.puts(\"ok\"); :ok\n    false -\u003e :error\n  end\n\n  # not preferred\n  case arg do\n    true -\u003e\n      IO.puts(\"ok\")\n      :ok\n    false -\u003e :error\n  end\n\n  # preferred\n  case arg do\n    true -\u003e\n      IO.puts(\"ok\")\n      :ok\n\n    false -\u003e\n      :error\n  end\n  ```\n\n* \u003ca name=\"comments-above-line\"\u003e\u003c/a\u003e\n  Place comments above the line they comment on.\n  \u003csup\u003e[[link](#comments-above-line)]\u003c/sup\u003e\n\n  ```elixir\n  String.first(some_string) # not preferred\n\n  # preferred\n  String.first(some_string)\n  ```\n\n* \u003ca name=\"comment-leading-spaces\"\u003e\u003c/a\u003e\n  Use one space between the leading `#` character of the comment and the text of\n  the comment.\n  \u003csup\u003e[[link](#comment-leading-spaces)]\u003c/sup\u003e\n\n  ```elixir\n  #not preferred\n  String.first(some_string)\n\n  # preferred\n  String.first(some_string)\n  ```\n\n### Indentation\n\n* \u003ca name=\"with-clauses\"\u003e\u003c/a\u003e\n  Indent and align successive `with` clauses.\n  Put the `do:` argument on a new line, aligned with the previous clauses.\n  \u003csup\u003e[[link](#with-clauses)]\u003c/sup\u003e\n\n  ```elixir\n  with {:ok, foo} \u003c- fetch(opts, :foo),\n       {:ok, my_var} \u003c- fetch(opts, :my_var),\n       do: {:ok, foo, my_var}\n  ```\n\n* \u003ca name=\"with-else\"\u003e\u003c/a\u003e\n  If the `with` expression has a `do` block with more than one line, or has an\n  `else` option, use multiline syntax.\n  \u003csup\u003e[[link](#with-else)]\u003c/sup\u003e\n\n  ```elixir\n  with {:ok, foo} \u003c- fetch(opts, :foo),\n       {:ok, my_var} \u003c- fetch(opts, :my_var) do\n    {:ok, foo, my_var}\n  else\n    :error -\u003e\n      {:error, :bad_arg}\n  end\n  ```\n\n### Parentheses\n\n* \u003ca name=\"parentheses-pipe-operator\"\u003e\u003c/a\u003e\n  Use parentheses for one-arity functions when using the pipe operator (`|\u003e`).\n  \u003csup\u003e[[link](#parentheses-pipe-operator)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  some_string |\u003e String.downcase |\u003e String.trim\n\n  # preferred\n  some_string |\u003e String.downcase() |\u003e String.trim()\n  ```\n\n* \u003ca name=\"function-names-with-parentheses\"\u003e\u003c/a\u003e\n  Never put a space between a function name and the opening parenthesis.\n  \u003csup\u003e[[link](#function-names-with-parentheses)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  f (3 + 2)\n\n  # preferred\n  f(3 + 2)\n  ```\n\n* \u003ca name=\"function-calls-and-parentheses\"\u003e\u003c/a\u003e\n  Use parentheses in function calls, especially inside a pipeline.\n  \u003csup\u003e[[link](#function-calls-and-parentheses)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  f 3\n\n  # preferred\n  f(3)\n\n  # not preferred and parses as rem(2, (3 |\u003e g)), which is not what you want.\n  2 |\u003e rem 3 |\u003e g\n\n  # preferred\n  2 |\u003e rem(3) |\u003e g()\n  ```\n\n* \u003ca name=\"keyword-list-brackets\"\u003e\u003c/a\u003e\n  Omit square brackets from keyword lists whenever they are optional.\n  \u003csup\u003e[[link](#keyword-list-brackets)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  some_function(foo, bar, [a: \"baz\", b: \"qux\"])\n\n  # preferred\n  some_function(foo, bar, a: \"baz\", b: \"qux\")\n  ```\n\n## The Guide\n\nThe rules in this section may not be applied by the code formatter, but they are\ngenerally preferred practice.\n\n### Expressions\n\n* \u003ca name=\"single-line-defs\"\u003e\u003c/a\u003e\n  Run single-line `def`s that match for the same function together, but separate\n  multiline `def`s with a blank line.\n  \u003csup\u003e[[link](#single-line-defs)]\u003c/sup\u003e\n\n  ```elixir\n  def some_function(nil), do: {:error, \"No Value\"}\n  def some_function([]), do: :ok\n\n  def some_function([first | rest]) do\n    some_function(rest)\n  end\n  ```\n\n* \u003ca name=\"multiple-function-defs\"\u003e\u003c/a\u003e\n  If you have more than one multiline `def`, do not use single-line `def`s.\n  \u003csup\u003e[[link](#multiple-function-defs)]\u003c/sup\u003e\n\n  ```elixir\n  def some_function(nil) do\n    {:error, \"No Value\"}\n  end\n\n  def some_function([]) do\n    :ok\n  end\n\n  def some_function([first | rest]) do\n    some_function(rest)\n  end\n\n  def some_function([first | rest], opts) do\n    some_function(rest, opts)\n  end\n  ```\n\n* \u003ca name=\"pipe-operator\"\u003e\u003c/a\u003e\n  Use the pipe operator to chain functions together.\n  \u003csup\u003e[[link](#pipe-operator)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  String.trim(String.downcase(some_string))\n\n  # preferred\n  some_string |\u003e String.downcase() |\u003e String.trim()\n\n  # Multiline pipelines are not further indented\n  some_string\n  |\u003e String.downcase()\n  |\u003e String.trim()\n\n  # Multiline pipelines on the right side of a pattern match\n  # should be indented on a new line\n  sanitized_string =\n    some_string\n    |\u003e String.downcase()\n    |\u003e String.trim()\n  ```\n\n  While this is the preferred method, take into account that copy-pasting\n  multiline pipelines into IEx might result in a syntax error, as IEx will\n  evaluate the first line without realizing that the next line has a pipeline.\n  To avoid this, you can wrap the pasted code in parentheses.\n\n* \u003ca name=\"avoid-single-pipelines\"\u003e\u003c/a\u003e\n  Avoid using the pipe operator just once.\n  \u003csup\u003e[[link](#avoid-single-pipelines)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  some_string |\u003e String.downcase()\n\n  System.version() |\u003e Version.parse()\n\n  # preferred\n  String.downcase(some_string)\n\n  Version.parse(System.version())\n  ```\n\n* \u003ca name=\"bare-variables\"\u003e\u003c/a\u003e\n  Use _bare_ variables in the first part of a function chain.\n  \u003csup\u003e[[link](#bare-variables)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  String.trim(some_string) |\u003e String.downcase() |\u003e String.codepoints()\n\n  # preferred\n  some_string |\u003e String.trim() |\u003e String.downcase() |\u003e String.codepoints()\n  ```\n\n* \u003ca name=\"fun-def-parentheses\"\u003e\u003c/a\u003e\n  Use parentheses when a `def` has arguments, and omit them when it doesn't.\n  \u003csup\u003e[[link](#fun-def-parentheses)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  def some_function arg1, arg2 do\n    # body omitted\n  end\n\n  def some_function() do\n    # body omitted\n  end\n\n  # preferred\n  def some_function(arg1, arg2) do\n    # body omitted\n  end\n\n  def some_function do\n    # body omitted\n  end\n  ```\n\n* \u003ca name=\"do-with-single-line-if-unless\"\u003e\u003c/a\u003e\n  Use `do:` for single line `if/unless` statements.\n  \u003csup\u003e[[link](#do-with-single-line-if-unless)]\u003c/sup\u003e\n\n  ```elixir\n  # preferred\n  if some_condition, do: # some_stuff\n  ```\n\n* \u003ca name=\"unless-with-else\"\u003e\u003c/a\u003e\n  Never use `unless` with `else`.\n  Rewrite these with the positive case first.\n  \u003csup\u003e[[link](#unless-with-else)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  unless success do\n    IO.puts('failure')\n  else\n    IO.puts('success')\n  end\n\n  # preferred\n  if success do\n    IO.puts('success')\n  else\n    IO.puts('failure')\n  end\n  ```\n\n* \u003ca name=\"true-as-last-condition\"\u003e\u003c/a\u003e\n  Use `true` as the last condition of the `cond` special form when you need a\n  clause that always matches.\n  \u003csup\u003e[[link](#true-as-last-condition)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  cond do\n    1 + 2 == 5 -\u003e\n      \"Nope\"\n\n    1 + 3 == 5 -\u003e\n      \"Uh, uh\"\n\n    :else -\u003e\n      \"OK\"\n  end\n\n  # preferred\n  cond do\n    1 + 2 == 5 -\u003e\n      \"Nope\"\n\n    1 + 3 == 5 -\u003e\n      \"Uh, uh\"\n\n    true -\u003e\n      \"OK\"\n  end\n  ```\n\n* \u003ca name=\"parentheses-and-functions-with-zero-arity\"\u003e\u003c/a\u003e\n  Use parentheses for calls to functions with zero arity, so they can be\n  distinguished from variables.\n  Starting in Elixir 1.4, the compiler will warn you about\n  locations where this ambiguity exists.\n  \u003csup\u003e[[link](#parentheses-and-functions-with-zero-arity)]\u003c/sup\u003e\n\n  ```elixir\n  defp do_stuff, do: ...\n\n  # not preferred\n  def my_func do\n    # is this a variable or a function call?\n    do_stuff\n  end\n\n  # preferred\n  def my_func do\n    # this is clearly a function call\n    do_stuff()\n  end\n  ```\n\n### Naming\n\nThis guide follows the [Naming Conventions] from the Elixir docs,\nincluding the use of `snake_case` and `CamelCase` to describe the casing\nrules.\n\n* \u003ca name=\"snake-case\"\u003e\u003c/a\u003e\n  Use `snake_case` for atoms, functions and variables.\n  \u003csup\u003e[[link](#snake-case)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  :\"some atom\"\n  :SomeAtom\n  :someAtom\n\n  someVar = 5\n\n  def someFunction do\n    ...\n  end\n\n  # preferred\n  :some_atom\n\n  some_var = 5\n\n  def some_function do\n    ...\n  end\n  ```\n\n* \u003ca name=\"camel-case\"\u003e\u003c/a\u003e\n  Use `CamelCase` for modules (keep acronyms like HTTP, RFC, XML uppercase).\n  \u003csup\u003e[[link](#camel-case)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  defmodule Somemodule do\n    ...\n  end\n\n  defmodule Some_Module do\n    ...\n  end\n\n  defmodule SomeXml do\n    ...\n  end\n\n  # preferred\n  defmodule SomeModule do\n    ...\n  end\n\n  defmodule SomeXML do\n    ...\n  end\n  ```\n\n* \u003ca name=\"predicate-function-trailing-question-mark\"\u003e\u003c/a\u003e\n  Functions that return a boolean (`true` or `false`) should be named\n  with a trailing question mark.\n  \u003csup\u003e[[link](#predicate-function-trailing-question-mark)]\u003c/sup\u003e\n\n  ```elixir\n  def cool?(var) do\n    String.contains?(var, \"cool\")\n  end\n  ```\n\n* \u003ca name=\"predicate-function-is-prefix\"\u003e\u003c/a\u003e\n  Boolean checks that can be used in guard clauses should be named with\n  an `is_` prefix.\n  For a list of allowed expressions, see the [Guard][Guard Expressions] docs.\n  \u003csup\u003e[[link](#predicate-function-is-prefix)]\u003c/sup\u003e\n\n  ```elixir\n  defguard is_cool(var) when var == \"cool\"\n  defguard is_very_cool(var) when var == \"very cool\"\n  ```\n\n* \u003ca name=\"private-functions-with-same-name-as-public\"\u003e\u003c/a\u003e\n  Private functions should not have the same name as public functions.\n  Also, the `def name` and `defp do_name` pattern is discouraged.\n\n  Usually one can try to find more descriptive names focusing on the differences.\n  \u003csup\u003e[[link](#private-functions-with-same-name-as-public)]\u003c/sup\u003e\n\n  ```elixir\n  def sum(list), do: sum_total(list, 0)\n\n  # private functions\n  defp sum_total([], total), do: total\n  defp sum_total([head | tail], total), do: sum_total(tail, head + total)\n  ```\n\n### Comments\n\n* \u003ca name=\"expressive-code\"\u003e\u003c/a\u003e\n  Write expressive code and try to convey your program's intention through\n  control-flow, structure and naming.\n  \u003csup\u003e[[link](#expressive-code)]\u003c/sup\u003e\n\n* \u003ca name=\"comment-grammar\"\u003e\u003c/a\u003e\n  Comments longer than a word are capitalized, and sentences use punctuation.\n  Use [one space][Sentence Spacing] after periods.\n  \u003csup\u003e[[link](#comment-grammar)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  # these lowercase comments are missing punctuation\n\n  # preferred\n  # Capitalization example\n  # Use punctuation for complete sentences.\n  ```\n\n* \u003ca name=\"comment-line-length\"\u003e\u003c/a\u003e\n  Limit comment lines to 100 characters.\n  \u003csup\u003e[[link](#comment-line-length)]\u003c/sup\u003e\n\n#### Comment Annotations\n\n* \u003ca name=\"annotations\"\u003e\u003c/a\u003e\n  Annotations should usually be written on the line immediately above the\n  relevant code.\n  \u003csup\u003e[[link](#annotations)]\u003c/sup\u003e\n\n* \u003ca name=\"annotation-keyword\"\u003e\u003c/a\u003e\n  The annotation keyword is uppercase, and is followed by a colon and a space,\n  then a note describing the problem.\n  \u003csup\u003e[[link](#annotation-keyword)]\u003c/sup\u003e\n\n  ```elixir\n  # TODO: Deprecate in v1.5.\n  def some_function(arg), do: {:ok, arg}\n  ```\n\n* \u003ca name=\"exceptions-to-annotations\"\u003e\u003c/a\u003e\n  In cases where the problem is so obvious that any documentation would be\n  redundant, annotations may be left with no note.\n  This usage should be the exception and not the rule.\n  \u003csup\u003e[[link](#exceptions-to-annotations)]\u003c/sup\u003e\n\n  ```elixir\n  start_task()\n\n  # FIXME\n  Process.sleep(5000)\n  ```\n\n* \u003ca name=\"todo-notes\"\u003e\u003c/a\u003e\n  Use `TODO` to note missing features or functionality that should be added at a\n  later date.\n  \u003csup\u003e[[link](#todo-notes)]\u003c/sup\u003e\n\n* \u003ca name=\"fixme-notes\"\u003e\u003c/a\u003e\n  Use `FIXME` to note broken code that needs to be fixed.\n  \u003csup\u003e[[link](#fixme-notes)]\u003c/sup\u003e\n\n* \u003ca name=\"optimize-notes\"\u003e\u003c/a\u003e\n  Use `OPTIMIZE` to note slow or inefficient code that may cause performance\n  problems.\n  \u003csup\u003e[[link](#optimize-notes)]\u003c/sup\u003e\n\n* \u003ca name=\"hack-notes\"\u003e\u003c/a\u003e\n  Use `HACK` to note code smells where questionable coding practices were used\n  and should be refactored away.\n  \u003csup\u003e[[link](#hack-notes)]\u003c/sup\u003e\n\n* \u003ca name=\"review-notes\"\u003e\u003c/a\u003e\n  Use `REVIEW` to note anything that should be looked at to confirm it is\n  working as intended.\n  For example: `REVIEW: Are we sure this is how the client does X currently?`\n  \u003csup\u003e[[link](#review-notes)]\u003c/sup\u003e\n\n* \u003ca name=\"custom-keywords\"\u003e\u003c/a\u003e\n  Use other custom annotation keywords if it feels appropriate, but be sure to\n  document them in your project's `README` or similar.\n  \u003csup\u003e[[link](#custom-keywords)]\u003c/sup\u003e\n\n### Modules\n\n* \u003ca name=\"one-module-per-file\"\u003e\u003c/a\u003e\n  Use one module per file unless the module is only used internally by another\n  module (such as a test).\n  \u003csup\u003e[[link](#one-module-per-file)]\u003c/sup\u003e\n\n* \u003ca name=\"underscored-filenames\"\u003e\u003c/a\u003e\n  Use `snake_case` file names for `CamelCase` module names.\n  \u003csup\u003e[[link](#underscored-filenames)]\u003c/sup\u003e\n\n  ```elixir\n  # file is called some_module.ex\n\n  defmodule SomeModule do\n  end\n  ```\n\n* \u003ca name=\"module-name-nesting\"\u003e\u003c/a\u003e\n  Represent each level of nesting within a module name as a directory.\n  \u003csup\u003e[[link](#module-name-nesting)]\u003c/sup\u003e\n\n  ```elixir\n  # file is called parser/core/xml_parser.ex\n\n  defmodule Parser.Core.XMLParser do\n  end\n  ```\n\n* \u003ca name=\"module-attribute-ordering\"\u003e\u003c/a\u003e\n  List module attributes, directives, and macros in the following order:\n  \u003csup\u003e[[link](#module-attribute-ordering)]\u003c/sup\u003e\n\n  1. `@moduledoc`\n  1. `@behaviour`\n  1. `use`\n  1. `import`\n  1. `require`\n  1. `alias`\n  1. `@module_attribute`\n  1. `defstruct`\n  1. `@type`\n  1. `@callback`\n  1. `@macrocallback`\n  1. `@optional_callbacks`\n  1. `defmacro`, `defmodule`, `defguard`, `def`, etc.\n\n  Add a blank line between each grouping, and sort the terms (like module names)\n  alphabetically.\n  Here's an overall example of how you should order things in your modules:\n\n  ```elixir\n  defmodule MyModule do\n    @moduledoc \"\"\"\n    An example module\n    \"\"\"\n\n    @behaviour MyBehaviour\n\n    use GenServer\n\n    import Something\n    import SomethingElse\n\n    require Integer\n\n    alias My.Long.Module.Name\n    alias My.Other.Module.Example\n\n    @module_attribute :foo\n    @other_attribute 100\n\n    defstruct [:name, params: []]\n\n    @type params :: [{binary, binary}]\n\n    @callback some_function(term) :: :ok | {:error, term}\n\n    @macrocallback macro_name(term) :: Macro.t()\n\n    @optional_callbacks macro_name: 1\n\n    @doc false\n    defmacro __using__(_opts), do: :no_op\n\n    @doc \"\"\"\n    Determines when a term is `:ok`. Allowed in guards.\n    \"\"\"\n    defguard is_ok(term) when term == :ok\n\n    @impl true\n    def init(state), do: {:ok, state}\n\n    # Define other functions here.\n  end\n  ```\n\n* \u003ca name=\"module-pseudo-variable\"\u003e\u003c/a\u003e\n  Use the `__MODULE__` pseudo variable when a module refers to itself. This\n  avoids having to update any self-references when the module name changes.\n  \u003csup\u003e[[link](#module-pseudo-variable)]\u003c/sup\u003e\n\n  ```elixir\n  defmodule SomeProject.SomeModule do\n    defstruct [:name]\n\n    def name(%__MODULE__{name: name}), do: name\n  end\n  ```\n\n* \u003ca name=\"alias-self-referencing-modules\"\u003e\u003c/a\u003e\n  If you want a prettier name for a module self-reference, set up an alias.\n  \u003csup\u003e[[link](#alias-self-referencing-modules)]\u003c/sup\u003e\n\n  ```elixir\n  defmodule SomeProject.SomeModule do\n    alias __MODULE__, as: SomeModule\n\n    defstruct [:name]\n\n    def name(%SomeModule{name: name}), do: name\n  end\n  ```\n\n* \u003ca name=\"repetitive-module-names\"\u003e\u003c/a\u003e\n  Avoid repeating fragments in module names and namespaces.\n  This improves overall readability and\n  eliminates [ambiguous aliases][Conflicting Aliases].\n  \u003csup\u003e[[link](#repetitive-module-names)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  defmodule Todo.Todo do\n    ...\n  end\n\n  # preferred\n  defmodule Todo.Item do\n    ...\n  end\n  ```\n\n### Documentation\n\nDocumentation in Elixir (when read either in `iex` with `h` or generated with\n[ExDoc]) uses the [Module Attributes] `@moduledoc` and `@doc`.\n\n* \u003ca name=\"moduledocs\"\u003e\u003c/a\u003e\n  Always include a `@moduledoc` attribute in the line right after `defmodule` in\n  your module.\n  \u003csup\u003e[[link](#moduledocs)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n\n  defmodule AnotherModule do\n    use SomeModule\n\n    @moduledoc \"\"\"\n    About the module\n    \"\"\"\n    ...\n  end\n\n  # preferred\n\n  defmodule AThirdModule do\n    @moduledoc \"\"\"\n    About the module\n    \"\"\"\n\n    use SomeModule\n    ...\n  end\n  ```\n\n* \u003ca name=\"moduledoc-false\"\u003e\u003c/a\u003e\n  Use `@moduledoc false` if you do not intend on documenting the module.\n  \u003csup\u003e[[link](#moduledoc-false)]\u003c/sup\u003e\n\n  ```elixir\n  defmodule SomeModule do\n    @moduledoc false\n    ...\n  end\n  ```\n\n* \u003ca name=\"moduledoc-spacing\"\u003e\u003c/a\u003e\n  Separate code after the `@moduledoc` with a blank line.\n  \u003csup\u003e[[link](#moduledoc-spacing)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  defmodule SomeModule do\n    @moduledoc \"\"\"\n    About the module\n    \"\"\"\n    use AnotherModule\n  end\n\n  # preferred\n  defmodule SomeModule do\n    @moduledoc \"\"\"\n    About the module\n    \"\"\"\n\n    use AnotherModule\n  end\n  ```\n\n* \u003ca name=\"heredocs\"\u003e\u003c/a\u003e\n  Use heredocs with markdown for documentation.\n  \u003csup\u003e[[link](#heredocs)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  defmodule SomeModule do\n    @moduledoc \"About the module\"\n  end\n\n  defmodule SomeModule do\n    @moduledoc \"\"\"\n    About the module\n\n    Examples:\n    iex\u003e SomeModule.some_function\n    :result\n    \"\"\"\n  end\n\n  # preferred\n  defmodule SomeModule do\n    @moduledoc \"\"\"\n    About the module\n\n    ## Examples\n\n        iex\u003e SomeModule.some_function\n        :result\n    \"\"\"\n  end\n  ```\n\n### Typespecs\n\nTypespecs are notation for declaring types and specifications, for\ndocumentation or for the static analysis tool Dialyzer.\n\nCustom types should be defined at the top of the module with the other\ndirectives (see [Modules](#modules)).\n\n* \u003ca name=\"typedocs\"\u003e\u003c/a\u003e\n  Place `@typedoc` and `@type` definitions together, and separate each\n  pair with a blank line.\n  \u003csup\u003e[[link](#typedocs)]\u003c/sup\u003e\n\n  ```elixir\n  defmodule SomeModule do\n    @moduledoc false\n\n    @typedoc \"The name\"\n    @type name :: atom\n\n    @typedoc \"The result\"\n    @type result :: {:ok, term} | {:error, term}\n\n    ...\n  end\n  ```\n\n* \u003ca name=\"union-types\"\u003e\u003c/a\u003e\n  If a union type is too long to fit on a single line, put each part of the\n  type on a separate line, indented one level past the name of the type.\n  \u003csup\u003e[[link](#union-types)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  @type long_union_type ::\n          some_type | another_type | some_other_type | one_more_type | a_final_type\n\n  # preferred\n  @type long_union_type ::\n          some_type\n          | another_type\n          | some_other_type\n          | one_more_type\n          | a_final_type\n  ```\n\n* \u003ca name=\"naming-main-types\"\u003e\u003c/a\u003e\n  Name the main type for a module `t`, for example: the type specification for a\n  struct.\n  \u003csup\u003e[[link](#naming-main-types)]\u003c/sup\u003e\n\n  ```elixir\n  defstruct [:name, params: []]\n\n  @type t :: %__MODULE__{\n          name: String.t() | nil,\n          params: Keyword.t()\n        }\n  ```\n\n* \u003ca name=\"spec-spacing\"\u003e\u003c/a\u003e\n  Place specifications right before the function definition,\n  after the `@doc`,\n  without separating them by a blank line.\n  \u003csup\u003e[[link](#spec-spacing)]\u003c/sup\u003e\n\n  ```elixir\n  @doc \"\"\"\n  Some function description.\n  \"\"\"\n  @spec some_function(term) :: result\n  def some_function(some_data) do\n    {:ok, some_data}\n  end\n  ```\n\n### Structs\n\n* \u003ca name=\"nil-struct-field-defaults\"\u003e\u003c/a\u003e\n  Use a list of atoms for struct fields that default to `nil`, followed by the\n  other keywords.\n  \u003csup\u003e[[link](#nil-struct-field-defaults)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  defstruct name: nil, params: nil, active: true\n\n  # preferred\n  defstruct [:name, :params, active: true]\n  ```\n\n* \u003ca name=\"struct-def-brackets\"\u003e\u003c/a\u003e\n  Omit square brackets when the argument of a `defstruct` is a keyword list.\n  \u003csup\u003e[[link](#struct-def-brackets)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  defstruct [params: [], active: true]\n\n  # preferred\n  defstruct params: [], active: true\n\n  # required - brackets are not optional, with at least one atom in the list\n  defstruct [:name, params: [], active: true]\n  ```\n\n* \u003ca name=\"multiline-structs\"\u003e\u003c/a\u003e\n  If a struct definition spans multiple lines, put each element on its own line,\n  keeping the elements aligned.\n  \u003csup\u003e[[link](#multiline-structs)]\u003c/sup\u003e\n\n  ```elixir\n  defstruct foo: \"test\",\n            bar: true,\n            baz: false,\n            qux: false,\n            quux: 1\n  ```\n\n  If a multiline struct requires brackets, format it as a multiline list:\n\n  ```elixir\n  defstruct [\n    :name,\n    params: [],\n    active: true\n  ]\n  ```\n\n### Exceptions\n\n* \u003ca name=\"exception-names\"\u003e\u003c/a\u003e\n  Make exception names end with a trailing `Error`.\n  \u003csup\u003e[[link](#exception-names)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  defmodule BadHTTPCode do\n    defexception [:message]\n  end\n\n  defmodule BadHTTPCodeException do\n    defexception [:message]\n  end\n\n  # preferred\n  defmodule BadHTTPCodeError do\n    defexception [:message]\n  end\n  ```\n\n* \u003ca name=\"lowercase-error-messages\"\u003e\u003c/a\u003e\n  Use lowercase error messages when raising exceptions, with no trailing\n  punctuation.\n  \u003csup\u003e[[link](#lowercase-error-messages)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  raise ArgumentError, \"This is not valid.\"\n\n  # preferred\n  raise ArgumentError, \"this is not valid\"\n  ```\n\n### Collections\n\n* \u003ca name=\"keyword-list-syntax\"\u003e\u003c/a\u003e\n  Always use the special syntax for keyword lists.\n  \u003csup\u003e[[link](#keyword-list-syntax)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  some_value = [{:a, \"baz\"}, {:b, \"qux\"}]\n\n  # preferred\n  some_value = [a: \"baz\", b: \"qux\"]\n  ```\n\n* \u003ca name=\"map-key-atom\"\u003e\u003c/a\u003e\n  Use the shorthand key-value syntax for maps when all of the keys are atoms.\n  \u003csup\u003e[[link](#map-key-atom)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  %{:a =\u003e 1, :b =\u003e 2, :c =\u003e 0}\n\n  # preferred\n  %{a: 1, b: 2, c: 3}\n  ```\n\n* \u003ca name=\"map-key-arrow\"\u003e\u003c/a\u003e\n  Use the verbose key-value syntax for maps if any key is not an atom.\n  \u003csup\u003e[[link](#map-key-arrow)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  %{\"c\" =\u003e 0, a: 1, b: 2}\n\n  # preferred\n  %{:a =\u003e 1, :b =\u003e 2, \"c\" =\u003e 0}\n  ```\n\n### Strings\n\n* \u003ca name=\"strings-matching-with-concatenator\"\u003e\u003c/a\u003e\n  Match strings using the string concatenator rather than binary patterns:\n  \u003csup\u003e[[link](#strings-matching-with-concatenator)]\u003c/sup\u003e\n\n  ```elixir\n  # not preferred\n  \u003c\u003c\"my\"::utf8, _rest::bytes\u003e\u003e = \"my string\"\n\n  # preferred\n  \"my\" \u003c\u003e _rest = \"my string\"\n  ```\n\n### Regular Expressions\n\n_No guidelines for regular expressions have been added yet._\n\n### Metaprogramming\n\n* \u003ca name=\"avoid-metaprogramming\"\u003e\u003c/a\u003e\n  Avoid needless metaprogramming.\n  \u003csup\u003e[[link](#avoid-metaprogramming)]\u003c/sup\u003e\n\n### Testing\n\n* \u003ca name=\"testing-assert-order\"\u003e\u003c/a\u003e\n  When writing [ExUnit] assertions, put the expression being tested to the left\n  of the operator, and the expected result to the right, unless the assertion is\n  a pattern match.\n  \u003csup\u003e[[link](#testing-assert-order)]\u003c/sup\u003e\n\n  ```elixir\n  # preferred\n  assert actual_function(1) == true\n\n  # not preferred\n  assert true == actual_function(1)\n\n  # required - the assertion is a pattern match\n  assert {:ok, expected} = actual_function(3)\n  ```\n\n## Resources\n\n### Alternative Style Guides\n\n* [Aleksei Magusev's Elixir Style Guide](https://github.com/lexmag/elixir-style-guide#readme)\n  — An opinionated Elixir style guide stemming from the coding style practiced\n  in the Elixir core libraries.\n  Developed by [Aleksei Magusev](https://github.com/lexmag) and\n  [Andrea Leopardi](https://github.com/whatyouhide), members of Elixir core team.\n  While the Elixir project doesn't adhere to any specific style guide,\n  this is the closest available guide to its conventions.\n\n* [Credo's Elixir Style Guide](https://github.com/rrrene/elixir-style-guide#readme)\n  — Style Guide for the Elixir language, implemented by\n  [Credo](http://credo-ci.org) static code analysis tool.\n\n### Tools\n\nRefer to [Awesome Elixir][Code Analysis] for libraries and tools that can help\nwith code analysis and style linting.\n\n## Getting Involved\n\n### Contributing\n\nIt's our hope that this will become a central hub for community discussion on\nbest practices in Elixir.\nFeel free to open tickets or send pull requests with improvements.\nThanks in advance for your help!\n\nCheck the [contributing guidelines][Contributing] for more information.\n\n### Spread the Word\n\nA community style guide is meaningless without the community's support. Please\ntweet, [star][Stargazers], and let any Elixir programmer know\nabout [this guide][Elixir Style Guide] so they can contribute.\n\n## Copying\n\n### License\n\n![Creative Commons License](http://i.creativecommons.org/l/by/3.0/88x31.png)\nThis work is licensed under a\n[Creative Commons Attribution 3.0 Unported License][License]\n\n### Attribution\n\nThe structure of this guide, bits of example code, and many of the initial\npoints made in this document were borrowed from the [Ruby community style guide].\nA lot of things were applicable to Elixir and allowed us to get _some_ document\nout quicker to start the conversation.\n\nHere's the [list of people who have kindly contributed][Contributors] to this\nproject.\n\n\u003c!-- Links --\u003e\n[Chinese Simplified]: https://github.com/geekerzp/elixir_style_guide/blob/master/README-zhCN.md\n[Chinese Traditional]: https://github.com/elixirtw/elixir_style_guide/blob/master/README_zhTW.md\n[Code Analysis]: https://github.com/h4cc/awesome-elixir#code-analysis\n[Code Of Conduct]: https://github.com/elixir-lang/elixir/blob/master/CODE_OF_CONDUCT.md\n[Code Formatter]: https://hexdocs.pm/elixir/Code.html#format_string!/2\n[Conflicting Aliases]: https://elixirforum.com/t/using-aliases-for-fubar-fubar-named-module/1723\n[Contributing]: https://github.com/christopheradams/elixir_style_guide/blob/master/CONTRIBUTING.md\n[Contributors]: https://github.com/christopheradams/elixir_style_guide/graphs/contributors\n[Elixir Style Guide]: https://github.com/christopheradams/elixir_style_guide\n[Elixir]: http://elixir-lang.org\n[ExDoc]: https://github.com/elixir-lang/ex_doc\n[ExUnit]: https://hexdocs.pm/ex_unit/ExUnit.html\n[French]: https://github.com/ronanboiteau/elixir_style_guide/blob/master/README_frFR.md\n[Guard Expressions]: https://hexdocs.pm/elixir/patterns-and-guards.html#list-of-allowed-functions-and-operators\n[Hex]: https://hex.pm/packages\n[Japanese]: https://github.com/kenichirow/elixir_style_guide/blob/master/README-jaJP.md\n[Korean]: https://github.com/marocchino/elixir_style_guide/blob/new-korean/README-koKR.md\n[License]: http://creativecommons.org/licenses/by/3.0/deed.en_US\n[Mix format]: https://hexdocs.pm/mix/Mix.Tasks.Format.html\n[Module Attributes]: http://elixir-lang.org/getting-started/module-attributes.html#as-annotations\n[Naming Conventions]: https://hexdocs.pm/elixir/naming-conventions.html\n[Portuguese]: https://github.com/gusaiani/elixir_style_guide/blob/master/README_ptBR.md\n[Ruby community style guide]: https://github.com/bbatsov/ruby-style-guide\n[Russian]: https://github.com/sofialapteva/elixir_style_guide/blob/russian/README_ru.md\n[Sentence Spacing]: http://en.wikipedia.org/wiki/Sentence_spacing\n[Spanish]: https://github.com/iver/elixir_style_guide/blob/spanish/i18n/README_es.md\n[Stargazers]: https://github.com/christopheradams/elixir_style_guide/stargazers\n[Thai]: https://github.com/tamectosphere/elixir_style_guide/blob/feat/thai-translation/README_th.md\n","funding_links":[],"categories":["Programming Languages","Elixir","Top 20 packages","Styleguides","Resources","Uncategorized"],"sub_categories":["Elixir","Mesh networks","Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristopheradams%2Felixir_style_guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristopheradams%2Felixir_style_guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristopheradams%2Felixir_style_guide/lists"}