You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In order to facilitate software reuse, Elixir provides three directives. As we are going to see below, they are called directives because they have **lexical scope**.
12
12
13
-
## alias
13
+
## `alias`
14
14
15
15
`alias` allows you to set up aliases for any given module name. Imagine our `Math` module uses a special list implementation for doing math specific operations:
16
16
@@ -59,7 +59,7 @@ end
59
59
60
60
In the example above, since we are invoking `alias` inside the function `plus/2`, the alias will just be valid inside the function `plus/2`. `minus/2` won't be affected at all.
61
61
62
-
## require
62
+
## `require`
63
63
64
64
Elixir provides macros as a mechanism for meta-programming (writing code that generates code).
65
65
@@ -78,7 +78,7 @@ In Elixir, `Integer.is_odd/1` is defined as a macro so that it can be used as a
78
78
79
79
In general a module does not need to be required before usage, except if we want to use the macros available in that module. An attempt to call a macro that was not loaded will raise an error. Note that like the `alias` directive, `require` is also lexically scoped. We will talk more about macros in a later chapter.
80
80
81
-
## import
81
+
## `import`
82
82
83
83
We use `import` whenever we want to easily access functions or macros from other modules without using the fully-qualified name. For instance, if we want to use the `duplicate/2` function from the `List` module several times, we can simply import it:
In this chapter, we will learn about the `case`, `cond` and `if` control-flow structures.
12
12
13
-
## case
13
+
## `case`
14
14
15
15
`case` allows us to compare a value against many patterns until we find a matching one:
16
16
@@ -133,7 +133,7 @@ iex> f.(-1, 3)
133
133
134
134
The number of arguments in each anonymous function clause needs to be the same, otherwise an error is raised.
135
135
136
-
## cond
136
+
## `cond`
137
137
138
138
`case` is useful when you need to match against different values. However, in many circumstances, we want to check different conditions and find the first one that evaluates to true. In such cases, one may use `cond`:
139
139
@@ -174,7 +174,7 @@ iex> cond do
174
174
"1 is considered as true"
175
175
```
176
176
177
-
## if and unless
177
+
## `if` and `unless`
178
178
179
179
Besides `case` and `cond`, Elixir also provides the macros `if/2` and `unless/2` which are useful when you need to check for just one condition:
180
180
@@ -204,16 +204,16 @@ iex> if nil do
204
204
205
205
> Note: An interesting note regarding `if/2` and `unless/2` is that they are implemented as macros in the language; they aren't special language constructs as they would be in many languages. You can check the documentation and the source of `if/2` in [the `Kernel` module docs](/docs/stable/elixir/Kernel.html). The `Kernel` module is also where operators like `+/2` and functions like `is_function/2` are defined, all automatically imported and available in your code by default.
206
206
207
-
## `do`/`end` blocks
207
+
## `do/end` blocks
208
208
209
-
At this point, we have learned four control structures: `case`, `cond`, `if` and `unless`, and they were all wrapped in `do`/`end` blocks. It happens we could also write `if` as follows:
209
+
At this point, we have learned four control structures: `case`, `cond`, `if` and `unless`, and they were all wrapped in `do/end` blocks. It happens we could also write `if` as follows:
210
210
211
211
```iex
212
212
iex> if true, do: 1 + 2
213
213
3
214
214
```
215
215
216
-
In Elixir, `do`/`end` blocks are a convenience for passing a group of expressions to `do:`. These are equivalent:
216
+
In Elixir, `do/end` blocks are a convenience for passing a group of expressions to `do:`. These are equivalent:
Copy file name to clipboardExpand all lines: getting-started/io-and-the-file-system.markdown
+1-1
Original file line number
Diff line number
Diff line change
@@ -84,7 +84,7 @@ as, in case of an error, `File.read/1` will return `{:error, reason}` and the pa
84
84
85
85
If you don't want to handle a possible error (i.e., you want it to bubble up), prefer using `File.read!/1`.
86
86
87
-
## The Path module
87
+
## The `Path` module
88
88
89
89
The majority of the functions in the `File` module expect paths as arguments. Most commonly, those paths will be regular binaries. The [`Path`](/docs/stable/elixir/Path.html) module provides facilities for working with such paths:
Copy file name to clipboardExpand all lines: getting-started/mix-otp/agent.markdown
+3-3
Original file line number
Diff line number
Diff line change
@@ -139,7 +139,7 @@ end
139
139
140
140
You can read more about ExUnit cases in the [`ExUnit.Case` module documentation](/docs/stable/ex_unit/ExUnit.Case.html) and more about callbacks in [`ExUnit.Callbacks` docs](/docs/stable/ex_unit/ExUnit.Callbacks.html).
141
141
142
-
## Other Agent actions
142
+
## Other agent actions
143
143
144
144
Besides getting a value and updating the agent state, agents allow us to get a value and update the agent state in one function call via `Agent.get_and_update/2`. Let's implement a `KV.Bucket.delete/2` function that deletes a key from the bucket, returning its current value:
145
145
@@ -154,9 +154,9 @@ def delete(bucket, key) do
154
154
end
155
155
```
156
156
157
-
Now it is your turn to write a test for the functionality above! Also, be sure to explore the documentation for Agents to learn more about them.
157
+
Now it is your turn to write a test for the functionality above! Also, be sure to explore the documentation for agents to learn more about them.
158
158
159
-
## Client/Server in Agents
159
+
## Client/Server in agents
160
160
161
161
Before we move on to the next chapter, let's discuss the client/server dichotomy in agents. Let's expand the `delete/2` function we have just implemented:
Copy file name to clipboardExpand all lines: getting-started/mix-otp/genserver.markdown
+1-1
Original file line number
Diff line number
Diff line change
@@ -245,7 +245,7 @@ Observe that we were able to considerably change the server implementation witho
245
245
246
246
Finally, different from the other callbacks, we have defined a "catch-all" clause for `handle_info/2` that discards any unknown message. To understand why, let's move on to the next section.
247
247
248
-
## call, cast or info?
248
+
## `call`, `cast` or `info`?
249
249
250
250
So far we have used three callbacks: `handle_call/3`, `handle_cast/2` and `handle_info/2`. Deciding when to use each is straightforward:
Copy file name to clipboardExpand all lines: getting-started/mix-otp/supervisor-and-application.markdown
+1-1
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ When things fail, your first reaction may be: "let's rescue those errors". But,
14
14
15
15
In this chapter, we are going to learn about supervisors and also about applications. We are going to create not one, but two supervisors, and use them to supervise our processes.
16
16
17
-
## Our first Supervisor
17
+
## Our first supervisor
18
18
19
19
Creating a supervisor is not much different from creating a GenServer. We are going to define a module named `KV.Supervisor`, which will use the [Supervisor](/docs/stable/elixir/Supervisor.html) behaviour, inside the `lib/kv/supervisor.ex` file:
Copy file name to clipboardExpand all lines: getting-started/processes.markdown
+2-2
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ Elixir's processes should not be confused with operating system processes. Proce
14
14
15
15
In this chapter, we will learn about the basic constructs for spawning new processes, as well as sending and receiving messages between different processes.
16
16
17
-
## spawn
17
+
## `spawn`
18
18
19
19
The basic mechanism for spawning new processes is with the auto-imported `spawn/1` function:
20
20
@@ -47,7 +47,7 @@ true
47
47
48
48
Processes get much more interesting when we are able to send and receive messages.
49
49
50
-
## send and receive
50
+
## `send` and `receive`
51
51
52
52
We can send messages to a process with `send/2` and receive them with `receive/1`:
Copy file name to clipboardExpand all lines: getting-started/protocols.markdown
+2-2
Original file line number
Diff line number
Diff line change
@@ -116,9 +116,9 @@ end
116
116
117
117
If desired, you could come up with your own semantics for a user being blank. Not only that, you could use structs to build more robust data types, like queues, and implement all relevant protocols, such as `Enumerable` and possibly `Blank`, for this data type.
118
118
119
-
In many cases though, developers may want to provide a default implementation for structs, as explicitly implementing the protocol for all structs can be tedious. That's when falling back to Any comes in handy.
119
+
In many cases though, developers may want to provide a default implementation for structs, as explicitly implementing the protocol for all structs can be tedious. That's when falling back to `Any` comes in handy.
120
120
121
-
## Falling back to Any
121
+
## Falling back to `Any`
122
122
123
123
It may be convenient to provide a default implementation for all types. This can be achieved by setting `@fallback_to_any` to `true` in the protocol definition:
Copy file name to clipboardExpand all lines: getting-started/recursion.markdown
+4-4
Original file line number
Diff line number
Diff line change
@@ -49,9 +49,9 @@ The second definition matches the pattern and has no guard so it will be execute
49
49
Our `msg` is printed and `print_multiple_times/2` is called again this time with the second argument set to `1`.
50
50
Because `n` is now set to `1`, the guard in our first definition of `print_multiple_times/2` evaluates to true, and we execute this particular definition. The `msg` is printed, and there is nothing left to execute.
51
51
52
-
We defined `print_multiple_times/2` so that no matter what number is passed as the second argument it either triggers our first definition (known as a "base case") or it triggers our second definition which will ensure that we get exactly one step closer to our base case.
52
+
We defined `print_multiple_times/2` so that no matter what number is passed as the second argument it either triggers our first definition (known as a _base case_) or it triggers our second definition which will ensure that we get exactly one step closer to our base case.
53
53
54
-
## "Reduce" and "map" algorithms
54
+
## Reduce and map algorithms
55
55
56
56
Let's now see how we can use the power of recursion to sum a list of numbers:
57
57
@@ -82,7 +82,7 @@ sum_list [], 6
82
82
83
83
When the list is empty, it will match the final clause which returns the final result of `6`.
84
84
85
-
The process of taking a list and "reducing" it down to one value is known as a "reduce" algorithm and is central to functional programming.
85
+
The process of taking a list and _reducing_ it down to one value is known as a _reduce algorithm_ and is central to functional programming.
86
86
87
87
What if we instead want to double all of the values in our list?
88
88
@@ -100,7 +100,7 @@ end
100
100
Math.double_each([1, 2, 3]) #=> [2, 4, 6]
101
101
```
102
102
103
-
Here we have used recursion to traverse a list doubling each element and returning a new list. The process of taking a list and "mapping" over it is known as a "map" algorithm.
103
+
Here we have used recursion to traverse a list doubling each element and returning a new list. The process of taking a list and _mapping_ over it is known as a _map algorithm_.
104
104
105
105
Recursion and [tail call](http://en.wikipedia.org/wiki/Tail_call) optimization are an important part of Elixir and are commonly used to create loops. However, when programming in Elixir you will rarely use recursion as above to manipulate lists.
Copy file name to clipboardExpand all lines: getting-started/where-to-go-next.markdown
+1-1
Original file line number
Diff line number
Diff line change
@@ -28,7 +28,7 @@ Remember that in case of any difficulties, you can always visit the **#elixir-la
28
28
29
29
Don't forget that you can also check the [source code of Elixir itself](https://github.com/elixir-lang/elixir), which is mostly written in Elixir (mainly the `lib` directory), or [explore Elixir's documentation](/docs.html).
0 commit comments