程序代写代做代考 Erlang kernel B tree compiler graph C html Concurrent Programming

Concurrent Programming
CS511
1/49

About Erlang
􏰟 Functional language
􏰟 Concurrent/Distributed
􏰟 No shared memory (message passing)
􏰟 No types at compile time 􏰟 Dynamically typed
􏰟 Open source
􏰟 Developed in the 80s in Ericsson by Joe Armstrong, Robert Virding and Mike Williams
2/49

Runtime System
􏰟 Compiled code runs on a virtual machine (BEAM). 􏰟 Lightweight processes
􏰟 Fast process creation
􏰟 Support hot-swapping
3/49

More About Erlang
􏰟 Open Telecom Platform (OTP) (fault-tolerance, hot code update, …)
􏰟 Practically “proven” programming patterns
􏰟 Supporting tools 􏰟 Debugger
􏰟 Unit testing 􏰟 Dialyzer
􏰟 Mnesia
4/49

Typical Applications
􏰟 Telecoms
􏰟 Switches (POTS, ATM, IP, …)
􏰟 GPRS
􏰟 SMS applications
􏰟 Internet applications
􏰟 WhatsApp (backbone)
􏰟 Facebook (chat)
􏰟 Amazon (SimpleDB, part of the Amazon Elastic Compute
Cloud)
􏰟 Yahoo! (social bookmarking service, Delicious)
􏰟 Online shopping (Klarna AB)
􏰟 T-Mobile
􏰟 Discord
􏰟 3D modelling (Wings3D)
5/49

Bibliography
􏰟 Programming Erlang: Software for a Concurrent World, Joe Armstrong
􏰟 Learn some Erlang for Great Good!, Fred Hebert
􏰟 Erlang Programming, Cesarini and Thompson
Note: Some of the material in these slides draw from the above sources
6/49

Downloading and Installing
􏰟 http://www.erlang.org/downloads
􏰟 Prepackaged binaries from https://www.
erlang-solutions.com/resources/download.html
􏰟 Setting up erlang mode in emacs+flycheck: http://www. lambdacat.com/post-modern-emacs-setup-for-erlang/
7/49

Erlang
Shell
Data Types
Modules
8/49

Running Erlang
1 $ erl
2 Erlang/OTP 19 [erts -8.0] [source -6dc93c1] [64-bit] [smp:4:4]
[async-threads:10] [hipe] [kernel-poll:false]
3
4 Eshell V8.0 (abort with ^G)
5 1> io:format(“Hello , world!~n”).
6 Hello, world!
7 ok
8 2> q().
9 ok
10 $
9/49

A Small Script
1 $ cat hello.erl
2 %% Sample module
3 -module(hello).
4 -export([hello/0]).
5 hello() -> “Hello, world!”.
6 $ erl
7 Erlang/OTP 19 [erts -8.0] [source -6dc93c1] [64-bit] [smp:4:4]
[async-threads:10] [hipe] [kernel-poll:false]
8
9 Eshell V8.0 (abort with ^G)
10 1> c(hello).
11 {ok,hello}
12 2> hello:hello().
13 “Hello , world!”
14 3> q().
Mind the dot!
10/49

Erlang
Shell
Data Types
Modules
11/49

Sequential Fragment
􏰟 Data types and variables 􏰟 Function definitions
􏰟 Pattern matching
12/49

Numbers
Integers (arbitrarily big)
1 7> fact:fact(200).
2 788657867364790503552363213932185062295135977687173263294742 3 533244359449963403342920304284011984623904177212138919638830 4 257642790242637105061926624952829931113462857270763317237396 5 988943922445621451664240254033291864131227428294853277524242 6 407573903240321257405579568660226031904170324062351700858796 7 178922222789623703897374720000000000000000000000000000000000 8 000000000000000
Floats
1 > 2.78 + 9.6.
2 12.379999999999999
􏰟 IEEE 754 de 64–bits (range: ±10308)
13/49

Atoms
1 start_with_a_lower_case_letter 2 ’Anything_inside_quotes\n\09’
􏰟 Names must begin in lowercase or between apostrophes 􏰟 Heavily used
14/49

Characters and Strings
􏰟 Characters: $a, $n. 􏰟 Strings
1 9> “hello”. 2 “hello”
􏰟 They are, in fact, a list of integers.
1 10> “hello\7”.
2 [104,101,108,108,111,7] 3 11> is_list(“hello”).
4 true
15/49

Tuples
1 {}
2 {atom, another_atom, ’PPxT’}
3 {atom, {tup, 2}, {{tup}, element}}
4 {atom, {“hello”,5}}
5
6 12> is_tuple({atom, another_atom, ’PPxT’}).
7 true
8 13> is_list({atom, another_atom, ’PPxT’}).
9 false
10 14> is_atom({atom, another_atom, ’PPxT’}).
11 false
16/49

