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
Copy file name to clipboardExpand all lines: lib/elixir/pages/getting-started/alias-require-and-import.md
+1-78Lines changed: 1 addition & 78 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -156,83 +156,6 @@ end
156
156
157
157
Since `use` allows any code to run, we can't really know the side-effects of using a module without reading its documentation. Therefore use this function with care and only if strictly required. Don't use `use` where an `import` or `alias` would do.
158
158
159
-
## Understanding Aliases
160
-
161
-
At this point, you may be wondering: what exactly is an Elixir alias and how is it represented?
162
-
163
-
An alias in Elixir is a capitalized identifier (like `String`, `Keyword`, etc) which is converted to an atom during compilation. For instance, the `String` alias translates by default to the atom `:"Elixir.String"`:
164
-
165
-
```elixir
166
-
iex>is_atom(String)
167
-
true
168
-
iex>to_string(String)
169
-
"Elixir.String"
170
-
iex>:"Elixir.String"==String
171
-
true
172
-
```
173
-
174
-
By using the `alias/2` directive, we are changing the atom the alias expands to.
175
-
176
-
Aliases expand to atoms because in the Erlang Virtual Machine (and consequently Elixir) modules are always represented by atoms:
177
-
178
-
```elixir
179
-
iex>List.flatten([1, [2], 3])
180
-
[1, 2, 3]
181
-
iex>:"Elixir.List".flatten([1, [2], 3])
182
-
[1, 2, 3]
183
-
```
184
-
185
-
That's the mechanism we use to call Erlang modules:
186
-
187
-
```elixir
188
-
iex>:lists.flatten([1, [2], 3])
189
-
[1, 2, 3]
190
-
```
191
-
192
-
## Module nesting
193
-
194
-
Now that we have talked about aliases, we can talk about nesting and how it works in Elixir. Consider the following example:
195
-
196
-
```elixir
197
-
defmoduleFoodo
198
-
defmoduleBardo
199
-
end
200
-
end
201
-
```
202
-
203
-
The example above will define two modules: `Foo` and `Foo.Bar`. The second can be accessed as `Bar` inside `Foo` as long as they are in the same lexical scope.
204
-
205
-
If, later, the `Bar` module is moved outside the `Foo` module definition, it must be referenced by its full name (`Foo.Bar`) or an alias must be set using the `alias` directive discussed above.
206
-
207
-
**Note**: in Elixir, you don't have to define the `Foo` module before being able to define the `Foo.Bar` module, as they are effectively independent. The above could also be written as:
208
-
209
-
```elixir
210
-
defmoduleFoo.Bardo
211
-
end
212
-
213
-
defmoduleFoodo
214
-
aliasFoo.Bar
215
-
# Can still access it as `Bar`
216
-
end
217
-
```
218
-
219
-
Aliasing a nested module does not bring parent modules into scope. Consider the following example:
220
-
221
-
```elixir
222
-
defmoduleFoodo
223
-
defmoduleBardo
224
-
defmoduleBazdo
225
-
end
226
-
end
227
-
end
228
-
229
-
aliasFoo.Bar.Baz
230
-
# The module `Foo.Bar.Baz` is now available as `Baz`
231
-
# However, the module `Foo.Bar` is *not* available as `Bar`
232
-
```
233
-
234
-
As we will see in later chapters, aliases also play a crucial role in macros, to guarantee they are hygienic.
235
-
236
159
## Multi alias/import/require/use
237
160
238
161
It is possible to `alias`, `import`, `require`, or `use` multiple modules at once. This is particularly useful once we start nesting modules, which is very common when building Elixir applications. For example, imagine you have an application where all modules are nested under `MyApp`, you can alias the modules `MyApp.Foo`, `MyApp.Bar` and `MyApp.Baz` at once as follows:
@@ -241,4 +164,4 @@ It is possible to `alias`, `import`, `require`, or `use` multiple modules at onc
241
164
aliasMyApp.{Foo, Bar, Baz}
242
165
```
243
166
244
-
With this, we have finished our tour of Elixir modules. The next topic to cover is module attributes.
167
+
With this, we have finished our tour of Elixir modules.
Copy file name to clipboardExpand all lines: lib/elixir/pages/getting-started/anonymous-functions.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ Anonymous functions allow us to store and pass executable code around as if it w
9
9
10
10
## Identifying functions and documentation
11
11
12
-
Before we move on to discuss anonymous functions, let's talk about how Elixir identifies named functions.
12
+
Before we move on to discuss anonymous functions, let's talk about how Elixir identifies named functions – the functions defined in [modules](modules-and-functions.md).
13
13
14
14
Functions in Elixir are identified by both their name and their arity. The arity of a function describes the number of arguments that the function takes. From this point on we will use both the function name and its arity to describe functions throughout the documentation. `trunc/1` identifies the function which is named `trunc` and takes `1` argument, whereas `trunc/2` identifies a different (nonexistent) function with the same name but with an arity of `2`.
Copy file name to clipboardExpand all lines: lib/elixir/pages/getting-started/case-cond-and-if.md
+14-7Lines changed: 14 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -100,7 +100,11 @@ iex> if nil do
100
100
"This will"
101
101
```
102
102
103
-
This is also a good opportunity to talk about variable scoping in Elixir. If any variable is declared or changed inside [`if`](`if/2`), [`case`](`case/2`), and similar constructs, the declaration and change will only be visible inside the construct. For example:
103
+
### Expressions
104
+
105
+
Some programming languages make a distinction about expressions (code that returns a value) and statements (code that returns no value). In Elixir, there are only expressions, no statements. Everything you write in Elixir language returns some value.
106
+
107
+
This property allows variables to be scoped to individual blocks of code such as [`if`](`if/2`), [`case`](`case/2`), where declarations or changes are only visible inside the block. A change can't leak to outer blocks, which makes code easier to follow and understand. For example:
104
108
105
109
```elixir
106
110
iex> x =1
@@ -113,19 +117,22 @@ iex> x
113
117
1
114
118
```
115
119
116
-
In said cases, if you want to change a value, you must return the value from the [`if`](`if/2`):
120
+
You see the return value of the [`if`](`if/2`) expression as the resulting `2` here. To retain changes made within the [`if`](`if/2`) expression on the outer block you need to assign the returned value to a variable in the outer block.
117
121
118
122
```elixir
119
123
iex> x =1
120
124
1
121
-
iex> x =iftruedo
122
-
...> x +1
123
-
...>else
124
-
...> x
125
-
...>end
125
+
iex> x =
126
+
...>iftruedo
127
+
...> x +1
128
+
...>else
129
+
...> x
130
+
...>end
126
131
2
127
132
```
128
133
134
+
With all expressions returning a value there's also no need for alternative constructs, such as ternary operators posing as an alternative to [`if`](`if/2`). Elixir does include an inline notation for [`if`](`if/2`) and, as we will [learn later](keywords-and-maps.md#do-blocks-and-keywords), it is a syntactic variation on `if`'s arguments.
135
+
129
136
> #### `if` is a macro {: .info}
130
137
>
131
138
> An interesting note regarding [`if`](`if/2`) is that it is implemented as a macro in the language: it isn't a special language construct as it would be in many languages. You can check the documentation and its source for more information.
Copy file name to clipboardExpand all lines: lib/elixir/pages/getting-started/keywords-and-maps.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -131,7 +131,7 @@ iex> if true do
131
131
In the example above, the `do` and `else` blocks make up a keyword list. They are nothing more than a syntax convenience on top of keyword lists. We can rewrite the above to:
132
132
133
133
```elixir
134
-
iex>iftrue, do:"This will be seen", else:"This won't"
134
+
iex>if(true, do:"This will be seen", else:"This won't")
135
135
"This will be seen"
136
136
```
137
137
@@ -225,6 +225,8 @@ These operations have one large benefit in that they raise if the key does not e
225
225
226
226
Elixir developers typically prefer to use the `map.key` syntax and pattern matching instead of the functions in the `Map` module when working with maps because they lead to an assertive style of programming. [This blog post by José Valim](https://dashbit.co/blog/writing-assertive-code-with-elixir) provides insight and examples on how you get more concise and faster software by writing assertive code in Elixir.
227
227
228
+
In a further chapter you'll learn about ["Structs"](structs.md), which further enforce the idea of a map with predefined keys.
229
+
228
230
## Nested data structures
229
231
230
232
Often we will have maps inside maps, or even keywords lists inside maps, and so forth. Elixir provides conveniences for manipulating nested data structures via the `get_in/1`, `put_in/2`, `update_in/2`, and other macros giving the same conveniences you would find in imperative languages while keeping the immutable properties of the language.
Copy file name to clipboardExpand all lines: lib/elixir/pages/getting-started/modules-and-functions.md
+76-2Lines changed: 76 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ iex> String.length("hello")
12
12
5
13
13
```
14
14
15
-
In order to create our own modules in Elixir, we use the [`defmodule`](`defmodule/2`) macro. The first letter of the module must be in uppercase. We use the [`def`](`def/2`) macro to define functions in that module. The first letter of every function must be in lowercase (or underscore):
15
+
In order to create our own modules in Elixir, we use the [`defmodule`](`defmodule/2`) macro. The first letter of an module name (an alias, as described further down) must be in uppercase. We use the [`def`](`def/2`) macro to define functions in that module. The first letter of every function must be in lowercase (or underscore):
When a variable is not used by a function or a clause, we add a leading underscore (`_`) to its name to signal this intent. This rule is also covered in our [Naming Conventions](../references/naming-conventions.md#underscore-_foo) document.
169
169
170
-
This finishes our short introduction to modules. In the next chapters, we will learn how to use function definitions for recursion and later on explore more functionality related to modules.
170
+
## Understanding Aliases
171
+
172
+
An alias in Elixir is a capitalized identifier (like `String`, `Keyword`, etc) which is converted to an atom during compilation. For instance, the `String` alias translates by default to the atom `:"Elixir.String"`:
173
+
174
+
```elixir
175
+
iex>is_atom(String)
176
+
true
177
+
iex>to_string(String)
178
+
"Elixir.String"
179
+
iex>:"Elixir.String"==String
180
+
true
181
+
```
182
+
183
+
By using the `alias/2` directive, we are changing the atom the alias expands to.
184
+
185
+
Aliases expand to atoms because in the Erlang Virtual Machine (and consequently Elixir) modules are always represented by atoms. By namespacing
186
+
those atoms elixir modules avoid conflicting with existing erlang modules.
187
+
188
+
```elixir
189
+
iex>List.flatten([1, [2], 3])
190
+
[1, 2, 3]
191
+
iex>:"Elixir.List".flatten([1, [2], 3])
192
+
[1, 2, 3]
193
+
```
194
+
195
+
That's the mechanism we use to call Erlang modules:
196
+
197
+
```elixir
198
+
iex>:lists.flatten([1, [2], 3])
199
+
[1, 2, 3]
200
+
```
201
+
202
+
## Module nesting
203
+
204
+
Now that we have talked about aliases, we can talk about nesting and how it works in Elixir. Consider the following example:
205
+
206
+
```elixir
207
+
defmoduleFoodo
208
+
defmoduleBardo
209
+
end
210
+
end
211
+
```
212
+
213
+
The example above will define two modules: `Foo` and `Foo.Bar`. The second can be accessed as `Bar` inside `Foo` as long as they are in the same lexical scope.
214
+
215
+
If, later, the `Bar` module is moved outside the `Foo` module definition, it must be referenced by its full name (`Foo.Bar`) or an alias must be set using the `alias` directive discussed above.
216
+
217
+
**Note**: in Elixir, you don't have to define the `Foo` module before being able to define the `Foo.Bar` module, as they are effectively independent. The above could also be written as:
218
+
219
+
```elixir
220
+
defmoduleFoo.Bardo
221
+
end
222
+
223
+
defmoduleFoodo
224
+
aliasFoo.Bar
225
+
# Can still access it as `Bar`
226
+
end
227
+
```
228
+
229
+
Aliasing a nested module does not bring parent modules into scope. Consider the following example:
230
+
231
+
```elixir
232
+
defmoduleFoodo
233
+
defmoduleBardo
234
+
defmoduleBazdo
235
+
end
236
+
end
237
+
end
238
+
239
+
aliasFoo.Bar.Baz
240
+
# The module `Foo.Bar.Baz` is now available as `Baz`
241
+
# However, the module `Foo.Bar` is *not* available as `Bar`
242
+
```
243
+
244
+
As we will see in later chapters, aliases also play a crucial role in macros, to guarantee they are hygienic.
Copy file name to clipboardExpand all lines: lib/elixir/pages/getting-started/pattern-matching.md
+32-32Lines changed: 32 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -113,6 +113,38 @@ iex> [0 | list]
113
113
[0, 1, 2, 3]
114
114
```
115
115
116
+
In some cases, you don't care about a particular value in a pattern. It is a common practice to bind those values to the underscore, `_`. For example, if only the head of the list matters to us, we can assign the tail to underscore:
117
+
118
+
```elixir
119
+
iex> [head |_] = [1, 2, 3]
120
+
[1, 2, 3]
121
+
iex> head
122
+
1
123
+
```
124
+
125
+
The variable `_` is special in that it can never be read from. Trying to read from it gives a compile error:
126
+
127
+
```elixir
128
+
iex>_
129
+
** (CompileError) iex:1: invalid use of _. "_" represents a value to be ignored in a pattern and cannot be used in expressions
130
+
```
131
+
132
+
If a variable is mentioned more than once in a pattern, all references must bind to the same value:
133
+
134
+
```elixir
135
+
iex> {x, x} = {1, 1}
136
+
{1, 1}
137
+
iex> {x, x} = {1, 2}
138
+
** (MatchError) no match of right hand side value: {1, 2}
139
+
```
140
+
141
+
Although pattern matching allows us to build powerful constructs, its usage is limited. For instance, you cannot make function calls on the left side of a match. The following example is invalid:
142
+
143
+
```elixir
144
+
iex>length([1, [2], 3]) =3
145
+
** (CompileError) iex:1: cannot invoke remote function :erlang.length/1 inside match
146
+
```
147
+
116
148
Pattern matching allows developers to easily destructure data types such as tuples and lists. As we will see in the following chapters, it is one of the foundations of recursion in Elixir and applies to other types as well, like maps and binaries.
117
149
118
150
## The pin operator
@@ -168,36 +200,4 @@ iex> {y, 1} = {2, 2}
168
200
** (MatchError) no match of right hand side value: {2, 2}
169
201
```
170
202
171
-
If a variable is mentioned more than once in a pattern, all references must bind to the same value:
172
-
173
-
```elixir
174
-
iex> {x, x} = {1, 1}
175
-
{1, 1}
176
-
iex> {x, x} = {1, 2}
177
-
** (MatchError) no match of right hand side value: {1, 2}
178
-
```
179
-
180
-
In some cases, you don't care about a particular value in a pattern. It is a common practice to bind those values to the underscore, `_`. For example, if only the head of the list matters to us, we can assign the tail to underscore:
181
-
182
-
```elixir
183
-
iex> [head |_] = [1, 2, 3]
184
-
[1, 2, 3]
185
-
iex> head
186
-
1
187
-
```
188
-
189
-
The variable `_` is special in that it can never be read from. Trying to read from it gives a compile error:
190
-
191
-
```elixir
192
-
iex>_
193
-
** (CompileError) iex:1: invalid use of _. "_" represents a value to be ignored in a pattern and cannot be used in expressions
194
-
```
195
-
196
-
Although pattern matching allows us to build powerful constructs, its usage is limited. For instance, you cannot make function calls on the left side of a match. The following example is invalid:
197
-
198
-
```elixir
199
-
iex>length([1, [2], 3]) =3
200
-
** (CompileError) iex:1: cannot invoke remote function :erlang.length/1 inside match
201
-
```
202
-
203
203
This finishes our introduction to pattern matching. As we will see in the next chapter, pattern matching is very common in many language constructs and they can be further augmented with guards.
Copy file name to clipboardExpand all lines: lib/elixir/pages/references/patterns-and-guards.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -83,6 +83,19 @@ iex> _
83
83
** (CompileError) iex:3: invalid use of _
84
84
```
85
85
86
+
A pinned value represents the value itself and not its – even if syntatically equal – pattern. The right hand side is compared to be equal to the pinned value:
87
+
88
+
```iex
89
+
iex> x = %{}
90
+
%{}
91
+
iex> {:ok, %{}} = {:ok, %{a: 13}}
92
+
{:ok, %{a: 13}}
93
+
iex> {:ok, ^x} = {:ok, %{a: 13}}
94
+
** (MatchError) no match of right hand side value: {:ok, %{a: 13}}
95
+
(stdlib 6.2) erl_eval.erl:667: :erl_eval.expr/6
96
+
iex:2: (file)
97
+
```
98
+
86
99
### Literals (numbers and atoms)
87
100
88
101
Atoms and numbers (integers and floats) can appear in patterns and they are always represented as is. For example, an atom will only match an atom if they are the same atom:
0 commit comments