48
Introduction to Erlang Franck Petit / Sebastien Tixeuil [email protected]

Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Introduction to ErlangFranck Petit / Sebastien Tixeuil

[email protected]

Page 2: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Hello World

• ‘%’ starts a comment

• ‘.’ ends a declaration

• Every function must be in a module

• one module per source file

• source file name is module name + “.erl”

• ‘:’ used for calling functions in other modules

Page 3: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Recursive Functions

• Variables start with upper-case characters

• ‘;’ separates function clauses

• ‘,’ separates instructions

• Variables are local to the function clause

• Pattern matching and guards to select clauses

Page 4: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Recursive Functions

-module(mymath). -export([factorial/1]).

factorial(0) -> 1;factorial(N) -> N * factorial(N-1).

> mymath:factorial(6).720

Page 5: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Tail Recursion

• The arity is part of the function name

• Non-exported functions are local to the module

Page 6: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Tail Recursion-module(mylists). -export([reverse/1]).

reverse(L) -> reverse(L, []).

reverse([H|T], L) -> reverse(T, [H|L]);reverse([], L) -> L.

> mylists:reverse([3,2,1]).[1,2,3]

Page 7: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Recursion over Lists

• Pattern-matching selects components of the data

• ‘_’ is a “don’t care” pattern (not a variable)

• ‘[]’ is the empty list

• ‘[X,Y,Z]’ is a list with exactly three elements

• ‘[X,Y,Z|Tail]’ has three or more elements

Page 8: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

List Recursion with Accumulator

• The same syntax is used to construct lists

• Strings are simply lists of character codes

• Avoid adding data to the end of the list

Page 9: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Numbers

• Regular numbers 123 -34567 12.345 -27.45e-05

• #-notation for base-N integers16#ffff

• $-notation for character codes (ISO-8859-1)$A (->65)

Page 10: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Atoms

• Must start with lower case character or be quotedfriday unquoted_atoms_cannot_contain_blanks ’A quoted atom with several blanks’ ’hello \n my friend’

• Similar to hashed strings

• use only one word of data

• constant-time equality test

Page 11: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Tuples

• Terms separated by ‘,’ and enclosed in {} {a,12,’hello’}

{1,2,{3, 4},{a,{b,c}}}

{}

• A fixed number of items (similar to structure or record in conventional programming languages)

• A tuple whose first element is an atom is called a tagged tuple

Page 12: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Other Data Types• Functions

• Binaries

• Process identifiers

• References

• No separate booleans

• Erlang values in general are called “terms”

• All terms are ordered and can be compared with ‘<‘, ‘>’, ‘==’, ‘=:=’, etc.

Page 13: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Built-in Functions• Implemented in C

• All the type tests and conversions are BIFs

• Most BIFs (not all) are in the module “erlang”

• Many common BIFs are auto-imported (recognized without writing “erlang:...”)

• Operators (‘+’,’-’,’*’,’/’,...) are also really BIFs

Page 14: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Standard Libraries• Application Libraries

• Kernel

• erlang

• code

• file

• inet

• os

• Stdlib

• lists

• dict

• sets

• ...

Page 15: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Expressions• Boolean and/or/xor are strict (always evaluate both

arguments)

• Use andalso/orelse for short circuit evaluation

• ‘==’ for equality, not ‘=’

• Always use parentheses when not absolutely certain about the precedence

Page 16: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Fun Expressions• Anonymous functions (lambda expressions)

• Can have several clauses

• All variables in the pattern are new

• All variable bindings in the fun are local

• Variables bound in the environment can be used in the fun-body

Page 17: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Pattern Matching• Match failure causes run-time error

• Successful matching binds the variables

• but only if they are not already bound to a value

• previously bound variables can be used in a pattern

• a new variable can also be repeated in a pattern

Page 18: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Pattern Matchingmylength([]) -> 0;

mylength([_|T]) -> mylength(T) + 1.

Page 19: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Case-switches• Any number of clauses

• Patterns and guards, just as in functions

• ‘;’ separates clauses

• Use ‘_’ as catch-all

• Variables may also begin with underscore

• signals “I don’t intend to use this value”

Page 20: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

If-switches• Like a case-switch without the patterns and the

‘when’ keyword

• Use ‘true’ as catch-all

factorial(N) when N == 0 -> 1;

factorial(N) when N > 0 ->! N * factorial(N - 1).

Page 21: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Switching • Pattern Matching

factorial(0) -> 1;factorial(N) -> N * factorial(N-1).

• Whenfactorial(N) when N == 0 -> 1;factorial(N) when N > 0 ->! N * factorial(N - 1).

• Iffactorial(N) -> if N == 0 -> 1; N > 0 -> N * factorial(N - 1) end.

• Casefactorial(N) -> 1 case (N) of 0 -> 1; N when N > 0 -> N * factorial(N - 1) end.

Page 22: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

List Processing• List Processing BIFs

atom_to_list(A)float_to_list(F)integer_to_list(I)tuple_to_list(T)list_to_atom(L)...hd(L)tl(L)length(L)

• List Processing Functionsmember(X,L)append(L1,L2)reverse(L)delete_all(X,L)

Page 23: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Tuple Processing• Tuple Processing BIFs

