Skip to content

Commit ae3a13a

Browse files
author
José Valim
committed
Build early on a distinction between named and anonymous functions
1 parent 24d3eef commit ae3a13a

File tree

4 files changed

+13
-21
lines changed

4 files changed

+13
-21
lines changed

_posts/2013-08-08-elixir-design-goals.markdown

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ defmodule Hello do
136136
end
137137
```
138138

139-
Given my previous background in Ruby, it is natural that some of the constructs added were borrowed from Ruby. However, those additions were a by-product, never a language goal.
139+
Given my previous background in Ruby, it is natural that some of the constructs added were borrowed from Ruby. However, those additions were a by-product, and not a language goal.
140140

141141
Many language constructs are also inspired by their Erlang counter-parts, like some of the control-flow macros, operators and containers. Notice how some Elixir code:
142142

crash-course.markdown

+1-8
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,6 @@ iex> ^a = 3
152152

153153
### Calling functions
154154

155-
Elixir allows you to omit parentheses in function calls, Erlang does not.
156-
157-
| Erlang | Elixir |
158-
|-------------------|----------------|
159-
| some_function(). | some_function |
160-
| sum(A, B) | sum a, b |
161-
162155
Invoking a function from a module uses different syntax. In Erlang, you would write
163156

164157
```erlang
@@ -174,7 +167,7 @@ List.last([1, 2])
174167
**Note**. Since Erlang modules are represented by atoms, you may invoke Erlang functions in Elixir as follows:
175168

176169
```elixir
177-
:lists.sort [3, 2, 1]
170+
:lists.sort([3, 2, 1])
178171
```
179172

180173
All of the Erlang built-ins reside in the `:erlang` module.

getting-started/basic-types.markdown

+9-12
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ iex> rem 10, 3
4444
1
4545
```
4646

47-
Notice that parentheses are not required in order to invoke a function.
47+
Notice Elixir allows you to drop the parentheses when invoking named functions. Such feature gives a cleaner syntax when writing declarations and control-flow constructs.
4848

4949
Elixir also supports shortcut notations for entering binary, octal, and hexadecimal numbers:
5050

@@ -94,7 +94,6 @@ false
9494

9595
Elixir provides a bunch of predicate functions to check for a value type. For example, the `is_boolean/1` function can be used to check if a value is a boolean or not:
9696

97-
9897
```iex
9998
iex> is_boolean(true)
10099
true
@@ -104,7 +103,7 @@ false
104103

105104
You can also use `is_integer/1`, `is_float/1` or `is_number/1` to check, respectively, if an argument is an integer, a float, or either.
106105

107-
> Note: At any moment you can type `h` in the shell to print information on how to use the shell. The `h` helper can also be used to access documentation for any function. For example, typing `h is_integer/1` is going to print the documentation for the `is_integer/1` function. It also works with operators and other constructs (try `h ==/2`).
106+
> Note: At any moment you can type `h()` in the shell to print information on how to use the shell. The `h` helper can also be used to access documentation for any function. For example, typing `h is_integer/1` is going to print the documentation for the `is_integer/1` function. It also works with operators and other constructs (try `h ==/2`).
108107
109108
## Atoms
110109

@@ -197,24 +196,24 @@ iex> String.upcase("hellö")
197196

198197
## Anonymous functions
199198

200-
Functions are delimited by the keywords `fn` and `end`:
199+
Anonymous functions can be created inline and are delimited by the keywords `fn` and `end`:
201200

202201
```iex
203202
iex> add = fn a, b -> a + b end
204203
#Function<12.71889879/2 in :erl_eval.expr/5>
204+
iex> add.(1, 2)
205+
3
205206
iex> is_function(add)
206207
true
207-
iex> is_function(add, 2)
208+
iex> is_function(add, 2) # check if it expects exactly 2 arguments
208209
true
209-
iex> is_function(add, 1)
210+
iex> is_function(add, 1) # check if it expects exactly 1 argument
210211
false
211-
iex> add.(1, 2)
212-
3
213212
```
214213

215-
Functions are "first class citizens" in Elixir meaning they can be passed as arguments to other functions as integers and strings can. In the example, we have passed the function in the variable `add` to the `is_function/1` function which correctly returned `true`. We can also check the arity of the function by calling `is_function/2`.
214+
Functions are "first class citizens" in Elixir meaning they can be passed as arguments to other functions in the same way as integers and strings. In the example, we have passed the function in the variable `add` to the `is_function/1` function which correctly returned `true`. We can also check the arity of the function by calling `is_function/2`.
216215

217-
Note a dot (`.`) between the variable and parenthesis is required to invoke an anonymous function.
216+
Note a dot (`.`) between the variable and parentheses is required to invoke an anonymous function. The dot ensures there is no ambiguity between calling an anonymous function named `add` and a named function `add/2`. In this sense, Elixir makes a clear distinction between anonymous functions and named functions. We will explore those differences in [Chapter 8](/getting-started/modules.html).
218217

219218
Anonymous functions are closures and as such they can access variables that are in scope when the function is defined. Let's define a new anonymous function that uses the `add` anonymous function we have previously defined:
220219

@@ -236,8 +235,6 @@ iex> x
236235
42
237236
```
238237

239-
The capture syntax [`&()`](https://hexdocs.pm/elixir/Kernel.SpecialForms.html) can also be used for creating anonymous functions. This type of syntax will be discussed in [Chapter 8](/getting-started/modules.html).
240-
241238
## (Linked) Lists
242239

243240
Elixir uses square brackets to specify a list of values. Values can be of any type:

getting-started/modules.markdown

+2
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ iex> fun.(0)
156156
true
157157
```
158158

159+
Remember Elixir makes a distinction between anonymous functions and named functions, where the former must be invoked with a dot (`.`) between the variable name and parentheses. The capture operator bridges this gap by allowing named functions to be assigned to variables and passed as arguments in the same way we assign, invoke and pass anonymous functions.
160+
159161
Local or imported functions, like `is_function/1`, can be captured without the module:
160162

161163
```iex

0 commit comments

Comments
 (0)