Prolog, Erlang, Elixir

a side-by-side reference sheet

grammar and invocation | variables and expressions | arithmetic and logic | strings | regexes | dates and time | lists | tuples | dictionaries | algebraic data types | functions | execution control | file handles | files | directories | processes and environment | libraries and namespaces | reflection | repl

prolog erlang elixir
version used
 
SWI Prolog 5.10 8.0 1.3
show version
 
$ swipl --version $ erl -version $ elixir -v
grammar and invocation
prolog erlang elixir
hello world $ cat ./hello.pl
hello :-
  format('Hello, World!~n'),
  halt.

$ swipl -q -t hello -f ./hello.pl
Hello, World!
$ cat hello.erl
-module(hello).
-export([hello_world/0]).

hello_world() ->
  io:format("Hello, World!~n"),
  halt(0).

$ erlc hello.erl

$ erl -noshell -run hello hello_world
Hello, World!
$ cat hello.exs
IO.puts "Hello, World!"

$ elixir hello.exs
Hello, World!
compiler does not create a stand-alone executable:
$ erlc +native foo.erl
bytecode compiler
 
$ erlc foo.erl
interpreter $ cat arg-analyzer
%%!
main([String]) ->
  io:format("argument was: ~s\n", [String]);
main(_) ->
  io:format("Usage: arg-analyzer ARG\n").

$ escript arg-analyzer foo
argument was: foo
shebang $ cat arg-analyzer
#!/usr/bin/env escript
%%!
main([String]) ->
  io:format("argument was: ~s\n", [String]);
main(_) ->
  io:format("Usage: arg-analyzer ARG\n").

$ ./arg-analyzer foo
argument was: foo
repl
 
$ swipl $ erl $ iex
block delimiters if ; end
case ; end
try catch end
fun ; end
receive end
do ; end
statement terminator
 
. .
end-of-line comment
 
% a comment % a comment # a comment
multiple line comment /* comment line
comment line
*/
variables and expressions
prolog erlang elixir
variable identifier upper case letter followed by alphanumeric characters upper case letter following by alphanumeric characters and underscores.
write once variable previously unused variables on the left side of an equal sign will be assigned to values that make the left match the right
assignment X = 3.
4 = Y.
X = 3. x = 3
parallel assignment (X, Y) = (1, 2).
[X, Y] = [1, 2].
{X, Y} = {1, 2}.
foo(X, Y) = foo(1, 2).
{X, Y} = {1, 2}.
[Z, W] = [1, 2].
{x, y} = {1, 2}
[z, w] = [1, 2]
non-referential identifier lower case letter followed by alphanumeric characters; can also include underscore: _ lower case letter followed by alphanumeric characters; can also include period: . at-sign: @ underscore: _
quoted non-referential identifier any printable characters inside single quotes; use backslash to escape a single quote. any printable characters inside single quotes; use backslash or two single quotes to escape a single quote.
conditional expression if
  X > 0 -> 1;
  X == 0 -> X;
  X < 0 -> -1
end
if x > 0 do 1 else if x < 0 do -1 else 0 end end
case case X of
  1 -> true;
  0 -> false
end
case x do
  1 -> true
  0 -> false
end
arithmetic and logic
prolog erlang elixir
true and false
 
true fail true false true false
falsehoods
 
false and all non-boolean values false nil
logical operators , ; ?? ?? and or xor not
in guards:
, ;
# arguments must be boolean:
and or not

# arguments of any type permitted:
&& || !
short circuit operators andalso orelse and or && ||
relational operators =:= \= < > =< >= == /= < > =< >=
no numeric conversion:
=:= =/=
arithmetic expression is(X, 2 + 2). 2 + 2 2 + 2
arithmetic operators

addition, subtraction, multiplication, float division, integer division, remainder
+ - * / // mod + - * / div rem + - * / div rem