Modeling Data
type ’a tree = Leaf of ’a | Node of (’a tree)*(’a tree)
􏰟 Atoms to indicate which constructor is used at top-level 􏰟 Tuples to collect the arguments of the constructor
􏰟 Example:
Node(Node(Leaf 3,Leaf 4), Leaf 5)
becomes
{node , {node , {leaf , 3}, {leaf , 4}}, {leaf , 5}}
17/49

Operators
􏰟 Arithmetic: +, -, *, /, div, rem
􏰟 Equal value: “==” and “/=”
􏰟 Exact equality (type and value): “=:=” and “=/=”
􏰟 Boolean: and, or, xor, not, andalso, orelse
18/49

Operator Examples
1 1> 4 2 true 3 2> 4 4 false 5 3> 1 6 true
== 4.0. =:= 4.0. =/= 0. /= 1.
% value is 4 on both sides
% value same but type different
7 4> 1
8 false
9 5> 1 =/= 1.0.
10 true.
􏰟 Use == and /=
􏰟 Switch to =:= and =/= only when you need exact equality (type and value)
19/49

Lists
1 []
2 [1, true]
3 [1 | [true] ] 4 [ok, 10]
􏰟 List concatenation: “++”
􏰟 List subtraction: “–”
􏰟 List cons: “|”
􏰟 List comprehension: [ math:log(A)|| A <- lists:seq(1,10)] 20/49 Operator and List Examples 1 3> L1 = [ apple, cherry ].
2 [apple ,cherry]
3 4> L2 = [ lime, grape ].
4 [lime,grape]
5 5> L3 = L1 ++ L2.
6 [apple,cherry,lime,grape]
7 6> L3 — [cherry].
8 [apple,lime,grape]
9 7> L4 = [ banana | L3 ].
10 [banana,apple,cherry,lime,grape]
11 8> [ Head | Tail ] = L4.
12 [banana,apple,cherry,lime,grape]
􏰟 Note: = is not assignment; it is matching
21/49

Operator and List Examples (cont.)
1 9> b(). % b() shows all bindings
2 Head = banana % Head and Tail have been bound 3 L3 = [apple,cherry,lime,grape]
4 L4 = [banana,apple,cherry,lime,grape]
5 Tail = [apple,cherry,lime,grape]
6 ok
7 10> f(). % f() flushes all bindings
8 ok
9 11> { A, B } = { 4.0, 5.2 }.
10 {4.0,5.2} 11 12> b(). 12 A = 4.0
13 B = 5.2
14 13> { C, D } = { 4.0, 5.2 }. 15 {4.0,5.2}
16 14>{A,B}=={C,D}.
17 true
18 15> { A, B } =:= { C, D }. 19 true
22/49

Comparison
􏰟 In Erlang all terms are comparable
number < atom < reference < fun < port < pid < tuple < map < nil < list < bitstring 􏰟 Integers and floats are compared as usual 􏰟 The rest are compared as indicated above 1 1> a<2. 2 false 3 2> 2 a = 3. % fails because a is not a variable 2 ** exception error: no match of right hand side value 3
32>A=3. 43 53>B=3. 63
7 4>A=B. 83
9 5>A=4.
10 ** exception error: no match of right hand side value 4
11 6> X = { hello, goodbye }. % hello & goodbye are atoms
12 {hello ,goodbye}
13 7> { Y, Z } = X.
14 {hello ,goodbye}
15 8> Y.
16 hello
17 9> Z.
18 goodbye
% notice: ends with a period
% there’s that period again
% succeeds: A and B both have value 3
% fails because A cannot be re-bound
% binds both Y and Z
25/49

More on Variables
1 10> X = {Y,Z}.
2 {hello ,goodbye}
3 11> X = {hello,Z}.
4 {hello ,goodbye}
5 12> q()
6 12> q().
7 * 2: syntax error before: q
8 13> q(). % succeeds: quits Erlang shell
9 ok
% succeeds because of value match % succeeds because of value match
% notice: forgot the period
% fails because Erlang reads “q()q().”
26/49

Functions
􏰟 May have several clauses
􏰟 Function is sequence of pattern matching clauses separated by
semicolons – semicolon means “or” 􏰟 Finish definition with .
􏰟 Function application matches arguments to pattern in some clause
1 fact (0) -> 1;
2 fact(N) when N>0 -> N * fact(N-1).
􏰟 “when …” is a clause guard
27/49

