Introducing Elixir: Getting Started in Functional Programming (2014)
Appendix A. An Elixir Parts Catalog
Like every language, Elixir has drawers full of parts that are fun to peruse, and there are many more available through Erlang.
These are a few of the more common ones, all represented using Elixir calling conventions. If you want much much more, see the erlang documents.
Shell Commands
You can use most Elixir functions from the shell, but the commands shown in Table A-1 are ones that are exclusive to the shell.
Table A-1. Elixir shell commands
Command |
Action |
c(file) |
Compiles the specified Erlang file. |
c(file,path) |
Compiles the specified file and puts object code in the directory specified by path. |
ls() |
Lists files at the current location. |
ls(path) |
Lists files at the specified path. |
cd(Directory) |
Changes to the specified Directory. |
pwd() |
Gets the present working directory. |
clear() |
Clears the screen. |
h() |
Prints list of available helpers. |
h(item) |
Prints help for the specified item. |
l(Module) |
Loads given Module’s code, purging the current version. |
m() |
Lists all loaded modules. |
r(Module) |
Recompiles and reloads the given Module’s source file. |
v() |
Prints a list of all commands and returned values for this session. |
v(n) |
Retrieves +n+th output value from shell session. |
flush() |
Flushes all messages sent to the shell. |
Reserved Words
There are a few Elixir terms you can’t use outside of their intended context.
The Elixir compiler will wonder what you’re trying to do if you use certain keywords as function names (see a list of these words in Table A-2. It will try to treat your functions as if they were code, and you can get very strange errors. After all, you should be able to have something calledinlist, right?
Table A-2. Reserved words that require careful use
after |
and |
catch |
do |
else |
end |
false |
fn |
in |
inbits |
inlist |
nil |
not |
or |
rescue |
true |
when |
xor |
The answer is simple: use something else.
While the following aren’t reserved words, there are also a few atoms commonly used in return values. It’s probably best to use them only in the circumstances where they’re normally expected.
Table A-3. Commonly used return-value atoms
Atom |
Means |
:ok |
Normal exit to a method. (Does not mean that whatever you asked for succeeded.) |
:error |
Something went wrong. Typically accompanied by a larger explanation. |
:undefined |
A value hasn’t been assigned yet. Common in record instances. |
:reply |
A reply is included with some kind of return value. |
:noreply |
No return value is included. A response of some sort may come, however, from other communication. |
:stop |
Used in OTP to signal that a server should stop, and triggers the terminate function. |
:ignore |
Returned by OTP supervisor process that can’t start a child. |
Operators
Table A-4. Logical (Boolean) operators
Operator |
Operator |
Description |
and |
&& |
Logical and |
or |
|| |
Logical or |
not |
! |
Unary logical not |
xor |
(No equivalent) |
Logical xor |
The logical not operator has the highest precedence. and, &&, or, and || are short-circuit operators. If they don’t need to process all the possibilities in their arguments, they stop at the first one that gives them a definite answer.
Operators in the first column require their argument(s) to be Boolean. Operators in the second column will accept any expression, with any value that is not false or nil treated as true. Because of short-circuiting, the && and || operators will return whichever value “decided” the ultimate true or false value. For example, nil || 5 returns 5, and nil && 5 returns nil.
Table A-5. Term-comparison operators
Operator |
Description |
== |
Equal to |
!= |
Not equal to |
<= |
Less than or equal to |
< |
Less than |
>= |
Greater than or equal to |
> |
Greater than |
=== |
Exactly equal to |
!== |
Exactly not equal to |
You can compare elements of different types in Elixir. The relationship of types from “least” to “greatest” is:
number < atom < reference < fn < port < pid < tuple < list < bit string
Within number, you can compare integers and floats except with the more specific === and !== operators, both of which will return false when you compare numbers of different types.
You can also compare tuples even when they contain different numbers of values. Elixir will go through the tuples from left to right and evaluate on the first value that returns a clear answer.
Table A-6. Arithmetic operators
Operator |
Description |
+ |
Unary + (positive) |
- |
Unary - (negative) |
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Floating-point division |
To calculate integer division and integer remainder, use the div and rem functions. Thus, div(17, 3) yields 5, and rem(17, 3) yields 2.
Table A-7. Binary operators
Function |
Operator |
Description |
bnot |
~ |
Unary bitwise not |
band |
&&& |
Bitwise and |
bor |
||| |
Bitwise or |
bxor |
^ |
Arithmetic bitwise xor |
bsl |
<<< |
Arithmetic bitshift left |
bsr |
>>> |
Bitshift right |
If you wish to use these operators and functions, your code must use Bitwise.
Table A-8. Operator precedence, from highest to lowest
Operator |
Associativity |
Unary + - ! ^ not ~~~ |
Not associative |
=~ |> /> |
Right |
++ -- ** |
Right |
<> |
Right |
* / |
Left |
+ - |
Left |
&&& ||| |
Left |
.. |
Left |
in |
Left |
< > <= >= == === != !== |
Left |
and |
Left |
or |
Left |
&& |
Left |
|| |
Left |
<- |
Right |
= |
Right |
inlist inbits |
Left |
| |
Right |
// |
Right |
when |
Right |
:: |
Right |
, |
Left |
-> |
Right |
do |
Left |
@ |
Not associative |
The highest priority operator in an expression is evaluated first. Elixir evaluates operators with the same priority by following associative paths. (Left associative operators go left to right, and right associative operators go right to left.)
Guard Components
Elixir allows only a limited subset of functions and other features in guard expressions, going well beyond a “no side effects” rule to keep a simple subset of possibilities. The list of allowed components includes the following:
§ true
§ Other constants (regarded as false)
§ Term comparisons (Table A-5)
§ Arithmetic expressions (Table A-6 and Table A-7)
§ Boolean expressions and these logical operators: and and or
§ The following functions: hd/1, is_atom/1, is_binary/1, is_bitstring/1, is_boolean/1, is_float/1, is_function/1, is_function/2, is_integer/1, is_list/1, is_number/1, is_pid/1, is_port/1, is_record/1, is_record/2, is_reference/1,is_term/2, is_tuple/1
Common Functions
Table A-9. Mathematical functions
Function |
Use |
:math.pi/0 |
The constant pi |
:math.sin/1 |
Sine |
:math.cos/1 |
Cosine |
:math.tan/1 |
Tangent |
:math.asin/1 |
Inverse sine (arcsine) |
:math.acos/1 |
Inverse cosine (arcosine) |
:math.atan/1 |
Inverse tangent (arctangent) |
:math.atan2/2 |
Arctangent that understands quadrants |
:math.sinh/1 |
Hyperbolic sine |
:math.cosh/1 |
Hyperbolic cosine |
:math.tanh/1 |
Hyperbolic tangent |
:math.asinh/1 |
Hyperbolic arcsine |
:math.acosh/1 |
Hyperbolic arccosine |
:math.atanh/1 |
Hyperbolic arctangent |
:math.exp/1 |
Exponential function |
:math.log/1 |
Natural logarithm (base e) |
:math.log10/1 |
Logarithm (base 10) |
:math.pow/2 |
First argument to the second argument power |
:math.sqrt/1 |
Square root |
:math.erf/1 |
Error function |
:math.erfc/1 |
Complementary error function |
Arguments for all trigonometric functions are expressed in radians. To convert degrees to radians, divide by 180 and multiply by pi.
WARNING
The erf/1 and erfc/1 functions may not be implemented in Windows. The Erlang documentation also warns more broadly that “Not all functions are implemented on all platforms,” but these come directly from the C-language libraries.
Table A-10. Approachable higher-order functions for processing collections and lists
Function |
Returns |
Use |
Enum.each/2 |
ok |
Side effects specified in function |
Enum.map/2 |
New list |
Apply function to list values |
Enum.filter/2 |
Subset |
Creating list where function returns true |
Enum:all?/2 |
Boolean |
Returns true if function true for all values, otherwise false |
Enum.any?/2 |
Boolean |
Returns true if function true for any values, otherwise false |
Enum.take_while/2 |
Subset |
Collects the head of the list until the function is true |
Enum.drop_while/2 |
Subset |
Deletes the head of the list until the function is true |
List.foldl/3 |
Accumulator |
Passes function list value and accumulator, forward through list |
List.foldr/3 |
Accumulator |
Passes function list value and accumulator, backward through list |
Enum.partition/2 |
Tuple of two lists |
Split list based on function |
Chapter 8 describes these in greater detail.
Table A-11. Escape sequences for strings
Sequence |
Produces |
\" |
Double quote |
\' |
Single quote |
\\ |
Backslash |
\b |
Backspace |
\d |
Delete |
\e |
Escape |
\f |
Form feed |
\n |
Newline |
\r |
Carriage return |
\s |
Space |
\t |
Tab |
\v |
Vertical tab |
\xXY |
Character in hex |
\x{X…} |
Characters in hex, where X… is one or more hexadecimal characters |
^a…^z or ^A…\^Z |
Control-A to control-Z |
Table A-12. String sigils
Sigil |
Meaning |
%c %C |
Returns a list of characters |
%r %R |
Returns a regular expression |
%s %S |
Returns a binary string |
%w %W |
Returns a list of words |
Sigils created with lowercase letters will use escaping and interpolation as usual; those created with uppercase letters will be created exactly as written, with no escaping or interpolation.
Datatypes for Documentation and Analysis
Table A-13. Basic datatypes for @spec and ExDoc
atom() |
binary() |
float() |
fun() |
integer() |
list() |
tuple() |
union() |
node() |
number() |
String.t() |
char() |
byte() |
[] (nil) |
any() |
none() |
pid() |
port() |
reference() |
The type String.t() is used for Elixir binaries; the type string() is used for Erlang’s strings stored as a list of characters. For more, see the user manual.