What Is Erlang?What Is Erlang?
Erlang is a programming language for building highly parallel,
distributed, fault-tolerant systems.
To start the Erlang interpreter, type erl at the shell prompt. And do not
forget: there is a dot at the end of an Erlang statement, not a
semicolon.
Facts about ErlangFacts about Erlang
● “Shared-nothing” model: no shared variables, pure message passing
● Erlang processes run on nodes, nodes run on physical computers
● Pairs of processes can be linked to support termination notification
● Hot-swappable modules (dynamic on-the-fly code replacement)
● Mnesia: built-in distributed fault-tolerant database
● OTP (Open Telecom Platform), a set of libraries and procedures that
includes:
● A complete Web server
● A complete FTP server
● A CORBA ORB
Apach vs YawsApach vs Yaws
● Yaws is an Erlang-
based Web server
● The graph shows
thoughput (KB/sec)
vs. load.
● Apache (blue and
green) dies when
subject to a load of
ca. 4000 parallel
sessions.
Erlang execution modelErlang execution model
Sequential ErlangSequential Erlang
Programming Erlang: the Sequential Part 6
ArithmeticsArithmetics
● Erlang integer numbers are arbitrary-sized (there is no overflow)
● 16#19AC is a base 16 number, 32#SUGAR is a base 32 number, etc.
● / always produces a floating point value; rem and div perform integer
division. 5/2 is 2.5
● bnot, band, bor, bxor, bsl, bsl perform bitwise operations
Programming Erlang: the Sequential Part 7
VariablesVariables
● Variables in Erlang are single-assignment (immutable), like final in
Java. Single assignment does not cause side effects and makes
parallelism easy. Variable names begin with an uppercase letter.
● = is not assignment but matching: it matches the LHS against the RHS
and binds variables to the matching values. No weird math like
X=X+1.
● Function f() “forgets” all existing bindings.
Programming Erlang: the Sequential Part 8
ExamplesExamples
1> Oranges = 7.
7
2> Apples = 12.
12
3> Apples1 = Apples / 5 + Oranges.
9.4
4> Apples = Apples.
12
5> Oranges = Apples.
** exception error: no match of right hand side value
12
Programming Erlang: the Sequential Part 9
AtomsAtoms
● An atom is like a C/Java enum. It begins with a lowercase letter, can
consist of alphanumeric symbols, underscores _, and @. It can also be
any sequence of symbols in single quotation marks.
● The value of an atom is the atom itself.
Programming Erlang: the Sequential Part 10
ExamplesExamples
1> Apple.
* 1: variable 'Apple' is unbound
2> apple.
apple
3> 'Apple'.
'Apple'
4> apples@oranges.
apples@oranges.
Programming Erlang: the Sequential Part 11
TuplesTuples
● A tuple is a collection of values enclosed in curly braces {}.
● The tuple fields do not have to be homogeneous.
● Tuple fields can be extracted using pattern matching.
● Atom _ matches anything.
Programming Erlang: the Sequential Part 12
ExamplesExamples
1> Food = {{apples, 12}, {oranges, 32}}.
{{apples,12},{oranges,32}}
2> {_,{_,Noranges}} = Food.
{{apples,12}, {oranges,32}}
3> NOranges.
32
Programming Erlang: the Sequential Part 13
ListsLists
● A list is an ordered collection of values enclosed in square brackets [].
● A list has a head H (car) and a tail T (cdr). T must be a list (can be an
empty list []).
● Vertical bar | separates H from T: [ H | T ]
● List elements can be extracted by pattern matching.
● Always build lists by adding a head to a tail! Operator ++ is very
slow.
Programming Erlang: the Sequential Part 14
ExamplesExamples
1> Food = [{apples,12},{oranges,77},{foobar,3}].
[{apples,12},{oranges,77},{foobar,3}]
2> [Breakfast|MoreFood] = Food.
[{apples,12},{oranges,77},{foobar,3}]
3> Breakfast.
{apples,12}
4> {FruitForBreakfast,_} = Breakfast.
{apples,12}
5> FruitForBreakfast.
apples
Programming Erlang: the Sequential Part 15
Other OperatorsOther Operators
● =:= tests for equality
● Boolean operators: and, or, not, xor
● Short-circuit Boolean: orelse, andalso
● ++ (infix) appends lists (should be avoided)
● -- subtracts a list from a list
Programming Erlang: the Sequential Part 16
StringsStrings
● A string is a list of integers.
● A string can be also represented as a collection of printable symbols
enclosed into double quotes.
● Operator $ translates a character into its numerical value: $a is 97.
● [$h,$e,$l,$l,$o] is “hello.”
Programming Erlang: the Sequential Part 17
ModulesModules
● A module (mymod) is a logically complete piece of code in a file
(mymod.erl).
● Function c() compiles a module into bytecode: c(mymod). produces
file mymod.beam.
● Modules have attributes.
● Attribute -module(mymod). starts the module code.
● Attribute -import(othermod). imports a module.
● Attribute -export([list of funcs]). exports functions.
● Attributes must precede any other code.
Programming Erlang: the Sequential Part 18
FunctionsFunctions
● A function consists of one or more clauses with heads and bodies.
● The clauses are separated by a semicolon.
● The order of clauses matters.
● Clauses can be recursive.
● Functions must be declared in modules (not in the shell).
● Functions are polymorphic.
Programming Erlang: the Sequential Part 19
ExamplesExamples
-export[area/1].
area ({rectangle, H, W}) → W * H;
area ({circle, R}) → 3.14159 * R * R.
%% Another file!
-export[reduce/1,reduce/0].
reduce ([]) → 0;
reduce ([Head|Tail]) → someFuncOf (Head)
+ reduce (Tail).
%% Functions can be polymorphic.
reduce () → reduce ([]).
Programming Erlang: the Sequential Part 20
Anonymous Functions (Funs)Anonymous Functions (Funs)
● A function is a first-order object.
● It can be anonymous (like a closure)—a fun.
● Funs can be passed as parameters.
● Funs can be returned.
Programming Erlang: the Sequential Part 21
ExamplesExamples
%% file apply.erl
-export([apply1/2]).
apply1 (Func, X) → Func(X).
%% shell
1> apply.apply1 (fun(X)→X*X end,77).
5929
2> Invert = fun(X) → bnot X end.
#Fun<erl_eval.6.13229925>
3> apply:apply1 (Invert, 77).
-78
4> Invert(16).
17
Programming Erlang: the Sequential Part 22
Module “lists”Module “lists”
● Implicitly imported.
● lists:map/2 applies a function to a list and returns a new list
● lists:filter/2 returns a list of elements for which a function returns true
● lists:seq/2 returns a list of sequential integer numbers in a range
● lists:reverse/1 reverses a list (highly optimized!)
Programming Erlang: the Sequential Part 23
ExamplesExamples
1> lists:filter (fun (X) → X div 2 =:= X-1 end,
[1,2,3,4,5,6,7]).
[1,2]
2> lists:map (fun (X) → X*X end, [1,2,3,4,5,6,7]).
[1,4,9,16,25,36,49]
Programming Erlang: the Sequential Part 24
List ComprehensionList Comprehension
● List comprehensions are expression to create lists by rules
● A comprehension consists of a constructor and qualifiers (one or
more)
● A qualifier is a filter (a predicate or a boolean expression) or a
generator of the form Pattern←List
Programming Erlang: the Sequential Part 25
ExamplesExamples
1> [X*X || X←[1,2,3,4,5,6,7,8]].
[1,4,9,16,25,36,49,64]
2> [X*X || X←lists:seq (1,8)].
[1,4,9,16,25,36,49,64]
%% qsort
qsort ([])→[];
qsort ([Pivot|T]) → qsort ([X || X ← T, X < Pivot] ++
[Pivot] ++ qsort ([X || X←T, X >= Pivot]).
%% permutations
perms ([]) → [[]];
perms (L) → [[H|T] || H ← L, T ← perms (L--[H])].
Programming Erlang: the Sequential Part 26
Block ExpressionsBlock Expressions
● Used when more than one expression is needed to produce the value
(like progn in Lisp)
● The value of the block is the value of the last expression:
begin
expr1,
expr2,
expr3
end
Programming Erlang: the Sequential Part 27
GuardsGuards
● Guard sequence is a series of guards separated by “;” (meaning “or”)
● Guard is a sequence of guard expressions separated by “,” (meaning
“and”)
● Guard expression is true, constant (=false), guard predicate (is_atom,
is_number, etc.), guard built-in function (abs, float, etc.), term
comparison (/=,==,=/=,=:=,etc.), arithmetic expression or (short-
circuit) boolean expression
Programming Erlang: the Sequential Part 28
ExamplesExamples
small(X) when X=:=0 orelse 1/abs(X) > 1000 → true;
small(X) → false;
max(X,Y) when X>Y → X;
max(X,Y) when true → Y. %% when true is optional
… when is_tuple(X), size(X)=:=6, abs(element(3,X))>5
element(4,X)=:=hd(L) …
Programming Erlang: the Sequential Part 29
RecordsRecords
● Records are tuples with named elements.
● They are declared with -record() attribute.
● They are usually stored in *.hrl files.
● Those files are included with the -include(). attribute or
with rr() shell command
● Records are instantiated with the # operator with or without
default values
● Records can be copied with changes
● Fields can be extracted by matching
Programming Erlang: the Sequential Part 30
ExamplesExamples
%% File “student.hrl”
-record(student,{name,age,class=freshman}).
%% File “main.erl”
-include(“student.hrl”).
BestStudent = #student{}.
SeniorStudent = #student{class=senior}.
AnotherSenior = BestStudent#student{age=17}.
#student{age=Age} = AnotherSenior.
Age. %% Will print 17
Programming Erlang: the Sequential Part 31
ExamplesExamples
clear_status (#todo{status=S,who=W})=R) →
R#todo{status=finished}.
Programming Erlang: the Sequential Part 32
Conditional statementsConditional statements
case Expression of
Pattern1 [when Guard1] → seq1;
Pattern2 [when Guard2] → seq2;
end
if
Guard1 → sequence1;
Guard2 → sequence2;
end
If there is no match, an exception is raised. Atom true matches everything.
Programming Erlang: the Sequential Part 33
ExamplesExamples
%% Split a lists into odd and even elements
odds_and_evens (L) →
odds_and_evens (L,[],[]).
odds_and_evens ([H|T],Odds,Evens) →
case (H rem 2) of
1 → odds_and_evens (T,[H|Odds],Evens);
0 → odds_and_evens (T, Odds, [H, Evens])
end
odds_and_evens ([], Odds, Evens) →
{lists:reverse (Odds), lists:reverse (Evens)}.
Programming Erlang: the Sequential Part 34
● There are three types of errors in Erlang:
● exit(Why) broadcasts {'EXIT',Pid,Why} to all linked processes
● throw(Why) throws an exception
● erlang:error(Why) terminates the current process immediately
Raising ExceptionsRaising Exceptions
Programming Erlang: the Sequential Part 35
Catching an ExceptionCatching an Exception
try FuncOrExprSeq
%% This part can be omitted
of
Pattern1 [when Guard1] → Expression1;
...
catch
%% Type can be throw (default), exit, error or _:_
ExType1: ExPattern1 [when ExGuard1] → ExExpr1;
...
after %% Guaranteed to execute!
AfterExpression
end
Programming Erlang: the Sequential Part 36
ExampleExample
try math:sqrt(-1)
catch
error: {badarith, _} → ....
end
Programming Erlang: the Sequential Part 37
Process DictionaryProcess Dictionary
● Each process has a private dictionary: an associative array
● Built-in functions (BIFs) to work with dictionaries:
● @spec put (Key, Value) → OldValue.
● @spec get (Key) → Value | undefined.
● @spec get_keys () → [Key].
● @spec get () → [{Key, Value}].
● @spec erase (Key) → Value.
● @spec erase() → [{Key, Value}].
Programming Erlang: the Sequential Part 38
MacrosMacros
● Defined using -define(). attribute.
● Called using ?.
● Parameters allowed.
● Predefined macros: ?FILE, ?MODULE, ?LINE.
● Other attributes: -ifdef()., -undef()., -ifndef()., -else., -endif.
Programming Erlang: the Sequential Part 39
ExamplesExamples
%% To be used in binaries
-define (DWORD, 32/unsigned-little-integer).
?DWORD.
%% Simple macro with parameters
-ifndef (isodd).
-define (isodd (X), X rem 2 =:= 1).
-endif.
?isodd (77).
Programming Erlang: the Sequential Part 40
This presentation roughly covers the first 27
pages (of the total of 29
) of
“Programming Erlang. Software for a Concurrent World,” by Joe
Armstrong.

Introduction to Erlang Part 1

  • 1.
    What Is Erlang?WhatIs Erlang? Erlang is a programming language for building highly parallel, distributed, fault-tolerant systems. To start the Erlang interpreter, type erl at the shell prompt. And do not forget: there is a dot at the end of an Erlang statement, not a semicolon.
  • 2.
    Facts about ErlangFactsabout Erlang ● “Shared-nothing” model: no shared variables, pure message passing ● Erlang processes run on nodes, nodes run on physical computers ● Pairs of processes can be linked to support termination notification ● Hot-swappable modules (dynamic on-the-fly code replacement) ● Mnesia: built-in distributed fault-tolerant database ● OTP (Open Telecom Platform), a set of libraries and procedures that includes: ● A complete Web server ● A complete FTP server ● A CORBA ORB
  • 3.
    Apach vs YawsApachvs Yaws ● Yaws is an Erlang- based Web server ● The graph shows thoughput (KB/sec) vs. load. ● Apache (blue and green) dies when subject to a load of ca. 4000 parallel sessions.
  • 4.
  • 5.
  • 6.
    Programming Erlang: theSequential Part 6 ArithmeticsArithmetics ● Erlang integer numbers are arbitrary-sized (there is no overflow) ● 16#19AC is a base 16 number, 32#SUGAR is a base 32 number, etc. ● / always produces a floating point value; rem and div perform integer division. 5/2 is 2.5 ● bnot, band, bor, bxor, bsl, bsl perform bitwise operations
  • 7.
    Programming Erlang: theSequential Part 7 VariablesVariables ● Variables in Erlang are single-assignment (immutable), like final in Java. Single assignment does not cause side effects and makes parallelism easy. Variable names begin with an uppercase letter. ● = is not assignment but matching: it matches the LHS against the RHS and binds variables to the matching values. No weird math like X=X+1. ● Function f() “forgets” all existing bindings.
  • 8.
    Programming Erlang: theSequential Part 8 ExamplesExamples 1> Oranges = 7. 7 2> Apples = 12. 12 3> Apples1 = Apples / 5 + Oranges. 9.4 4> Apples = Apples. 12 5> Oranges = Apples. ** exception error: no match of right hand side value 12
  • 9.
    Programming Erlang: theSequential Part 9 AtomsAtoms ● An atom is like a C/Java enum. It begins with a lowercase letter, can consist of alphanumeric symbols, underscores _, and @. It can also be any sequence of symbols in single quotation marks. ● The value of an atom is the atom itself.
  • 10.
    Programming Erlang: theSequential Part 10 ExamplesExamples 1> Apple. * 1: variable 'Apple' is unbound 2> apple. apple 3> 'Apple'. 'Apple' 4> apples@oranges. apples@oranges.
  • 11.
    Programming Erlang: theSequential Part 11 TuplesTuples ● A tuple is a collection of values enclosed in curly braces {}. ● The tuple fields do not have to be homogeneous. ● Tuple fields can be extracted using pattern matching. ● Atom _ matches anything.
  • 12.
    Programming Erlang: theSequential Part 12 ExamplesExamples 1> Food = {{apples, 12}, {oranges, 32}}. {{apples,12},{oranges,32}} 2> {_,{_,Noranges}} = Food. {{apples,12}, {oranges,32}} 3> NOranges. 32
  • 13.
    Programming Erlang: theSequential Part 13 ListsLists ● A list is an ordered collection of values enclosed in square brackets []. ● A list has a head H (car) and a tail T (cdr). T must be a list (can be an empty list []). ● Vertical bar | separates H from T: [ H | T ] ● List elements can be extracted by pattern matching. ● Always build lists by adding a head to a tail! Operator ++ is very slow.
  • 14.
    Programming Erlang: theSequential Part 14 ExamplesExamples 1> Food = [{apples,12},{oranges,77},{foobar,3}]. [{apples,12},{oranges,77},{foobar,3}] 2> [Breakfast|MoreFood] = Food. [{apples,12},{oranges,77},{foobar,3}] 3> Breakfast. {apples,12} 4> {FruitForBreakfast,_} = Breakfast. {apples,12} 5> FruitForBreakfast. apples
  • 15.
    Programming Erlang: theSequential Part 15 Other OperatorsOther Operators ● =:= tests for equality ● Boolean operators: and, or, not, xor ● Short-circuit Boolean: orelse, andalso ● ++ (infix) appends lists (should be avoided) ● -- subtracts a list from a list
  • 16.
    Programming Erlang: theSequential Part 16 StringsStrings ● A string is a list of integers. ● A string can be also represented as a collection of printable symbols enclosed into double quotes. ● Operator $ translates a character into its numerical value: $a is 97. ● [$h,$e,$l,$l,$o] is “hello.”
  • 17.
    Programming Erlang: theSequential Part 17 ModulesModules ● A module (mymod) is a logically complete piece of code in a file (mymod.erl). ● Function c() compiles a module into bytecode: c(mymod). produces file mymod.beam. ● Modules have attributes. ● Attribute -module(mymod). starts the module code. ● Attribute -import(othermod). imports a module. ● Attribute -export([list of funcs]). exports functions. ● Attributes must precede any other code.
  • 18.
    Programming Erlang: theSequential Part 18 FunctionsFunctions ● A function consists of one or more clauses with heads and bodies. ● The clauses are separated by a semicolon. ● The order of clauses matters. ● Clauses can be recursive. ● Functions must be declared in modules (not in the shell). ● Functions are polymorphic.
  • 19.
    Programming Erlang: theSequential Part 19 ExamplesExamples -export[area/1]. area ({rectangle, H, W}) → W * H; area ({circle, R}) → 3.14159 * R * R. %% Another file! -export[reduce/1,reduce/0]. reduce ([]) → 0; reduce ([Head|Tail]) → someFuncOf (Head) + reduce (Tail). %% Functions can be polymorphic. reduce () → reduce ([]).
  • 20.
    Programming Erlang: theSequential Part 20 Anonymous Functions (Funs)Anonymous Functions (Funs) ● A function is a first-order object. ● It can be anonymous (like a closure)—a fun. ● Funs can be passed as parameters. ● Funs can be returned.
  • 21.
    Programming Erlang: theSequential Part 21 ExamplesExamples %% file apply.erl -export([apply1/2]). apply1 (Func, X) → Func(X). %% shell 1> apply.apply1 (fun(X)→X*X end,77). 5929 2> Invert = fun(X) → bnot X end. #Fun<erl_eval.6.13229925> 3> apply:apply1 (Invert, 77). -78 4> Invert(16). 17
  • 22.
    Programming Erlang: theSequential Part 22 Module “lists”Module “lists” ● Implicitly imported. ● lists:map/2 applies a function to a list and returns a new list ● lists:filter/2 returns a list of elements for which a function returns true ● lists:seq/2 returns a list of sequential integer numbers in a range ● lists:reverse/1 reverses a list (highly optimized!)
  • 23.
    Programming Erlang: theSequential Part 23 ExamplesExamples 1> lists:filter (fun (X) → X div 2 =:= X-1 end, [1,2,3,4,5,6,7]). [1,2] 2> lists:map (fun (X) → X*X end, [1,2,3,4,5,6,7]). [1,4,9,16,25,36,49]
  • 24.
    Programming Erlang: theSequential Part 24 List ComprehensionList Comprehension ● List comprehensions are expression to create lists by rules ● A comprehension consists of a constructor and qualifiers (one or more) ● A qualifier is a filter (a predicate or a boolean expression) or a generator of the form Pattern←List
  • 25.
    Programming Erlang: theSequential Part 25 ExamplesExamples 1> [X*X || X←[1,2,3,4,5,6,7,8]]. [1,4,9,16,25,36,49,64] 2> [X*X || X←lists:seq (1,8)]. [1,4,9,16,25,36,49,64] %% qsort qsort ([])→[]; qsort ([Pivot|T]) → qsort ([X || X ← T, X < Pivot] ++ [Pivot] ++ qsort ([X || X←T, X >= Pivot]). %% permutations perms ([]) → [[]]; perms (L) → [[H|T] || H ← L, T ← perms (L--[H])].
  • 26.
    Programming Erlang: theSequential Part 26 Block ExpressionsBlock Expressions ● Used when more than one expression is needed to produce the value (like progn in Lisp) ● The value of the block is the value of the last expression: begin expr1, expr2, expr3 end
  • 27.
    Programming Erlang: theSequential Part 27 GuardsGuards ● Guard sequence is a series of guards separated by “;” (meaning “or”) ● Guard is a sequence of guard expressions separated by “,” (meaning “and”) ● Guard expression is true, constant (=false), guard predicate (is_atom, is_number, etc.), guard built-in function (abs, float, etc.), term comparison (/=,==,=/=,=:=,etc.), arithmetic expression or (short- circuit) boolean expression
  • 28.
    Programming Erlang: theSequential Part 28 ExamplesExamples small(X) when X=:=0 orelse 1/abs(X) > 1000 → true; small(X) → false; max(X,Y) when X>Y → X; max(X,Y) when true → Y. %% when true is optional … when is_tuple(X), size(X)=:=6, abs(element(3,X))>5 element(4,X)=:=hd(L) …
  • 29.
    Programming Erlang: theSequential Part 29 RecordsRecords ● Records are tuples with named elements. ● They are declared with -record() attribute. ● They are usually stored in *.hrl files. ● Those files are included with the -include(). attribute or with rr() shell command ● Records are instantiated with the # operator with or without default values ● Records can be copied with changes ● Fields can be extracted by matching
  • 30.
    Programming Erlang: theSequential Part 30 ExamplesExamples %% File “student.hrl” -record(student,{name,age,class=freshman}). %% File “main.erl” -include(“student.hrl”). BestStudent = #student{}. SeniorStudent = #student{class=senior}. AnotherSenior = BestStudent#student{age=17}. #student{age=Age} = AnotherSenior. Age. %% Will print 17
  • 31.
    Programming Erlang: theSequential Part 31 ExamplesExamples clear_status (#todo{status=S,who=W})=R) → R#todo{status=finished}.
  • 32.
    Programming Erlang: theSequential Part 32 Conditional statementsConditional statements case Expression of Pattern1 [when Guard1] → seq1; Pattern2 [when Guard2] → seq2; end if Guard1 → sequence1; Guard2 → sequence2; end If there is no match, an exception is raised. Atom true matches everything.
  • 33.
    Programming Erlang: theSequential Part 33 ExamplesExamples %% Split a lists into odd and even elements odds_and_evens (L) → odds_and_evens (L,[],[]). odds_and_evens ([H|T],Odds,Evens) → case (H rem 2) of 1 → odds_and_evens (T,[H|Odds],Evens); 0 → odds_and_evens (T, Odds, [H, Evens]) end odds_and_evens ([], Odds, Evens) → {lists:reverse (Odds), lists:reverse (Evens)}.
  • 34.
    Programming Erlang: theSequential Part 34 ● There are three types of errors in Erlang: ● exit(Why) broadcasts {'EXIT',Pid,Why} to all linked processes ● throw(Why) throws an exception ● erlang:error(Why) terminates the current process immediately Raising ExceptionsRaising Exceptions
  • 35.
    Programming Erlang: theSequential Part 35 Catching an ExceptionCatching an Exception try FuncOrExprSeq %% This part can be omitted of Pattern1 [when Guard1] → Expression1; ... catch %% Type can be throw (default), exit, error or _:_ ExType1: ExPattern1 [when ExGuard1] → ExExpr1; ... after %% Guaranteed to execute! AfterExpression end
  • 36.
    Programming Erlang: theSequential Part 36 ExampleExample try math:sqrt(-1) catch error: {badarith, _} → .... end
  • 37.
    Programming Erlang: theSequential Part 37 Process DictionaryProcess Dictionary ● Each process has a private dictionary: an associative array ● Built-in functions (BIFs) to work with dictionaries: ● @spec put (Key, Value) → OldValue. ● @spec get (Key) → Value | undefined. ● @spec get_keys () → [Key]. ● @spec get () → [{Key, Value}]. ● @spec erase (Key) → Value. ● @spec erase() → [{Key, Value}].
  • 38.
    Programming Erlang: theSequential Part 38 MacrosMacros ● Defined using -define(). attribute. ● Called using ?. ● Parameters allowed. ● Predefined macros: ?FILE, ?MODULE, ?LINE. ● Other attributes: -ifdef()., -undef()., -ifndef()., -else., -endif.
  • 39.
    Programming Erlang: theSequential Part 39 ExamplesExamples %% To be used in binaries -define (DWORD, 32/unsigned-little-integer). ?DWORD. %% Simple macro with parameters -ifndef (isodd). -define (isodd (X), X rem 2 =:= 1). -endif. ?isodd (77).
  • 40.
    Programming Erlang: theSequential Part 40 This presentation roughly covers the first 27 pages (of the total of 29 ) of “Programming Erlang. Software for a Concurrent World,” by Joe Armstrong.