div and rem are functions, not operators
integer division is(X, 7 // 3). 7 div 3. div 7, 3
div(7, 3)
integer division by zero zero_divisor error bad argument exception raises ArithmeticError
float division
 
is(X, 7 / 3). 7 / 3. 7 / 3
float division by zero zero_divisor error bad argument exception raises ArithmeticError
power
 
is(X, 2**32). math:pow(2, 32). :math.pow(2, 32)
sqrt
 
is(X, sqrt(2)). math:sqrt(2). :math.sqrt(2)
sqrt -1
 
arithmetic evaluation error: undefined raises bad argument exception raises ArithmeticError
transcendental functions exp log
sin cos tan
asin acos atan
atan2
math:exp math:log
math:sin math:cos math:tan
math:asin math:acos math:atan
math:atan2
:math.exp :math.log
:math.sin :math.cos :math.tan
:math.asin :math.acos :math.atan
:math.atan2
float truncation truncate round floor ceiling % 2, 3:
trunc(2.7)
round(2.7)

none
none
# 2, 3:
trunc(2.7)
round(2.7)

# 2.0, 3.0:
Float.floor(2.7)
Float.ceil(2.7)
absolute value is(X, abs(-3)).
is(X, abs(-3.2)).
abs(-3)
abs(-3.2)
abs(-3)
abs(-3.2)
integer overflow
float literal with exponent 2.0e2
-2.0E-2
2.0e2
-2.0E-2
2.0e2
-2.0e-2
random number is(X, random(100)).
??
random:uniform().
random:uniform(100).
:random.uniform
:random.uniform(100)
random seed
 
set_random(seed(17)). random:seed(17, 17, 17). :random.seed(17, 17, 17)
result of not seeding seeded using /dev/random or system time interpreter uses same seed at startup.
bit operators is(X, 5 << 1).
is(X, 5 >> 1).
is(X, 5 /\ 1).
is(X, 5 \/ 1).
is(X, 5 xor 1).
is(X, 5 \ 1).
5 bsl 1
5 bsr 1
5 band 1
5 bor 1
5 bxor 1
bnot 5
import Bitwise

5 <<< 1
5 >>> 1
5 &&& 1
5 ||| 1
5 ^^^ 1
~~~5
binary, octal, and hex literals 2#101010
8#52
16#2A
0b101010
0o52
0x2A
strings
prolog erlang elixir
string literal list of characters:
"don't say \"no\""

quoted atom:
'don\'t say "no"'
"don't say \"no\"" "don't say \"no\""
newline in literal yes; and \n notation can also be used yes; and \n notation can also be used
character escapes \a \b \e \f \n \r \s \t \v \xhh…\ \uhhhh \Uhhhhhhhh \ooo \\ \' \" \d is delete; \s is space
\b \d \e \f \n \q \r \s \t \u \v \xhh \x{hh…} \ooo \' \" \\
\" \' \\ \a \b \d \e \f \n \r \s \t \v \0
\xhh \uhhhh \u{h…}
concatenate append("one ","two ",Y), append(Y,"three",X). "one " ++ "two " ++ "three"

string:concat("one ", string:concat("two ", "three"))

concatenates double quoted string literals only:
"one " "two " "three"
"one " <> "two " <> "three"
replicate
 
Hbar = string:copies("-", 80). :binary.copy("-", 80)
trim
both sides, left side, right side
string:strip(" lorem ")
string:strip(" lorem", left)
string:strip("lorem ", right)
String.trim(" lorem ")
pad
on right, on left, both sides
string:right("lorem", 10, $ )
string:left("lorem", 10, $ )
string:centre("lorem", 10, $ )
String.pad_leading("lorem", 10, ["$"])
String.pad_trailing("lorem", 10, ["$"])
number to string "value: " ++ integer_to_list(8)
"value: " ++ float_to_list(3.14)
"value: " <> Integer.to_string(8)
"value: " <> Float.to_string(3.14)
string to number 7 + list_to_integer("12")
73.9 + list_to_float("0.039")
7 + String.to_integer("12")
73.9 + String.to_float("0.039")
non-referential identifier to string name(foo, X). atom_to_list(foo) Atom.to_string(:foo)
string to non-referential identifier string_to_atom("foo", X). list_to_existing_atom("foo") String.to_atom("foo")
translate case
to upper, to lower
upcase_atom('lorem', X).
downcase_atom('LOREM', X).
string:to_upper("lorem")
string:to_lower("LOREM")
String.downcase("LOREM")
String.upcase("lorem")
String.capitalize("lorem")
split string:tokens("foo bar baz", " ")

{ok, Rx} = re:compile("\s+").
re:split("foo bar baz", Rx, [{return, list}])
String.split("foo bar baz")
Regex.split(~r/ /, "foo bar baz")
join
 
string:join(["foo", "bar", "baz"], " ") String.join(["foo", "bar", "baz"])
character literal
 
none $A 'A'
string length length("hello", X).

atom_length('hello', X).
length("hello") String.length("hello")
index of substring
first, last
% 5:
string:str("foo bar bar", "bar")

% 9:
string:rstr("foo bar bar", "bar")
# {4, 3}:
:binary.match("foo bar baz", "bar")

??
extract substring string:substr("foo bar bar", 5, 3) String.slice("foo bar baz", 5..3)
chr and ord char_code(X, 65).
char_code('A', X).
[65]
lists:nth(1, "A")
List.to_string([65])
Enum.at('A', 0)
regular expressions
prolog erlang elixir
literal % none; strings are used:
"lorem|ipsum"

% can be compiled to RE object:
Rx = re:compile("lorem|ispum").
~r/lorem|ipsum/
character class abbreviations . \d \D \h \H \s \S \v \V \w \W . \d \D \h \H \s \S \v \V \w \W
anchors
 
^ $ \A \b \B \G \z \Z ^ $ \A \b \B \G \z \Z
match test {ok, Rx} = re:compile(".*1999.*").

case re:run("it's 2000", Rx) of
  {match, _} -> io:format("party!");
  nomatch -> io:format("work")
end.
Regex.match?(~r/.*1999/, "it's 2000")
String.match?("it's 2000", ~r/.*1999/)
case insensitive match test {ok, Rx} = re:compile("lorem", [caseless]).

case re:run("Lorem", Rx) of
  {match, _} -> io:format("matches");
  nomatch -> io:format("doesn't match")
end.
Regex.match?(~r/lorem/i, "Lorem")
String.match?("Lorem", ~r/lorem/i)
modifiers unicode
caseless
dotall
multiline
extended
firstline
ungreedy
u i s m x f U
substitution {ok, Rx} = re:compile("mi").

NewStr = re:replace("do re mi mi mi", Rx, "ma",
  [global, {return,list}]).
Regex.replace(~r/mi/, "do re mi mi mi", "ma")
String.replace("do re mi mi mi", ~r/mi/, "ma")
match, prematch, postmatch S = "It's 1999!".
Rx = "(\\d{4})".
[Pre, Match, Post] = re:split(S, Rx, [{return, list}]).
group capture S = "2010-06-03".
Rx = "(\\d{4})-(\\d{2})-(\\d{2})".
Opts = [{capture, all_but_first, list}].
{match, [Yr, Mn, Dy]} = re:run(S, Rx, Opts).
named group capture S = "foo.txt".
Rx = "^(?<file>.+)\\.(?<suffix>.+)$".
Opts = [{capture, [file, suffix], list}].
{match, [File, Suffix]} = re:run(S, Rx, Opts).
scan
backreference in match S = "do do".
Rx = "(\\w+) \\1".
{match, _} = re:run(S, Rx).
backreference in substitution S = "do re".
Rx = "(\\w+) (\\w+)".
Opts = [{return, list}].
S2 = re:replace(S, Rx, "\\2 \\1", Opts).
dates and time
prolog erlang elixir
current date/time {{YYYY,MM,DD}, {HH,MI,SS}} = calendar:universal_time().
{{YYYY,MM,DD}, {HH,MI,SS}} = calendar:local_time().
DateTime.utc_now
lists
prolog erlang elixir
list literal [1, 2, 3] [1, 2, 3] [1, 2, 3]
cons X = [4 | [3, 2, 1]]. [4 | [3, 2, 1]] [4 | [3, 2, 1]]
head [X | _] = [1, 2, 3]. hd([1 ,2, 3])
% or use pattern matching:
[Head | _] = [1 ,2, 3].
Head
hd([1, 2, 3])
[head | _] = [1, 2, 3]
List.first [1, 2, 3]
tail [_ | X] = [1, 2, 3]. tl([1, 2, 3])
% or use pattern matching:
[_ | Tail] = [1, 2, 3].
Tail
tl([1, 2, 3])
[_ | tail] = [1, 2, 3]
length length([1, 2, 3], X). length([1, 2, 3]) length([1, 2, 3])
Enum.count([1, 2, 3])
append append([1, 2], [3, 4], List). [1, 2] ++ [3, 4] [1, 2] ++ [3, 4]
sort sort([1, 3, 2, 4], X). lists:sort([1, 3, 2, 4]). Enum.sort([1, 3, 2, 4])
reverse reverse([1, 2, 3, 4], X). lists:reverse([1, 2, 3, 4]). Enum.reverse([1, 2, 3, 4])
membership member(1, [1, 2, 3]). Enum.member?([1, 2, 3], 1)
zip lists:zip([1, 2, 3], ["a", "b", "c"]). Enum.zip([1, 2, 3], ["a", "b", "c"])
map lists:map(fun(X) -> X * X end, [1, 2, 3]). Enum.map([1, 2, 3], fn x -> x * x end)
filter lists:filter(fun(X) -> X > 2 end, [1, 2, 3]). Enum.filter([1, 2, 3], fn x -> x > 2 end)
reduce % 2:
lists:foldl(fun(X, Y) -> X - Y end, 0, [1, 2, 3, 4]).

% -2:
lists:foldr(fun(X, Y) -> X - Y end, 0, [1, 2, 3, 4]).
# 2:
Enum.reduce([1, 2, 3], fn x, y -> x - y end)
tuples
prolog erlang elixir
tuple literal (1, "hello", 3.14) {1, "foo", 3.14} {1, "foo", 3.14}
tuple element access % "foo":
element(1, {1, "foo", 3.14})

% {1, "bar", 3.14}:
setelement(2, {1, "foo", 3.14}, "bar")
# "foo":
elem({1, "foo", 3.14}, 2)

# 1, "bar", 3.14}:
put_elem({1, "foo", 3.14}, 2, "bar")
tuple length tuple_size({1, "foo", 3.14}) tuple_size({1, "foo", 3.14})
dictionaries
prolog erlang elixir
literal %{"t" => 1, "f" => 0}
size
lookup
update
missing key behavior
is key present
iterate
algebraic data types
record
prolog erlang elixir
functions
function definition factorial(0,1).
factorial(N, F) :- is(N1, N - 1), factorial(N1, F1), is(F, N * F1).
factorial(0) -> 1;
factorial(N) -> N * factorial(N-1).
def factorial(0), do: 1
def factorial(n), do: n * factorial(n - 1)
function definition with guards factorial(N) when N > 0 -> N * factorial(N-1);
factorial(0) -> 1.
def factorial(n) when n > 0, do: n * factorial(n - 1)
def factorial(0), do: 1
anonymous function fun(X, Y) -> X + Y end fn(x, y) -> x + y end
piecewise defined anonymous function fun([]) -> null;
  ([X|_]) -> X
end
execution control
prolog erlang elixir
if if
  X == 0 -> io:format("no hits~n");
  X == 1 -> io:format("one hit~n");
  X > 1 -> io:format("~w hits~n", [X])
end.
if x == 0 do
  IO.puts "no hits"
else
  IO.puts "hits"
end
for for x <- 1..10, do: IO.puts(x)
try/catch X = 0.
try (7 div X) of
  Val -> Val
catch
  error:badarith -> 0
end.
try do
  div(7, 0)
  :ok
catch
  _, _ -> :failed
end
receive message -module(echo).
-export([loop/0]).
 
loop() ->
  receive
    {From, Msg} ->
      From ! { self(), Msg},
      loop();
    stop ->
      true
  end.
receive do
  {:ok, some_value} -> :yay
  {:error, val} when val > 0 -> :meh
  {:error, oh_no} -> :aw
end
spawn process Pid = spawn(echo, loop, []). pid = spawn(fn -> :ok end)
send message Pid ! {self(), hello}. send(pid, :hello)
list processes processes(). Process.list
file handles
prolog erlang elixir
read line from stdin # returns newline terminated string:
s = IO.gets("> ")
write line to stdout
write line to stderr
open file for reading open('foo.txt', read, Fd). {:ok, f} = File.open("/etc/hosts", [:read])
read line X = io:get_line("type line: ").
read character get_char(X). X = io:get_chars("type char: ", 1).
read term read(X). {ok, X} = io:read("type term: ").
open file for writing open('foo.txt', write, Fd). {:ok, f} = File.open("/tmp/foo.txt", [:write])
open file for appending
write line
write character put_char("A").
put_char(65)
write term X = hello, write(X). io:write(X).
printf format('foo: ~s ~2f ~w~n', ["bar", 3.1415, 7]). io:format("foo: ~s ~.2f ~w~n", ["bar", 3.1415, 7]).
close file close(Fd). :ok = File.close(f)
files
prolog erlang elixir
file test, regular file test filelib:is_file("/etc/hosts")
filelib:is_regular("/etc/hosts")
File.regular? "/etc/hosts"
file size filelib:file_size("/etc/hosts")
directories
prolog erlang elixir
build pathname filename:join("/etc", "passwd")
dirname and basename filename:dirname("/etc/passwd")
filename:basename("/etc/passwd")
File.dirname "/etc/hosts"
File.basename "/etc/hosts"
absolute pathname filename:absname("..") File.absname "/etc/hosts"
glob paths returns list of strings:
filelib:wildcard("/etc/*")
make directory filelib:ensure_dir("/tmp/foo/bar/") File.mkdir_p("/tmp/foo/bar")
directory test filelib:is_dir("/tmp") File.dir? "/tmp"
processes and environment
prolog erlang elixir
command line arguments binds Argv to list of atoms representing command line args:
current_prolog_flag(argv, Argv).
when invoked by escript the command line arguments are passed to the function main in the invoked file as a list of strings. System.argv
program name
exit halt(1). halt(1). System.halt
libraries and namespaces
prolog erlang elixir
load file ways to load file data.pl:
[data].
['data.pl'].
consult(data)
define namespace in file factorial.erl
-module(factorial).
-export([factorial/1]).
definition of factorial
defmodule Factorial do
end
compile namespace c(factorial). c("factorial.ex")
use function in namespace factorial:factorial(7). Factorial.fact 7
reflection
prolog erlang elixir
inspect namespace factorial:module_info().
repl
help help(). h
clear variable f(X).
clear all variables f().
display processes i().
__________________________________________________________________________ __________________________________________________________________________ __________________________________________________________________________

version used

Version used for testing the examples in the sheet.

show version

How to determine the version.

Grammar and Invocation

hello world

A "Hello, World!" program.

compiler

The native compiler.

erlang:

Sometimes the HiPE native compiler must be installed separately.

Modules can be compiled to native code, but an Erlang runtime is still required to run the code.

bytecode compiler

The bytecode compiler.

interpreter

The interpreter.

shebang

How to associate an interpreter with a file on a Unix system.

repl

How to run the read-evaluate-print loop.

block delimiters

How blocks are delimited. A block is a sequence of statements which are executed in order.

statement terminator

How statements are terminated.

end-of-line comment

The syntax for a comment which goes to the end of the current line.

multiple line comment

The syntax for a delimited comment which can span lines.

Variables and Expressions

Arithmetic and Logic

true and false

The literals for true and false.

falsehoods

Values which evaluate as false in a boolean context.

logical operators

short circuit operators

relational operators

erlang:

Relational operators can be used on values with different types. In this case the precedence is determined by
the type according to this sequence:

number < atom < reference < fun < port < pid < tuple < list < binary

If a comparison is performed on an integer and a float, the integer will be converted to a float. =:= and =/= do not perform conversions and thus will always return false and true respectively when called on an integer and a float.

arithmetic expression

arithmetic operators

unary negation

integer division

How to find the quotient of two integers.

integer division by zero

The result of dividing an integer by zero.

float division

How to perform float division of two integers.

float division by zero

The result of dividing a float by zero.

power

sqrt

sqrt -1

transcendental functions

float truncation

absolute value

random number

random seed

bit operators

Strings

string literal

newline in literal

character escapes

erlang:

Some of the Erlang backslash escapes are not derived from C:

\d delete
\s space

concatenate

replicate

trim

pad

number to string

string to number

atom to string

string to atom

split

join

Regular Expressions

Dates and Time

Lists

Tuples

Dictionaries

Algebraic Data Types

Functions

function definition

function definition with guards

erlang:

The expressions in guards must be side-effect free. Thus they can only contain the following:

  • bound variables
  • literals
  • type tests: is_atom, is_boolean, is_tuple, …
  • relational operators
  • arithmetic operators
  • boolean operators
  • a few built-in functions

Execution Control

File Handles

read line

erlang:

io:get_line accepts an argument which is displayed as a prompt. The return value is a string which includes the newline.

read character

erlang:

io:get_chars accepts two arguments. The first is a string which is displayed as a prompt. The second is the number of characters to be read. The function keeps reading lines until the requested number of characters has been collected. The return value is a string which can contain newlines if a line of less than the requested number of characters was entered.

Files

Directories

Processes and Environment

Libraries and Namespaces

Reflection

REPL

Prolog

SWI Prolog Reference Manual
Prolog: The ISO Standard Document

Erlang

Erlang Reference Manual User's Guide
Erlang Standard Library

Elixir

Elixir: Introduction
Elixir: Standard Library

issue tracker | content of this page licensed under creative commons attribution-sharealike 3.0