Files
RedBear-OS/local/recipes/kde/kf6-syntaxhighlighting/source/autotests/html/learnelixir.exs.dark.html
T

427 lines
38 KiB
HTML

<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>learnelixir.exs</title>
<meta name="generator" content="KF5::SyntaxHighlighting - Definition (Elixir) - Theme (Breeze Dark)"/>
</head><body style="background-color:#232629;color:#cfcfc2"><pre>
<span style="color:#7a7c7d"># Original: https://learnxinyminutes.com/docs/elixir/</span>
<span style="color:#7a7c7d"># Single line comments start with a number symbol.</span>
<span style="color:#7a7c7d"># There's no multi-line comment,</span>
<span style="color:#7a7c7d"># but you can stack multiple comments.</span>
<span style="color:#7a7c7d"># To use the elixir shell use the `iex` command.</span>
<span style="color:#7a7c7d"># Compile your modules with the `elixirc` command.</span>
<span style="color:#7a7c7d"># Both should be in your path if you installed elixir correctly.</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d">## -- Basic types</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d"># There are numbers</span>
<span style="color:#f67400">3</span> <span style="color:#7a7c7d"># integer</span>
<span style="color:#f67400">0x1F</span> <span style="color:#7a7c7d"># integer</span>
<span style="color:#f67400">3.0</span> <span style="color:#7a7c7d"># float</span>
<span style="color:#7a7c7d"># Atoms, that are literals, a constant with name. They start with `:`.</span>
<span style="color:#27aeae">:hello</span> <span style="color:#7a7c7d"># atom</span>
<span style="color:#7a7c7d"># Tuples that are stored contiguously in memory.</span>
<span style="color:#8e44ad">{</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#8e44ad">}</span> <span style="color:#7a7c7d"># tuple</span>
<span style="color:#7a7c7d"># We can access a tuple element with the `elem` function:</span>
elem<span style="color:#8e44ad">({</span><span style="color:#f67400">1</span>, <span style="color:#f67400">2</span>, <span style="color:#f67400">3</span><span style="color:#8e44ad">}</span>, <span style="color:#f67400">0</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 1</span>
<span style="color:#7a7c7d"># Lists that are implemented as linked lists.</span>
<span style="color:#27ae60">[</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#27ae60">]</span> <span style="color:#7a7c7d"># list</span>
<span style="color:#7a7c7d"># We can access the head and tail of a list as follows:</span>
<span style="color:#27ae60">[</span>head <span style="color:#3f8058">|</span> tail<span style="color:#27ae60">]</span> <span style="color:#3f8058">=</span> <span style="color:#27ae60">[</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#27ae60">]</span>
head <span style="color:#7a7c7d">#=> 1</span>
tail <span style="color:#7a7c7d">#=> [2,3]</span>
<span style="color:#7a7c7d"># In elixir, just like in Erlang, the `=` denotes pattern matching and</span>
<span style="color:#7a7c7d"># not an assignment.</span>
<span style="color:#7a7c7d">#</span>
<span style="color:#7a7c7d"># This means that the left-hand side (pattern) is matched against a</span>
<span style="color:#7a7c7d"># right-hand side.</span>
<span style="color:#7a7c7d">#</span>
<span style="color:#7a7c7d"># This is how the above example of accessing the head and tail of a list works.</span>
<span style="color:#7a7c7d"># A pattern match will error when the sides don't match, in this example</span>
<span style="color:#7a7c7d"># the tuples have different sizes.</span>
<span style="color:#7a7c7d"># {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}</span>
<span style="color:#7a7c7d"># There are also binaries</span>
<span style="color:#3f8058">&lt;&lt;</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#3f8058">>></span> <span style="color:#7a7c7d"># binary</span>
<span style="color:#7a7c7d"># Strings and char lists</span>
<span style="color:#f44f4f">"hello"</span> <span style="color:#7a7c7d"># string</span>
<span style="color:#da4453">'hello'</span> <span style="color:#7a7c7d"># char list</span>
<span style="color:#7a7c7d"># Multi-line strings</span>
<span style="color:#f44f4f">"""</span>
<span style="color:#f44f4f">I'm a multi-line</span>
<span style="color:#f44f4f">string.</span>
<span style="color:#f44f4f">"""</span>
<span style="color:#7a7c7d">#=> "I'm a multi-line\nstring.\n"</span>
<span style="color:#7a7c7d"># Strings are all encoded in UTF-8:</span>
<span style="color:#f44f4f">"héllò"</span> <span style="color:#7a7c7d">#=> "héllò"</span>
<span style="color:#7a7c7d"># Strings are really just binaries, and char lists are just lists.</span>
<span style="color:#3f8058">&lt;&lt;</span>?a, ?b, ?c<span style="color:#3f8058">>></span> <span style="color:#7a7c7d">#=> "abc"</span>
<span style="color:#27ae60">[</span>?a, ?b, ?c<span style="color:#27ae60">]</span> <span style="color:#7a7c7d">#=> 'abc'</span>
<span style="color:#7a7c7d"># `?a` in elixir returns the ASCII integer for the letter `a`</span>
?a <span style="color:#7a7c7d">#=> 97</span>
<span style="color:#7a7c7d"># To concatenate lists use `++`, for binaries use `&lt;>`</span>
<span style="color:#27ae60">[</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#27ae60">]</span> <span style="color:#3f8058">++</span> <span style="color:#27ae60">[</span><span style="color:#f67400">4</span>,<span style="color:#f67400">5</span><span style="color:#27ae60">]</span> <span style="color:#7a7c7d">#=> [1,2,3,4,5]</span>
<span style="color:#da4453">'hello '</span> <span style="color:#3f8058">++</span> <span style="color:#da4453">'world'</span> <span style="color:#7a7c7d">#=> 'hello world'</span>
<span style="color:#3f8058">&lt;&lt;</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#3f8058">>></span> <span style="color:#3f8058">&lt;></span> <span style="color:#3f8058">&lt;&lt;</span><span style="color:#f67400">4</span>,<span style="color:#f67400">5</span><span style="color:#3f8058">>></span> <span style="color:#7a7c7d">#=> &lt;&lt;1,2,3,4,5>></span>
<span style="color:#f44f4f">"hello "</span> <span style="color:#3f8058">&lt;></span> <span style="color:#f44f4f">"world"</span> <span style="color:#7a7c7d">#=> "hello world"</span>
<span style="color:#7a7c7d"># Ranges are represented as `start..end` (both inclusive)</span>
<span style="color:#f67400">1</span><span style="color:#3f8058">..</span><span style="color:#f67400">10</span> <span style="color:#7a7c7d">#=> 1..10</span>
lower<span style="color:#3f8058">..</span>upper <span style="color:#3f8058">=</span> <span style="color:#f67400">1</span><span style="color:#3f8058">..</span><span style="color:#f67400">10</span> <span style="color:#7a7c7d"># Can use pattern matching on ranges as well</span>
<span style="color:#27ae60">[</span>lower, upper<span style="color:#27ae60">]</span> <span style="color:#7a7c7d">#=> [1, 10]</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d">## -- Operators</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d"># Some math</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">+</span> <span style="color:#f67400">1</span> <span style="color:#7a7c7d">#=> 2</span>
<span style="color:#f67400">10</span> <span style="color:#3f8058">-</span> <span style="color:#f67400">5</span> <span style="color:#7a7c7d">#=> 5</span>
<span style="color:#f67400">5</span> <span style="color:#3f8058">*</span> <span style="color:#f67400">2</span> <span style="color:#7a7c7d">#=> 10</span>
<span style="color:#f67400">10</span> <span style="color:#3f8058">/</span> <span style="color:#f67400">2</span> <span style="color:#7a7c7d">#=> 5.0</span>
<span style="color:#7a7c7d"># In elixir the operator `/` always returns a float.</span>
<span style="color:#7a7c7d"># To do integer division use `div`</span>
div<span style="color:#8e44ad">(</span><span style="color:#f67400">10</span>, <span style="color:#f67400">2</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 5</span>
<span style="color:#7a7c7d"># To get the division remainder use `rem`</span>
rem<span style="color:#8e44ad">(</span><span style="color:#f67400">10</span>, <span style="color:#f67400">3</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 1</span>
<span style="color:#7a7c7d"># There are also boolean operators: `or`, `and` and `not`.</span>
<span style="color:#7a7c7d"># These operators expect a boolean as their first argument.</span>
<span style="color:#27aeae;font-weight:bold">true</span> <span style="font-weight:bold">and</span> <span style="color:#27aeae;font-weight:bold">true</span> <span style="color:#7a7c7d">#=> true</span>
<span style="color:#27aeae;font-weight:bold">false</span> <span style="font-weight:bold">or</span> <span style="color:#27aeae;font-weight:bold">true</span> <span style="color:#7a7c7d">#=> true</span>
<span style="color:#7a7c7d"># 1 and true #=> ** (ArgumentError) argument error</span>
<span style="color:#7a7c7d"># Elixir also provides `||`, `&amp;&amp;` and `!` which accept arguments of any type.</span>
<span style="color:#7a7c7d"># All values except `false` and `nil` will evaluate to true.</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">||</span> <span style="color:#27aeae;font-weight:bold">true</span> <span style="color:#7a7c7d">#=> 1</span>
<span style="color:#27aeae;font-weight:bold">false</span> <span style="color:#3f8058">&amp;&amp;</span> <span style="color:#f67400">1</span> <span style="color:#7a7c7d">#=> false</span>
<span style="color:#27aeae;font-weight:bold">nil</span> <span style="color:#3f8058">&amp;&amp;</span> <span style="color:#f67400">20</span> <span style="color:#7a7c7d">#=> nil</span>
!true <span style="color:#7a7c7d">#=> false</span>
<span style="color:#7a7c7d"># For comparisons we have: `==`, `!=`, `===`, `!==`, `&lt;=`, `>=`, `&lt;` and `>`</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">==</span> <span style="color:#f67400">1</span> <span style="color:#7a7c7d">#=> true</span>
<span style="color:#f67400">1</span><span style="color:#3f8058"> !=</span> <span style="color:#f67400">1</span> <span style="color:#7a7c7d">#=> false</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">&lt;</span> <span style="color:#f67400">2</span> <span style="color:#7a7c7d">#=> true</span>
<span style="color:#7a7c7d"># `===` and `!==` are more strict when comparing integers and floats:</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">==</span> <span style="color:#f67400">1.0</span> <span style="color:#7a7c7d">#=> true</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">===</span> <span style="color:#f67400">1.0</span> <span style="color:#7a7c7d">#=> false</span>
<span style="color:#7a7c7d"># We can also compare two different data types:</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">&lt;</span> <span style="color:#27aeae">:hello</span> <span style="color:#7a7c7d">#=> true</span>
<span style="color:#7a7c7d"># The overall sorting order is defined below:</span>
<span style="color:#7a7c7d"># number &lt; atom &lt; reference &lt; functions &lt; port &lt; pid &lt; tuple &lt; list &lt; bit string</span>
<span style="color:#7a7c7d"># To quote Joe Armstrong on this: "The actual order is not important,</span>
<span style="color:#7a7c7d"># but that a total ordering is well defined is important."</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d">## -- Control Flow</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d"># `if` expression</span>
<span style="color:#fdbc4b;font-weight:bold">if</span> <span style="color:#27aeae;font-weight:bold">false</span> <span style="font-weight:bold">do</span>
<span style="color:#f44f4f">"This will never be seen"</span>
<span style="color:#fdbc4b;font-weight:bold">else</span>
<span style="color:#f44f4f">"This will"</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d"># There's also `unless`</span>
<span style="color:#fdbc4b;font-weight:bold">unless</span> <span style="color:#27aeae;font-weight:bold">true</span> <span style="font-weight:bold">do</span>
<span style="color:#f44f4f">"This will never be seen"</span>
<span style="color:#fdbc4b;font-weight:bold">else</span>
<span style="color:#f44f4f">"This will"</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d"># Remember pattern matching? Many control-flow structures in elixir rely on it.</span>
<span style="color:#7a7c7d"># `case` allows us to compare a value against many patterns:</span>
<span style="font-weight:bold">case</span> <span style="color:#8e44ad">{</span><span style="color:#27aeae">:one</span>, <span style="color:#27aeae">:two</span><span style="color:#8e44ad">}</span> <span style="font-weight:bold">do</span>
<span style="color:#8e44ad">{</span><span style="color:#27aeae">:four</span>, <span style="color:#27aeae">:five</span><span style="color:#8e44ad">}</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"This won't match"</span>
<span style="color:#8e44ad">{</span><span style="color:#27aeae">:one</span>, x<span style="color:#8e44ad">}</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"This will match and bind `x` to `:two`"</span>
_ <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"This will match any value"</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d"># It's common to bind the value to `_` if we don't need it.</span>
<span style="color:#7a7c7d"># For example, if only the head of a list matters to us:</span>
<span style="color:#27ae60">[</span>head <span style="color:#3f8058">|</span> _<span style="color:#27ae60">]</span> <span style="color:#3f8058">=</span> <span style="color:#27ae60">[</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#27ae60">]</span>
head <span style="color:#7a7c7d">#=> 1</span>
<span style="color:#7a7c7d"># For better readability we can do the following:</span>
<span style="color:#27ae60">[</span>head <span style="color:#3f8058">|</span> _tail<span style="color:#27ae60">]</span> <span style="color:#3f8058">=</span> <span style="color:#27ae60">[</span><span style="color:#27aeae">:a</span>, <span style="color:#27aeae">:b</span>, <span style="color:#27aeae">:c</span><span style="color:#27ae60">]</span>
head <span style="color:#7a7c7d">#=> :a</span>
<span style="color:#7a7c7d"># `cond` lets us check for many conditions at the same time.</span>
<span style="color:#7a7c7d"># Use `cond` instead of nesting many `if` expressions.</span>
<span style="color:#fdbc4b;font-weight:bold">cond</span> <span style="font-weight:bold">do</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">+</span> <span style="color:#f67400">1</span> <span style="color:#3f8058">==</span> <span style="color:#f67400">3</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"I will never be seen"</span>
<span style="color:#f67400">2</span> <span style="color:#3f8058">*</span> <span style="color:#f67400">5</span> <span style="color:#3f8058">==</span> <span style="color:#f67400">12</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"Me neither"</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">+</span> <span style="color:#f67400">2</span> <span style="color:#3f8058">==</span> <span style="color:#f67400">3</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"But I will"</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d"># It is common to set the last condition equal to `true`, which will always match.</span>
<span style="color:#fdbc4b;font-weight:bold">cond</span> <span style="font-weight:bold">do</span>
<span style="color:#f67400">1</span> <span style="color:#3f8058">+</span> <span style="color:#f67400">1</span> <span style="color:#3f8058">==</span> <span style="color:#f67400">3</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"I will never be seen"</span>
<span style="color:#f67400">2</span> <span style="color:#3f8058">*</span> <span style="color:#f67400">5</span> <span style="color:#3f8058">==</span> <span style="color:#f67400">12</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"Me neither"</span>
<span style="color:#27aeae;font-weight:bold">true</span> <span style="color:#3f8058">-></span>
<span style="color:#f44f4f">"But I will (this is essentially an else)"</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d"># `try/catch` is used to catch values that are thrown, it also supports an</span>
<span style="color:#7a7c7d"># `after` clause that is invoked whether or not a value is caught.</span>
<span style="color:#fdbc4b;font-weight:bold">try</span> <span style="font-weight:bold">do</span>
<span style="color:#fdbc4b;font-weight:bold">throw</span><span style="color:#8e44ad">(</span><span style="color:#27aeae">:hello</span><span style="color:#8e44ad">)</span>
<span style="color:#fdbc4b;font-weight:bold">catch</span>
message <span style="color:#3f8058">-></span> <span style="color:#f44f4f">"Got </span><span style="color:#27ae60">#{</span>message<span style="color:#27ae60">}</span><span style="color:#f44f4f">."</span>
<span style="font-weight:bold">after</span>
<span style="color:#27aeae;font-weight:bold">IO</span><span style="color:#3f8058">.</span>puts<span style="color:#8e44ad">(</span><span style="color:#f44f4f">"I'm the after clause."</span><span style="color:#8e44ad">)</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d">#=> I'm the after clause</span>
<span style="color:#7a7c7d"># "Got :hello"</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d">## -- Modules and Functions</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d"># Anonymous functions (notice the dot)</span>
square <span style="color:#3f8058">=</span> <span style="font-weight:bold">fn</span><span style="color:#8e44ad">(</span>x<span style="color:#8e44ad">)</span> <span style="color:#3f8058">-></span> x <span style="color:#3f8058">*</span> x <span style="font-weight:bold">end</span>
square<span style="color:#3f8058">.</span><span style="color:#8e44ad">(</span><span style="color:#f67400">5</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 25</span>
<span style="color:#7a7c7d"># They also accept many clauses and guards.</span>
<span style="color:#7a7c7d"># Guards let you fine tune pattern matching,</span>
<span style="color:#7a7c7d"># they are indicated by the `when` keyword:</span>
f <span style="color:#3f8058">=</span> <span style="font-weight:bold">fn</span>
x, y <span style="font-weight:bold">when</span> x <span style="color:#3f8058">></span> <span style="color:#f67400">0</span> <span style="color:#3f8058">-></span> x <span style="color:#3f8058">+</span> y
x, y <span style="color:#3f8058">-></span> x <span style="color:#3f8058">*</span> y
<span style="font-weight:bold">end</span>
f<span style="color:#3f8058">.</span><span style="color:#8e44ad">(</span><span style="color:#f67400">1</span>, <span style="color:#f67400">3</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 4</span>
f<span style="color:#3f8058">.</span><span style="color:#8e44ad">(</span><span style="color:#3f8058">-</span><span style="color:#f67400">1</span>, <span style="color:#f67400">3</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> -3</span>
<span style="color:#7a7c7d"># Elixir also provides many built-in functions.</span>
<span style="color:#7a7c7d"># These are available in the current scope.</span>
is_number<span style="color:#8e44ad">(</span><span style="color:#f67400">10</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> true</span>
is_list<span style="color:#8e44ad">(</span><span style="color:#f44f4f">"hello"</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> false</span>
elem<span style="color:#8e44ad">({</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#8e44ad">}</span>, <span style="color:#f67400">0</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 1</span>
<span style="color:#7a7c7d"># You can group several functions into a module. Inside a module use `def`</span>
<span style="color:#7a7c7d"># to define your functions.</span>
<span style="font-weight:bold">defmodule</span> <span style="color:#27aeae;font-weight:bold">Math</span> <span style="font-weight:bold">do</span>
<span style="font-weight:bold">def</span> sum<span style="color:#8e44ad">(</span>a, b<span style="color:#8e44ad">)</span> <span style="font-weight:bold">do</span>
a <span style="color:#3f8058">+</span> b
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">def</span> square<span style="color:#8e44ad">(</span>x<span style="color:#8e44ad">)</span> <span style="font-weight:bold">do</span>
x <span style="color:#3f8058">*</span> x
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">end</span>
<span style="color:#27aeae;font-weight:bold">Math</span><span style="color:#3f8058">.</span>sum<span style="color:#8e44ad">(</span><span style="color:#f67400">1</span>, <span style="color:#f67400">2</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 3</span>
<span style="color:#27aeae;font-weight:bold">Math</span><span style="color:#3f8058">.</span>square<span style="color:#8e44ad">(</span><span style="color:#f67400">3</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 9</span>
<span style="color:#7a7c7d"># To compile our simple Math module save it as `math.ex` and use `elixirc`</span>
<span style="color:#7a7c7d"># in your terminal: elixirc math.ex</span>
<span style="color:#7a7c7d"># Inside a module we can define functions with `def` and private functions with `defp`.</span>
<span style="color:#7a7c7d"># A function defined with `def` is available to be invoked from other modules,</span>
<span style="color:#7a7c7d"># a private function can only be invoked locally.</span>
<span style="font-weight:bold">defmodule</span> <span style="color:#27aeae;font-weight:bold">PrivateMath</span> <span style="font-weight:bold">do</span>
<span style="font-weight:bold">def</span> sum<span style="color:#8e44ad">(</span>a, b<span style="color:#8e44ad">)</span> <span style="font-weight:bold">do</span>
do_sum<span style="color:#8e44ad">(</span>a, b<span style="color:#8e44ad">)</span>
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">defp</span> do_sum<span style="color:#8e44ad">(</span>a, b<span style="color:#8e44ad">)</span> <span style="font-weight:bold">do</span>
a <span style="color:#3f8058">+</span> b
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">end</span>
<span style="color:#27aeae;font-weight:bold">PrivateMath</span><span style="color:#3f8058">.</span>sum<span style="color:#8e44ad">(</span><span style="color:#f67400">1</span>, <span style="color:#f67400">2</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 3</span>
<span style="color:#7a7c7d"># PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)</span>
<span style="color:#7a7c7d"># Function declarations also support guards and multiple clauses:</span>
<span style="font-weight:bold">defmodule</span> <span style="color:#27aeae;font-weight:bold">Geometry</span> <span style="font-weight:bold">do</span>
<span style="font-weight:bold">def</span> area<span style="color:#8e44ad">({</span><span style="color:#27aeae">:rectangle</span>, w, h<span style="color:#8e44ad">})</span> <span style="font-weight:bold">do</span>
w <span style="color:#3f8058">*</span> h
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">def</span> area<span style="color:#8e44ad">({</span><span style="color:#27aeae">:circle</span>, r<span style="color:#8e44ad">})</span> <span style="font-weight:bold">when</span> is_number<span style="color:#8e44ad">(</span>r<span style="color:#8e44ad">)</span> <span style="font-weight:bold">do</span>
<span style="color:#f67400">3.14</span> <span style="color:#3f8058">*</span> r <span style="color:#3f8058">*</span> r
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">end</span>
<span style="color:#27aeae;font-weight:bold">Geometry</span><span style="color:#3f8058">.</span>area<span style="color:#8e44ad">({</span><span style="color:#27aeae">:rectangle</span>, <span style="color:#f67400">2</span>, <span style="color:#f67400">3</span><span style="color:#8e44ad">})</span> <span style="color:#7a7c7d">#=> 6</span>
<span style="color:#27aeae;font-weight:bold">Geometry</span><span style="color:#3f8058">.</span>area<span style="color:#8e44ad">({</span><span style="color:#27aeae">:circle</span>, <span style="color:#f67400">3</span><span style="color:#8e44ad">})</span> <span style="color:#7a7c7d">#=> 28.25999999999999801048</span>
<span style="color:#7a7c7d"># Geometry.area({:circle, "not_a_number"})</span>
<span style="color:#7a7c7d">#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1</span>
<span style="color:#7a7c7d"># Due to immutability, recursion is a big part of elixir</span>
<span style="font-weight:bold">defmodule</span> <span style="color:#27aeae;font-weight:bold">Recursion</span> <span style="font-weight:bold">do</span>
<span style="font-weight:bold">def</span> sum_list<span style="color:#8e44ad">(</span><span style="color:#27ae60">[</span>head <span style="color:#3f8058">|</span> tail<span style="color:#27ae60">]</span>, acc<span style="color:#8e44ad">)</span> <span style="font-weight:bold">do</span>
sum_list<span style="color:#8e44ad">(</span>tail, acc <span style="color:#3f8058">+</span> head<span style="color:#8e44ad">)</span>
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">def</span> sum_list<span style="color:#8e44ad">(</span><span style="color:#27ae60">[]</span>, acc<span style="color:#8e44ad">)</span> <span style="font-weight:bold">do</span>
acc
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">end</span>
<span style="color:#27aeae;font-weight:bold">Recursion</span><span style="color:#3f8058">.</span>sum_list<span style="color:#8e44ad">(</span><span style="color:#27ae60">[</span><span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span><span style="color:#27ae60">]</span>, <span style="color:#f67400">0</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 6</span>
<span style="color:#7a7c7d"># Elixir modules support attributes, there are built-in attributes and you</span>
<span style="color:#7a7c7d"># may also add custom ones.</span>
<span style="font-weight:bold">defmodule</span> <span style="color:#27aeae;font-weight:bold">MyMod</span> <span style="font-weight:bold">do</span>
<span style="color:#27ae60">@moduledoc """</span>
<span style="color:#7a7c7d"> This is a built-in attribute on a example module.</span>
<span style="color:#7a7c7d"> </span><span style="color:#27ae60">"""</span>
<span style="color:#27ae60">@my_data</span> <span style="color:#f67400">100</span> <span style="color:#7a7c7d"># This is a custom attribute.</span>
<span style="color:#27aeae;font-weight:bold">IO</span><span style="color:#3f8058">.</span>inspect<span style="color:#8e44ad">(</span><span style="color:#27ae60">@my_data</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> 100</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d">## -- Structs and Exceptions</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d"># Structs are extensions on top of maps that bring default values,</span>
<span style="color:#7a7c7d"># compile-time guarantees and polymorphism into Elixir.</span>
<span style="font-weight:bold">defmodule</span> <span style="color:#27aeae;font-weight:bold">Person</span> <span style="font-weight:bold">do</span>
<span style="font-weight:bold">defstruct</span> <span style="color:#27aeae">name:</span> <span style="color:#27aeae;font-weight:bold">nil</span>, <span style="color:#27aeae">age:</span> <span style="color:#f67400">0</span>, <span style="color:#27aeae">height:</span> <span style="color:#f67400">0</span>
<span style="font-weight:bold">end</span>
joe_info <span style="color:#3f8058">=</span> %<span style="color:#27aeae;font-weight:bold">Person</span><span style="color:#8e44ad">{</span> <span style="color:#27aeae">name:</span> <span style="color:#f44f4f">"Joe"</span>, <span style="color:#27aeae">age:</span> <span style="color:#f67400">30</span>, <span style="color:#27aeae">height:</span> <span style="color:#f67400">180</span> <span style="color:#8e44ad">}</span>
<span style="color:#7a7c7d">#=> %Person{age: 30, height: 180, name: "Joe"}</span>
<span style="color:#7a7c7d"># Access the value of name</span>
joe_info<span style="color:#3f8058">.</span>name <span style="color:#7a7c7d">#=> "Joe"</span>
<span style="color:#7a7c7d"># Update the value of age</span>
older_joe_info <span style="color:#3f8058">=</span> %<span style="color:#8e44ad">{</span> joe_info <span style="color:#3f8058">|</span> <span style="color:#27aeae">age:</span> <span style="color:#f67400">31</span> <span style="color:#8e44ad">}</span>
<span style="color:#7a7c7d">#=> %Person{age: 31, height: 180, name: "Joe"}</span>
<span style="color:#7a7c7d"># The `try` block with the `rescue` keyword is used to handle exceptions</span>
<span style="color:#fdbc4b;font-weight:bold">try</span> <span style="font-weight:bold">do</span>
<span style="color:#fdbc4b;font-weight:bold">raise</span> <span style="color:#f44f4f">"some error"</span>
<span style="color:#fdbc4b;font-weight:bold">rescue</span>
<span style="color:#27aeae;font-weight:bold">RuntimeError</span> <span style="color:#3f8058">-></span> <span style="color:#f44f4f">"rescued a runtime error"</span>
_error <span style="color:#3f8058">-></span> <span style="color:#f44f4f">"this will rescue any error"</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d">#=> "rescued a runtime error"</span>
<span style="color:#7a7c7d"># All exceptions have a message</span>
<span style="color:#fdbc4b;font-weight:bold">try</span> <span style="font-weight:bold">do</span>
<span style="color:#fdbc4b;font-weight:bold">raise</span> <span style="color:#f44f4f">"some error"</span>
<span style="color:#fdbc4b;font-weight:bold">rescue</span>
x <span style="font-weight:bold">in</span> <span style="color:#27ae60">[</span><span style="color:#27aeae;font-weight:bold">RuntimeError</span><span style="color:#27ae60">]</span> <span style="color:#3f8058">-></span>
x<span style="color:#3f8058">.</span>message
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d">#=> "some error"</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d">## -- Concurrency</span>
<span style="color:#7a7c7d">## ---------------------------</span>
<span style="color:#7a7c7d"># Elixir relies on the actor model for concurrency. All we need to write</span>
<span style="color:#7a7c7d"># concurrent programs in elixir are three primitives: spawning processes,</span>
<span style="color:#7a7c7d"># sending messages and receiving messages.</span>
<span style="color:#7a7c7d"># To start a new process we use the `spawn` function, which takes a function</span>
<span style="color:#7a7c7d"># as argument.</span>
f <span style="color:#3f8058">=</span> <span style="font-weight:bold">fn</span> <span style="color:#3f8058">-></span> <span style="color:#f67400">2</span> <span style="color:#3f8058">*</span> <span style="color:#f67400">2</span> <span style="font-weight:bold">end</span> <span style="color:#7a7c7d">#=> #Function&lt;erl_eval.20.80484245></span>
spawn<span style="color:#8e44ad">(</span>f<span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> #PID&lt;0.40.0></span>
<span style="color:#7a7c7d"># `spawn` returns a pid (process identifier), you can use this pid to send</span>
<span style="color:#7a7c7d"># messages to the process. To do message passing we use the `send` operator.</span>
<span style="color:#7a7c7d"># For all of this to be useful we need to be able to receive messages. This is</span>
<span style="color:#7a7c7d"># achieved with the `receive` mechanism:</span>
<span style="color:#7a7c7d"># The `receive do` block is used to listen for messages and process</span>
<span style="color:#7a7c7d"># them when they are received. A `receive do` block will only</span>
<span style="color:#7a7c7d"># process one received message. In order to process multiple</span>
<span style="color:#7a7c7d"># messages, a function with a `receive do` block must recursively</span>
<span style="color:#7a7c7d"># call itself to get into the `receive do` block again.</span>
<span style="font-weight:bold">defmodule</span> <span style="color:#27aeae;font-weight:bold">Geometry</span> <span style="font-weight:bold">do</span>
<span style="font-weight:bold">def</span> area_loop <span style="font-weight:bold">do</span>
<span style="font-weight:bold">receive</span> <span style="font-weight:bold">do</span>
<span style="color:#8e44ad">{</span><span style="color:#27aeae">:rectangle</span>, w, h<span style="color:#8e44ad">}</span> <span style="color:#3f8058">-></span>
<span style="color:#27aeae;font-weight:bold">IO</span><span style="color:#3f8058">.</span>puts<span style="color:#8e44ad">(</span><span style="color:#f44f4f">"Area = </span><span style="color:#27ae60">#{</span>w <span style="color:#3f8058">*</span> h<span style="color:#27ae60">}</span><span style="color:#f44f4f">"</span><span style="color:#8e44ad">)</span>
area_loop<span style="color:#8e44ad">()</span>
<span style="color:#8e44ad">{</span><span style="color:#27aeae">:circle</span>, r<span style="color:#8e44ad">}</span> <span style="color:#3f8058">-></span>
<span style="color:#27aeae;font-weight:bold">IO</span><span style="color:#3f8058">.</span>puts<span style="color:#8e44ad">(</span><span style="color:#f44f4f">"Area = </span><span style="color:#27ae60">#{</span><span style="color:#f67400">3.14</span> <span style="color:#3f8058">*</span> r <span style="color:#3f8058">*</span> r<span style="color:#27ae60">}</span><span style="color:#f44f4f">"</span><span style="color:#8e44ad">)</span>
area_loop<span style="color:#8e44ad">()</span>
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">end</span>
<span style="font-weight:bold">end</span>
<span style="color:#7a7c7d"># Compile the module and create a process that evaluates `area_loop` in the shell</span>
pid <span style="color:#3f8058">=</span> spawn<span style="color:#8e44ad">(</span><span style="font-weight:bold">fn</span> <span style="color:#3f8058">-></span> <span style="color:#27aeae;font-weight:bold">Geometry</span><span style="color:#3f8058">.</span>area_loop<span style="color:#8e44ad">()</span> <span style="font-weight:bold">end</span><span style="color:#8e44ad">)</span> <span style="color:#7a7c7d">#=> #PID&lt;0.40.0></span>
<span style="color:#7a7c7d"># Alternatively</span>
pid <span style="color:#3f8058">=</span> spawn<span style="color:#8e44ad">(</span><span style="color:#27aeae;font-weight:bold">Geometry</span>, <span style="color:#27aeae">:area_loop</span>, <span style="color:#27ae60">[]</span><span style="color:#8e44ad">)</span>
<span style="color:#7a7c7d"># Send a message to `pid` that will match a pattern in the receive statement</span>
send pid, <span style="color:#8e44ad">{</span><span style="color:#27aeae">:rectangle</span>, <span style="color:#f67400">2</span>, <span style="color:#f67400">3</span><span style="color:#8e44ad">}</span>
<span style="color:#7a7c7d">#=> Area = 6</span>
<span style="color:#7a7c7d"># {:rectangle,2,3}</span>
send pid, <span style="color:#8e44ad">{</span><span style="color:#27aeae">:circle</span>, <span style="color:#f67400">2</span><span style="color:#8e44ad">}</span>
<span style="color:#7a7c7d">#=> Area = 12.56000000000000049738</span>
<span style="color:#7a7c7d"># {:circle,2}</span>
<span style="color:#7a7c7d"># The shell is also a process, you can use `self` to get the current pid</span>
self<span style="color:#8e44ad">()</span> <span style="color:#7a7c7d">#=> #PID&lt;0.27.0></span>
<span style="color:#7a7c7d"># Code not found in the original, but needed to test the full range of the syntax</span>
<span style="font-weight:bold">def</span> function, <span style="color:#27aeae">do:</span> <span style="color:#8e44ad">{</span><span style="color:#27aeae">:ok</span>, result<span style="color:#8e44ad">}</span>
<span style="color:#27ae60">[</span>
<span style="color:#27aeae">:a</span>,
<span style="color:#27aeae">:b</span>,
<span style="color:#27aeae">:c</span>
<span style="color:#27ae60">]</span>
%<span style="color:#8e44ad">{</span>
<span style="color:#27aeae">a:</span> <span style="color:#f44f4f">"a"</span>,
<span style="color:#27aeae">b:</span> <span style="color:#f44f4f">"b"</span>,
<span style="color:#27aeae">c:</span> <span style="color:#f44f4f">"c"</span>
<span style="color:#8e44ad">}</span>
%A<span style="color:#8e44ad">{</span>
<span style="color:#27aeae">a:</span> <span style="color:#f44f4f">"a"</span>,
<span style="color:#27aeae">b:</span> <span style="color:#f44f4f">"b"</span>,
<span style="color:#27aeae">c:</span> <span style="color:#f44f4f">"c"</span>
<span style="color:#8e44ad">}</span>
</pre></body></html>