File: learnelixir.exs.dark.html

package info (click to toggle)
kf6-syntax-highlighting 6.13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 47,568 kB
  • sloc: xml: 197,750; cpp: 12,850; python: 3,023; sh: 955; perl: 546; ruby: 488; pascal: 393; javascript: 161; php: 150; jsp: 132; lisp: 131; haskell: 124; ada: 119; ansic: 107; makefile: 96; f90: 94; ml: 85; cobol: 81; yacc: 71; csh: 62; erlang: 54; sql: 51; java: 47; objc: 37; awk: 31; asm: 30; tcl: 29; fortran: 18; cs: 10
file content (492 lines) | stat: -rw-r--r-- 37,617 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
<!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:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span>} <span style="color:#7a7c7d"># tuple</span>

<span style="color:#7a7c7d"># We can access a tuple element with the `elem` function:</span>
<span style="color:#8e44ad">elem</span>({<span style="color:#f67400">1</span>, <span style="color:#f67400">2</span>, <span style="color:#f67400">3</span>}, <span style="color:#f67400">0</span>) <span style="color:#7a7c7d">#=> 1</span>

<span style="color:#7a7c7d"># Lists that are implemented as linked lists.</span>
[<span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span>] <span style="color:#7a7c7d"># list</span>

<span style="color:#7a7c7d"># We can access the head and tail of a list as follows:</span>
[head <span style="color:#3f8058">|</span> tail] <span style="color:#3f8058">=</span> [<span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</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>
&lt;&lt;<span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</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>
&lt;&lt;<span style="color:#3daee9">?a</span>, <span style="color:#3daee9">?b</span>, <span style="color:#3daee9">?c</span>>> <span style="color:#7a7c7d">#=> "abc"</span>
[<span style="color:#3daee9">?a</span>, <span style="color:#3daee9">?b</span>, <span style="color:#3daee9">?c</span>]   <span style="color:#7a7c7d">#=> 'abc'</span>

<span style="color:#7a7c7d"># `?a` in elixir returns the ASCII integer for the letter `a`</span>
<span style="color:#3daee9">?a</span> <span style="color:#7a7c7d">#=> 97</span>

<span style="color:#7a7c7d"># To concatenate lists use `++`, for binaries use `&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:#f67400">4</span>,<span style="color:#f67400">5</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>

&lt;&lt;<span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span>>> <span style="color:#3f8058">&lt;></span> &lt;&lt;<span style="color:#f67400">4</span>,<span style="color:#f67400">5</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>
[lower, upper] <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>
<span style="color:#8e44ad">div</span>(<span style="color:#f67400">10</span>, <span style="color:#f67400">2</span>) <span style="color:#7a7c7d">#=> 5</span>

<span style="color:#7a7c7d"># To get the division remainder use `rem`</span>
<span style="color:#8e44ad">rem</span>(<span style="color:#f67400">10</span>, <span style="color:#f67400">3</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">true</span> <span style="font-weight:bold">and</span> <span style="color:#27aeae">true</span> <span style="color:#7a7c7d">#=> true</span>
<span style="color:#27aeae">false</span> <span style="font-weight:bold">or</span> <span style="color:#27aeae">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">true</span>  <span style="color:#7a7c7d">#=> 1</span>
<span style="color:#27aeae">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">nil</span> <span style="color:#3f8058">&amp;&amp;</span> <span style="color:#f67400">20</span>  <span style="color:#7a7c7d">#=> nil</span>
<span style="color:#3f8058">!</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">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">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:#27aeae">:one</span>, <span style="color:#27aeae">:two</span>} <span style="font-weight:bold">do</span>
  {<span style="color:#27aeae">:four</span>, <span style="color:#27aeae">:five</span>} <span style="color:#3f8058">-></span>
    <span style="color:#f44f4f">"This won't match"</span>
  {<span style="color:#27aeae">:one</span>, x} <span style="color:#3f8058">-></span>
    <span style="color:#f44f4f">"This will match and bind `x` to `:two`"</span>
  <span style="color:#7a7c7d">_</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>
[head <span style="color:#3f8058">|</span> <span style="color:#7a7c7d">_</span>] <span style="color:#3f8058">=</span> [<span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span>]
head <span style="color:#7a7c7d">#=> 1</span>

<span style="color:#7a7c7d"># For better readability we can do the following:</span>
[head <span style="color:#3f8058">|</span> <span style="color:#7a7c7d">_tail</span>] <span style="color:#3f8058">=</span> [<span style="color:#27aeae">:a</span>, <span style="color:#27aeae">:b</span>, <span style="color:#27aeae">:c</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">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:#27aeae">:hello</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:#8e44ad">#{</span>message<span style="color:#8e44ad">}</span><span style="color:#f44f4f">."</span>
<span style="font-weight:bold">after</span>
  IO.<span style="color:#8e44ad">puts</span>(<span style="color:#f44f4f">"I'm the after clause."</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="color:#8e44ad">fn</span>(x) <span style="color:#3f8058">-></span> x <span style="color:#3f8058">*</span> x <span style="font-weight:bold">end</span>
square.(<span style="color:#f67400">5</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:#f67400">1</span>, <span style="color:#f67400">3</span>)  <span style="color:#7a7c7d">#=> 4</span>
f.(<span style="color:#3f8058">-</span><span style="color:#f67400">1</span>, <span style="color:#f67400">3</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>
<span style="color:#8e44ad">is_number</span>(<span style="color:#f67400">10</span>)    <span style="color:#7a7c7d">#=> true</span>
<span style="color:#8e44ad">is_list</span>(<span style="color:#f44f4f">"hello"</span>) <span style="color:#7a7c7d">#=> false</span>
<span style="color:#8e44ad">elem</span>({<span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span>}, <span style="color:#f67400">0</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> Math <span style="font-weight:bold">do</span>
  <span style="font-weight:bold">def</span> <span style="color:#8e44ad">sum</span>(a, b) <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> <span style="color:#8e44ad">square</span>(x) <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>

Math.<span style="color:#8e44ad">sum</span>(<span style="color:#f67400">1</span>, <span style="color:#f67400">2</span>)  <span style="color:#7a7c7d">#=> 3</span>
Math.<span style="color:#8e44ad">square</span>(<span style="color:#f67400">3</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> PrivateMath <span style="font-weight:bold">do</span>
  <span style="font-weight:bold">def</span> <span style="color:#8e44ad">sum</span>(a, b) <span style="font-weight:bold">do</span>
    <span style="color:#8e44ad">do_sum</span>(a, b)
  <span style="font-weight:bold">end</span>

  <span style="font-weight:bold">defp</span> <span style="color:#8e44ad">do_sum</span>(a, b) <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>

PrivateMath.<span style="color:#8e44ad">sum</span>(<span style="color:#f67400">1</span>, <span style="color:#f67400">2</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> Geometry <span style="font-weight:bold">do</span>
  <span style="font-weight:bold">def</span> <span style="color:#8e44ad">area</span>({<span style="color:#27aeae">:rectangle</span>, w, h}) <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> <span style="color:#8e44ad">area</span>({<span style="color:#27aeae">:circle</span>, r}) <span style="font-weight:bold">when</span> <span style="color:#8e44ad">is_number</span>(r) <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>

Geometry.<span style="color:#8e44ad">area</span>({<span style="color:#27aeae">:rectangle</span>, <span style="color:#f67400">2</span>, <span style="color:#f67400">3</span>}) <span style="color:#7a7c7d">#=> 6</span>
Geometry.<span style="color:#8e44ad">area</span>({<span style="color:#27aeae">:circle</span>, <span style="color:#f67400">3</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> Recursion <span style="font-weight:bold">do</span>
  <span style="font-weight:bold">def</span> <span style="color:#8e44ad">sum_list</span>([head <span style="color:#3f8058">|</span> tail], acc) <span style="font-weight:bold">do</span>
    <span style="color:#8e44ad">sum_list</span>(tail, acc <span style="color:#3f8058">+</span> head)
  <span style="font-weight:bold">end</span>

  <span style="font-weight:bold">def</span> <span style="color:#8e44ad">sum_list</span>([], acc) <span style="font-weight:bold">do</span>
    acc
  <span style="font-weight:bold">end</span>
<span style="font-weight:bold">end</span>

Recursion.<span style="color:#8e44ad">sum_list</span>([<span style="color:#f67400">1</span>,<span style="color:#f67400">2</span>,<span style="color:#f67400">3</span>], <span style="color:#f67400">0</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> MyMod <span style="font-weight:bold">do</span>
  <span style="color:#a43340">@moduledoc """</span>
<span style="color:#a43340">  This is a built-in attribute on a example module.</span>
<span style="color:#a43340">  """</span>

  @my_data <span style="color:#f67400">100</span> <span style="color:#7a7c7d"># This is a custom attribute.</span>
  IO.<span style="color:#8e44ad">inspect</span>(@my_data) <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> Person <span style="font-weight:bold">do</span>
  <span style="font-weight:bold">defstruct</span> <span style="color:#27aeae">name:</span> <span style="color:#27aeae">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> %Person{ <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:#7a7c7d">#=> %Person{age: 30, height: 180, name: "Joe"}</span>

<span style="color:#7a7c7d"># Access the value of name</span>
joe_info.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> %{ joe_info <span style="color:#3f8058">|</span> <span style="color:#27aeae">age:</span> <span style="color:#f67400">31</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>
  RuntimeError <span style="color:#3f8058">-></span> <span style="color:#f44f4f">"rescued a runtime error"</span>
  <span style="color:#7a7c7d">_error</span> <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> [RuntimeError] <span style="color:#3f8058">-></span>
    x.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>
<span style="color:#8e44ad">spawn</span>(f) <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> Geometry <span style="font-weight:bold">do</span>
  <span style="font-weight:bold">def</span> <span style="color:#8e44ad">area_loop</span> <span style="font-weight:bold">do</span>
    <span style="font-weight:bold">receive</span> <span style="font-weight:bold">do</span>
      {<span style="color:#27aeae">:rectangle</span>, w, h} <span style="color:#3f8058">-></span>
        IO.<span style="color:#8e44ad">puts</span>(<span style="color:#f44f4f">"Area = </span><span style="color:#8e44ad">#{</span>w <span style="color:#3f8058">*</span> h<span style="color:#8e44ad">}</span><span style="color:#f44f4f">"</span>)
        <span style="color:#8e44ad">area_loop</span>()
      {<span style="color:#27aeae">:circle</span>, r} <span style="color:#3f8058">-></span>
        IO.<span style="color:#8e44ad">puts</span>(<span style="color:#f44f4f">"Area = </span><span style="color:#8e44ad">#{</span><span style="color:#f67400">3.14</span> <span style="color:#3f8058">*</span> r <span style="color:#3f8058">*</span> r<span style="color:#8e44ad">}</span><span style="color:#f44f4f">"</span>)
        <span style="color:#8e44ad">area_loop</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> <span style="color:#8e44ad">spawn</span>(<span style="font-weight:bold">fn</span> <span style="color:#3f8058">-></span> Geometry.<span style="color:#8e44ad">area_loop</span>() <span style="font-weight:bold">end</span>) <span style="color:#7a7c7d">#=> #PID&lt;0.40.0></span>
<span style="color:#7a7c7d"># Alternatively</span>
pid <span style="color:#3f8058">=</span> <span style="color:#8e44ad">spawn</span>(Geometry, <span style="color:#27aeae">:area_loop</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:#27aeae">:rectangle</span>, <span style="color:#f67400">2</span>, <span style="color:#f67400">3</span>}
<span style="color:#7a7c7d">#=> Area = 6</span>
<span style="color:#7a7c7d">#   {:rectangle,2,3}</span>

send pid, {<span style="color:#27aeae">:circle</span>, <span style="color:#f67400">2</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>
<span style="color:#8e44ad">self</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> <span style="color:#8e44ad">function</span>, <span style="color:#27aeae">do:</span> {<span style="color:#27aeae">:ok</span>, result}

[
  <span style="color:#27aeae">:a</span>,
  <span style="color:#27aeae">:b</span>,
  <span style="color:#27aeae">:c</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>
}

%A{
  <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:#7a7c7d"># Numerics</span>
<span style="color:#f67400">0xBE_EF</span>
<span style="color:#f67400">0o777_1</span>
<span style="color:#f67400">0b1010_0101_01</span>
<span style="color:#f67400">01234</span>
<span style="color:#f67400">1234_5678_9</span>

<span style="color:#f67400">3.14_159</span>
<span style="color:#f67400">1_23.00_00</span>
<span style="color:#f67400">4.13e20</span>
<span style="color:#f67400">6.12e-8</span>


<span style="color:#f44f4f">"String Interpolation: </span><span style="color:#8e44ad">#{</span><span style="color:#8e44ad">inspect</span>(<span style="color:#27aeae">nil</span>)<span style="color:#8e44ad">}</span><span style="color:#f44f4f">"</span>

<span style="color:#7a7c7d"># Sigils</span>
<span style="color:#f44f4f">~r/</span><span style="color:#3daee9">\b</span><span style="color:#f44f4f">foo_bar</span><span style="color:#3daee9">\b</span><span style="color:#f44f4f">/g</span>
<span style="color:#f44f4f">~s"asdf"</span>
<span style="color:#f44f4f">~w[foo bar one two three]a</span>
<span style="color:#f44f4f">~w(foo bar one two three)a</span>

<span style="color:#f44f4f">~c'char lists are typed like this now'</span>

<span style="color:#7a7c7d"># Documentation</span>
<span style="color:#a43340">@doc """</span>
<span style="color:#a43340;font-weight:bold;text-decoration:underline">## Documentation</span>
<span style="color:#a43340">lorem ipsum dolor</span>

<span style="color:#a43340;font-weight:bold">* </span><span style="color:#a43340">a</span>
<span style="color:#a43340;font-weight:bold">* </span><span style="color:#a43340">b</span>
<span style="color:#a43340;font-weight:bold">* </span><span style="color:#a43340">c</span>

<span style="color:#a43340;font-weight:bold">1. </span><span style="color:#a43340">x</span>
<span style="color:#a43340;font-weight:bold">2. </span><span style="color:#a43340">y</span>
<span style="color:#a43340;font-weight:bold">3. </span><span style="color:#a43340">z</span>
<span style="color:#a43340">"""</span>

<span style="color:#7a7c7d"># Module Attributes</span>
@<span style="color:#7f8c8d">compile</span> {<span style="color:#27aeae">:inline</span>, <span style="color:#27aeae">foo:</span> <span style="color:#f67400">1</span>}
@custom_attribute [<span style="color:#f67400">1</span>, <span style="color:#f67400">2</span>, <span style="color:#f67400">3</span>, <span style="color:#f67400">4</span>]

<span style="color:#7a7c7d"># More Atoms</span>
<span style="color:#27aeae">:"@foo"</span>
<span style="color:#27aeae">:bar?</span>
<span style="color:#27aeae">:bar!</span>
%{
  <span style="color:#27aeae">foo?:</span> <span style="color:#27aeae">false</span>,
  <span style="color:#27aeae">"@bar":</span> <span style="color:#f67400">1</span>
}
<span style="color:#27aeae">:+</span>
<span style="color:#27aeae">:**</span>
<span style="color:#27aeae">:++</span>
<span style="color:#27aeae">:%{}</span>

<span style="color:#7a7c7d"># Interpolation in Atoms</span>
<span style="color:#27aeae">:"bar</span><span style="color:#8e44ad">#{</span><span style="color:#8e44ad">inspect</span>(<span style="color:#8e44ad">foo</span>())<span style="color:#8e44ad">}</span><span style="color:#27aeae">"</span>

<span style="color:#7a7c7d"># Character Literals</span>
[<span style="color:#3daee9">?a</span>, <span style="color:#3daee9">?b</span>, <span style="color:#3daee9">?c</span>, <span style="color:#3daee9">?z</span>, <span style="color:#3daee9">?1</span>, <span style="color:#3daee9">?-</span>, <span style="color:#3daee9">?+</span>, <span style="color:#3daee9">?.</span>, <span style="color:#3daee9">?\s</span>, <span style="color:#3daee9">?\n</span>]

<span style="color:#7a7c7d"># Special Forms</span>
<span style="font-weight:bold">def</span> <span style="color:#8e44ad">foo</span>(<span style="color:#7a7c7d">_</span>, <span style="color:#7a7c7d">_opts</span>) <span style="font-weight:bold">do</span>
  IO.<span style="color:#8e44ad">inspect</span>(<span style="color:#7f8c8d">__MODULE__</span>)
  %<span style="color:#7f8c8d">__MODULE__</span>{}
<span style="font-weight:bold">end</span>
</pre></body></html>