Literals and Special Syntactic Rules
Integers can be written in various forms and number bases:
|1234 -123||Regular decimal notation|
|#b0 #b10101||Binary notation|
|#0 #10101||Binary notation (alternative form)|
|#o377 #o-111||Octal notation|
|#d123456789 #d+123||Explicitly decimal notation|
|#xc0ffe 0x-01||Hexadecimal notation|
|#2r1010 #8r377 #36rhelloworld||Notation with explicit base (up to 36)|
|#\a #$ #\ä #\🐭||Character notation (the value is the Unicode code point of the character|
|#\x1f42d;||Character notation with the value in hexadecimal|
In all these forms, the case of the indicating letter is not
#B1010 are identical as are
Similarly, the case is not significant for digits beyond
(i.e. 'a', 'b', 'c', … for number bases larger than 10), e.g.
is the same as
#xABCD and can even be mixed in the same number,
#36rHelloWorld is valid and the same number as
The character notation using hexadecimal code representation
#\x....;) is basically the same thing as the regular hexadecimal
#x.... except that it conveys to the reader that a
character is intended and that it does a sanity check on the value
(e.g. negative numbers and value outside the Unicode range are not
Floating point numbers
There is only one type of floating point numbers and the literals are written in the usual way, e.g. these are all valid floating point numbers:
1.0 +1.0 -1.0 1.0e10 1.111e-10
The one thing to watch out for is that you cannot omit the the part
before or after the decimal point if it is zero. E.g. the following
are not valid forms:
There are two forms of strings: list strings and binary strings.
List strings are just lists of integers (where the values have to be
from a certain set of numbers that are considered valid characters)
but they have their own syntax for literals (which will also be used
for integer lists as an output representation if the list contents
looks like it is meant to be a string):
"any text between double
quotes where \" and other special characters like \n can be
As a special case you can also write out the character number in the
\xHHH; (where "HHH" is an integer in hexadecimal notation),
"\x61;\x62;\x63;" is a complicated way of writing
This can be convenient when writing Unicode letters not easily
typeable or viewable with regular fonts. E.g.
"Cat: \x1f639;" might
be easier to type (and view on output devices without a Unicode font)
Binary strings are just like list strings but they are represented
differently in the virtual machine. The simple syntax is
#"This is a binary string \n with some \"escaped\" and quoted
You can also use the general format for creating binaries (
described below), e.g.
#B(97) are all the
same binary string.
Certain control characters can be more readably included by using their escaped name:
Alternatively you can also use the hexadecimal character encoding,
"a\x0a;b" are the same string.
We have already seen binary strings, but the
#B(...) syntax can be
used to create binaries with any contents. Unless the contents is a
simple integer you need to annotate it with a type and/or size.
Example invocations are that show the various annotations:
|#B(42 (42 (size 16)) (42 (size 32)))||#B(42 0 42 0 0 0 42)|
|#B(-42 111 (-42 (size 16)) 111 (-42 (size 32)))||#B(-42 111 (-42 (size 16)) 111 (-42 (size 32)))|
|#B((42 (size 32) big-endian) (42 (size 32) little-endian))||#B(0 0 0 42 42 0 0 0)|
|#B((1.23 float) 111 (1.23 (size 32) float) 111 (1.23 (size 64) float))||#B(63 243 174 20 122 225 71 174 111 63 157 112 164 111 63 243 174 20 122 225 71 174)|
|#B((#"a" binary) (#"b" binary))||#"ab"|
|#B("Cat:" #\ (128569 utf-8))||#"Cat: 😹"|
Learn more about "segments" of binary data in the Erlang teaching book.
Lists are formed either as
( ... ) or
[ ... ] where the
optional elements of the list are separated by some form or
() (the empty list),
(foo bar baz), or
(foo bar baz)
Tuples are written as
#(value1 value2 ...). The empty tuple
is also valid.
Maps are written as
#M(key1 value1 key2 value2 ...) (again, the
empty map is also valid and written as
Things that cannot be parsed as any of the above are usually considered as a symbol.
Simple examples are
:foo. But also
1.23e4extra (but note that
illegal digits don't make a number a symbol when using the explicit
number base notation, e.g.
#b10foo gives an error).
Symbol names can contain a surprising breadth or characters:
(This is basically all of the latin-1 character set without control character, whitespace, the various brackets, double quotes and semicolon).
Of these, only
# may not be the first
character of the symbol's name (but they are allowed as subsequent
I.e. these are all legal symbols:
Symbols can be explicitly constructed by wrapping their name in
vertical bars, e.g.
|symbol name with spaces|. In this
case the name can contain any character of in the range from 0 to 255
(or even none, i.e.
|| is a valid symbol). The vertical bar in the
symbol name needs to be escaped:
|symbol with a vertical bar \| in
its name| (similarly you will obviously have to escape the escape
character as well).
Comments come in two forms: line comments and block comments.
Line comments start with a semicolon (
;) and finish with the end of the line.
Block comments are written as
#| comment text |# where the comment
text may span multiple lines but my not contain another block comment,
i.e. it may not contain the character sequence
Evaluation While Reading
#.(... some expression ...). E.g.
'#.(+ 1 1) will evaluate the
(+ 1 1) while it reads the expression and then be effectively