The value types in Elixir represent numbers, names, ranges, and regular expressions.
Integer literals can be written as decimal (1234), hexadecimal (0xcafe), octal (0o765), and binary (0b1010).
Decimal numbers may contain underscores—these are often used to separate groups of three digits when writing large numbers, so one million could be written 1_000_000 (or perhaps 100_0000 in China and Japan).
There is no fixed limit on the size of integers—their internal representation grows to fit their magnitude.
| factorial(10000) # => 28462596809170545189...and so on for 35640 more digits... |
(You’ll see how to write a function such as factorial in Modules and Named Functions,.)
Floating-point numbers are written using a decimal point. There must be at least one digit before and after the decimal point. An optional trailing exponent may be given. These are all valid floating-point literals:
| 1.0 0.2456 0.314159e1 314159.0e-5 |
Floats are IEEE 754 double precision, giving them about 16 digits of accuracy and a maximum exponent of around 10308.
Atoms are constants that represent something’s name. We write them using a leading colon (:), which can be followed by an atom word or an Elixir operator. An atom word is a sequence of UTF-8 letters (including combining marks), digits, underscores, and at signs (@). It may end with an exclamation point or a question mark. You can also create atoms containing arbitrary characters by enclosing the characters following the colon in double quotes. These are all atoms:
| :fred :is_binary? :var@2 :<> :=== :"func/3" |
| :"long john silver" :эликсир :mötley_crüe |
An atom’s name is its value. Two atoms with the same name will always compare as being equal, even if they were created by different applications on two computers separated by an ocean.
We’ll be using atoms a lot to tag values.
Ranges are represented as start..end, where start and end are integers.
Elixir has regular-expression literals, written as ~r{regexp} or ~r{regexp}opts. Here I show the delimiters for regular-expression literals as { and }, but they are considerably more flexible. You can choose any nonalphanumeric characters as delimiters, as described in the discussion of sigils. Some people use ~r/…/ for nostalgic reasons, but this is less convenient than the bracketed forms, as any forward slashes inside the pattern must be escaped.
Elixir regular expression support is provided by PCRE,[4] which basically provides a Perl 5–compatible syntax for patterns.
You can specify one or more single-character options following a regexp literal. These modify the literal’s match behavior or add functionality.
Opt | Meaning |
---|---|
f | Force the pattern to start to match on the first line of a multiline string. |
i | Make matches case insensitive. |
m |
If the string to be matched contains multiple lines, ^ and $ match the start and end of these lines. \A and \z continue to match the beginning or end of the string. |
s |
Allow . to match any newline characters. |
U |
Normally modifiers like * and + are greedy, matching as much as possible. The U modifier makes them ungreedy, matching as little as possible. |
u | Enable unicode-specific patterns like \p. |
x |
Enable extended mode—ignore whitespace and comments (# to end of line). |
You manipulate regular expressions with the Regex module.
| iex> Regex.run ~r{[aeiou]}, "caterpillar" |
| ["a"] |
| iex> Regex.scan ~r{[aeiou]}, "caterpillar" |
| [["a"], ["e"], ["i"], ["a"]] |
| iex> Regex.split ~r{[aeiou]}, "caterpillar" |
| ["c", "t", "rp", "ll", "r"] |
| iex> Regex.replace ~r{[aeiou]}, "caterpillar", "*" |
| "c*t*rp*ll*r" |