Example 1
1 arith(X, Y) ->
2 io:format(“Arguments: ~p ~p~n”, [ X, Y ]) ,
3 Sum=X+Y,
4 Diff=X-Y,
5 Prod=X*Y,
6 Quo=XdivY,
7 io:fwrite(“~p ~p ~p ~p~n”, [ Sum, Diff, Prod, Quo ]) ,
8 { Sum, Diff, Prod, Quo } .
Take note:
􏰟 Function name starts with lowercase letter 􏰟 io:format is similar to printf
􏰟 Expressions separated by comma
􏰟 Function clause ended by period
􏰟 Final expression is function’s return value
28/49

Example 2
1 2 3 4 5 6
what_day(saturday) -> weekend ;
what_day(sunday) -> weekend ;
what_day(_) -> weekday .
% “saturday” is an atom % notice semicolon
% “sunday” is an atom
% semicolon again
% underscore is “don’t care” variable % period ends function
29/49

Example 3
1 2 3 4 5 6 7 8 9
10
drivers_license(Age) when Age < 16 -> forbidden ;
drivers_license(Age) when Age == 16 -> ’learners permit’ ;
drivers_license(Age) when Age == 17 -> ’probationary license’ ;
drivers_license(Age) when Age >= 65 ->
’vision test recommended but not required’ ;
drivers_license(_) -> ’full license’.
30/49

Function Application
􏰟 Function application is call-by-value or eager
􏰟 Clause matches if function name, arguments, and all guards
match the input
􏰟 Except for “built-in functions (BIFs)” must specify function’s module when calling
1 2> drivers_license(16).
2 ** exception error: undefined shell command
drivers_license/1
3 3> example:drivers_license(16).
4 ’learners permit’
31/49

Function Application
1 1> c(example). % c() compiles
2 {ok,example}
3 2> drivers_license(16). % must specify module
4 ** exception error: undefined shell command drivers_license
/1
5 3> example:drivers_license(16). 6 ’learners permit’
7 4> example:drivers_license(15). 8 forbidden
9 5> example:drivers_license(17).
10 ’probationary license’
11 6> example:drivers_license(23).
12 ’full license’
13 7> example:drivers_license(65).
14 ’vision test recommended but not required’ 15 8> q().
16 ok
32/49

Pattern Matching
The factorial definition uses pattern matching over numbers
1 fact (0) -> 1;
2 fact(N) when N>0 -> N * fact(N-1).
􏰟 A zero number (first clause)
􏰟 A number different from zero (second clause)
A more involved example. Function area to compute the area of
different geometrical figures.
1 area({square, Side}) -> Side * Side ;
2 area({circle , Radius}) -> Radius*Radius*math:pi().
􏰟 Patterns: {square, Side} and {circle, Radius}
􏰟 {square, Side} matches {square, 4} and binds 4 to variable Side
􏰟 {circle, Radius} matches {circle, 1} and binds 1 to variable Radius
33/49