tuple_to_list(T)element(N,T)setelement(N,T,Val)size(L)...

• Multiple Return Values

• PID, now()...

Page 24: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Catching Exceptions

• throw: user defined

• error: runtime errors

• exit: end process

• only catch throw exceptions normally

Page 25: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Processes

• Code is executed by a process

• A process keeps track of the program pointer, the stack, the variables values, etc.

• Every process has a unique process identifier

• Processes are concurrent

Page 26: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Processes: Implementation

• Virtual machine layer processes

• Preemptive multitasking

• Little overhead (e.g. 100.000 processes)

• Can use multiple CPUs on multiprocessor machines

Page 27: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Concurrency

• Several processes may use the same program code at the same time

• each has own program counter, stack, and variables

• programmer need not think about other processes updating the variables

Page 28: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Message Passing

• “!” is the send operator

• Pid of the receiver is used as the address

• Messages are sent asynchronously

• The sender continues immediately

• Any value can be sent as a message

Page 29: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Echo-module(echo).-export([start/0,loop/0]).

start() -> spawn(echo, loop, []).

loop() -> receive {From, Message} -> io:format("> echo: ~w Msg: ~w ~n", [self(), Message]), From ! Message, loop() end.

> Id=echo:start(), Id ! {self(),hello}.echo: <0.35.0> Msg: hello {<0.32.0>,hello}>

Page 30: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Message Queues

• Each process has a message queue (mailbox)

• incoming messages are placed in the queue (no size limit)

• A process receives a message when it extracts it from the mailbox

• need not take the first message in the queue

Page 31: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Receiving a Message

• receive-expressions are similar to case switches

• patterns are used to match messages in the mailbox

• messages in the queue are tested in order

• only one message can be extracted each time

Page 32: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Selective Receive

• Patterns and guards permit message selection

• receive-clauses are tried in order

• If no message matches, the process suspends and waits for a new message

Page 33: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Receive with Timeout

• A receive-expression can have an after-part

• can be an integer (milliseconds) or “infinity”

• The process waits until a matching message arrives, or the timeout limit is exceeded

• soft real-time: no guarantees

Page 34: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Send and Reply

• Pids are often included in messages (self()), so that the receiver can reply to the sender

• If the reply includes the Pid of the second process, it is easier for the first process to recognize the reply

Page 35: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Message Order

• The only guaranteed message order is when both the sender and the receiver are the same for both messages (first-in, first-out)

Page 36: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Selecting Unordered Messages

• Using selective receive, it is possible to choose which messages to accept, even if they arrive in a different order

Page 37: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Starting Processes

• The “spawn” function creates a new process

• The new process will run the specified function

• The spawn operation always returns immediately

• The return value is the Pid of the “child”

Page 38: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Process Termination

• A process terminates when:

• it finishes the function call that it started with

• there is an exception that is not caught

• All messages sent to a terminated process will be thrown away

• Same Pid will not be used before long time

Page 39: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

A Stateful Server

• The parameter variables of a server loop can be used to remember the current state

Page 40: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Hot Code Swapping

• When using “module:function(...)”, the latest version of module is always used

• If the server module is recompiled and reloaded, the process will jump to the new code after handling the next message

Page 41: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Registered Processes

• A process can be registered under a name

• Any process can send a message to a registered process, or look up the Pid

• The Pid might change (if the process is restarted and re-registered), but the name stays the same

Pid = spawn(?MODULE, server, []),register(myserver, Pid),myserver ! Msg.

Page 42: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Links and Exit Signals

• Any two processes can be linked

• Links are always bidirectionnal

• When a process dies, an exit signal is sent to all linked processes, which are also killed

• normal exit does not kill other processes

Page 43: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Trapping Exit Signals

• If a process sets its trap_exit flag, all signals will be caught and turned into normal messages

• process_flag(trap_exit, true)

• {‘EXIT’, Pid, ErrorTerm}

• This way, a process can watch other processes

Page 44: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Distribution

• Running “erl” with the flag “-name xxx”

• starts the Erlang network distribution system

• makes the virtual machine emulator a “node” (‘[email protected]’)

• Erlang nodes can communicate over the network (but must find each other first)

Page 45: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Connecting Nodes

• Nodes are connected the first time they try to communicate

• The function “net_adm:ping(Node)” is the easiest way to set up a connection between nodes

• returns “pong” or “pang”

• Send a message to a registered process using “{Name,Node} ! Message”

Page 46: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Distribution is Transparent

• Possible to send a Pid from one node to another (Pids are unique across nodes)

• You can send a message to any process through its Pid (even on another node)

• You can run several Erlang nodes (with different names) on the same computer

Page 47: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Running Remote Processes

• Variants of the spawn function can start processes directly on another node

• The module ‘global’ contains functions for

• registering and using named processes over the whole network of connected nodes

• setting global locks

Page 48: Introduction to Erlang - fileHello World • ‘%’ starts a comment • ‘.’ ends a declaration • Every function must be in a module • one module per source file • source

Ports: Talking to the Outside

• Talks to an external (or linked-in) C program

• A port is connected to the process that opened it

• The port sends data to the process in messages

• A process can send data to the port