An Elixir Parts Catalog - Introducing Elixir: Getting Started in Functional Programming (2014)

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.