Anonymous Functions
1 11> F = fun (Y) -> Y+1 end. 2 #Fun
3 12> F(2).
43
5 13> G = fun () -> 1 end.
6 #Fun 7 14> G().
81
9 15> G.
10 #Fun
11 16> [F,G].
12 [#Fun,#Fun]
34/49

Pattern Matching (cont.)
1 {B, C, D} = {10, foo, bar}
Succeeds: binds B to 10, C to foo and D to bar
1 {A, A, B} = {abc, abc, foo} Succeeds: binds A to abc, B to foo
1 {A, A, B} = {abc, def, 123} Fails
1 [A,B,C,D] = [1,2,3] Fails
35/49

Pattern Matching (cont.)
1 [H|T]= [1,2,3,4]
Succeeds: binds H to 1, T to [2,3,4]
1 [H|T] = [abc]
Succeeds: binds H to abc, T to []
1 [H|T] = [] Fails
1 {A, _ , [ B | _ ] , {B} } = {abc,23,[22,x],{22}} Succeeds: binds A to abc, B to 22
36/49

BIFs
􏰟 Much-used modules in Erlang library: io, list, dict, sets, gb trees
􏰟 You can inspect the source code for these libraries
􏰟 Eg. snippet from /usr/local/lib/erlang/lib/stdlib-3.
0/src/lists.erl
1 %% sum(L) returns the sum of the elements in L
2 -spec sum(List) -> number() when
3 List :: [number()].
4
5 sum(L) -> sum(L, 0). 6
7 sum([H|T], Sum) -> sum(T, Sum + H);
8 sum([], Sum) -> Sum.
37/49

Erlang
Shell
Data Types
Modules
38/49

Modules
􏰟 Basic compilation unit is a module 􏰟 Module name = file name (.erl)
􏰟 They contain attributes and function definitions
􏰟 Attributes are of the form -Name(Attribute). and describe
information about the module
􏰟 Let us create the module math_examples as follows.
1 -module(math_examples).
2 -export([fact/1,area/1]).
3 -author(“E.B”).
4
5 fact (0) -> 1;
6 fact(N) when N>0 -> N * fact(N-1).
7
8 area({square , Side}) -> Side*Side ;
9 area({circle , Radius}) -> Radius*Radius*math:pi().
39/49

Modules
Running the examples.
1 1> c(math_examples).
2 {ok,math_examples}
3 2> math_examples:fact(3). 46
5 3> math_examples:area({square ,4}).
6 16
7 4> math_examples:area({circle ,1}).
8 3.141592653589793
40/49

Modules
􏰟 A useful compiler option is export_all 1 5> c(a_module ,[export_all]).
2 {ok,a_module}
􏰟 This causes the compiler to ignore the -export module
attribute and export all functions defined 􏰟 You can also do the following:
1 -module(math_examples).
2 -compile(export_all).
3 -author(“E.B”).
4
5 fact (0) -> 1;
6 fact(N) when N>0 -> N * fact(N-1).
7
8 area({square , Side}) -> Side*Side ;
9 area({circle , Radius}) -> Radius*Radius*math:pi().
41/49

Modules – Information About
1 2 3 4 5 6 7 8 9
10 11 12 13
14 15 16
1> c(math_examples). {ok,math_examples}
2> math_examples:module_info(). [{module ,math_examples},
{exports ,[{fact ,1}, {area ,1},
{module_info ,0},
{module_info ,1}]}, {attributes,[{vsn,[292229879300425682399740783243125416564]
},
{author ,”E.B”}]}, {compile ,[{options ,[]},
{version ,”7.0″},
{source ,”/Users/ebonelli/Documents/erlang/
math_examples.erl”}]}, {native ,false},
{md5,<<219,217,109,113,225,135,117,96,156,42,192,248,50, 41,98,116>>}]
42/49

Modules – Command Line
􏰟 Compilation
1 $ erlc math_examples.erl
This generates a bytecode file (i.e. .beam file) 􏰟 Execution
1 $ erl -noshell -run math_examples factLstStr 5 -run init stop
factStr consumes a list of strings and then prints the result by calling fact
43/49

Records
􏰟 Declared as module attributes Definition
-module(records). -compile(export_all).
-record(robot, {name, type=industrial, hobbies, details=[]}) .
Creation
first_robot() ->
#robot{name=”Mechatron”, type=handmade ,
details=[“Moved by a small man inside”]}.
44/49

Records are Syntactic Sugar for Tuples
Accessing record fields
1 1> c(records).
2 {ok,records}
3 2> records:first_robot().
4 {robot ,”Mechatron”,handmade ,undefined ,[“Moved
inside”]}
by a
small man
􏰟 Note above: a record is just syntactic sugar for a tuple
􏰟 That means that if we try to access a field, we’ll get an error
1 3> (records:first_robot())#robot.name.
2 * 1: record robot undefined
45/49

Accessing the Fields
We must load the record definitions first
1 3> rr(records).
2 [robot]
3 4> records:first_robot().
4 #robot{name = “Mechatron”,type = handmade,hobbies =
undefined, details = [“Moved by a small man inside”]}
1 16> (records:first_robot())#robot.name.
2 “Mechatron”
3 17> Crusher = #robot{name=”Crusher”, hobbies=[“Crushing
people”,”petting cats”]}.
4 #robot{name = “Crusher”,type = industrial ,
5 hobbies = [“Crushing people”,”petting cats”],
6 details = []}
7 18> Crusher#robot.name.
8 “Crusher”
46/49

Updating Records
1 repairman(Rob) -> Details = Rob#robot.details ,
NewRob = Rob#robot{details=[“Repaired by
2
3 repairman”|Details]}, {repaired , NewRob}.
1 16> c(records).
2 {ok,records}
3 17> records:repairman(#robot{name=”Ulbert”, hobbies=[“trying
to have feelings”]}).
4 {repaired ,#robot{name = “Ulbert”,type = industrial , hobbies
= [“trying
5 to have feelings”], details = [“Repaired by repairman”]}}
47/49

Records in Header Files
1 2 3 4
1
1
%% this is a .hrl (header) file.
-record(included , {some_field , some_default = “yeah!”, unimaginative_name}).
To include it in records.erl, add the following line to the module: -include(“records.hrl”).
And an example function
included() -> #included{some_field=”Some value”}.
48/49

Records in Header Files
1 18> c(records).
2 {ok,records}
3 19> rr(records).
4 [included ,robot ,user]
5 20> records:included().
6 #included{some_field = “Some value”,some_default = “yeah!”,
7 unimaginative_name = undefined}
49/49