John J. Camilleri
TDA383/DIT390 Concurrent Programming
HT2016 LP1
1 + 1, 2 + 2, 3 + 3.
is 6
Cannot reassign variables - they are immutable
f()
(in shell)io:fwrite("Hello\n")
c(module)
hw:hello()
hw:hello/0hw:hello(Name)
hw:hello/1% file: foo.erl
-module(foo).
-export([hw/0]).
hw() ->
Msg = "Hello world!\n",
io:fwrite(Msg).
{atom,"string",123}
hw:greeting/1
hw:greeting({human,Name,Surname,Age})
hw:greeting({dog,Name,Age})
hw:greeting(Default)
P1 = {human, "John", "Camilleri", 30},
P2 = {dog, "Fluffy", 3},
% Age = 17, % enabling this leads to no match
case P1 of
{human, _, _, Age} -> Age ;
{dog, _, Age} -> Age * 7 ;
_ -> unknown_age
end.
if
Age > 18 -> adult ;
Age > 0 -> minor ;
true -> invalid_age
end.
[atom,"string",123]
[H|T] = [1,2,3,4]
[H|T] = "kittens"
hd([1,2,3]) = 1
tl([1,2,3]) = [2,3]
io:fwrite("~p\n", [ hd("fluffy") ])
→ 102io:fwrite("~c\n", [ hd("fluffy") ])
→ fio:fwrite("~s\n", [ hd("fluffy") ])
→ bad argumentX = 5, Y = 10, io:fwrite("The sum of ~p and ~p is ~p\n", [ X, Y, X+Y ]).
sum([X1,X2,X3,X4]) == X1 + X2 + X3 + X4
sum([X1,X2,X3,X4]) == X1 + (X2 + X3 + X4)
sum([X1,X2,X3,X4]) == X1 + sum([X2,X3,X4])
sum([]) == 0; % base case
sum([X1|XS]) == X1 + sum(XS). %recursive case
[X*2 || X <- [1,2,3,4,5]]
→ [2,4,6,8,10][X*2 || X <- [1,2,3,4,5], X > 2]
→ [6,8,10]erlang
dbl(X) -> X * 2.
erlang
apply_twice(Fun, X) ->
Once = Fun(X),
Twice = Fun(Once),
Twice.
dbl
function into apply_twice
:
erlang
apply_twice(fun dbl/1, 2) == 8.
Define apply_n
, then redefine apply_twice
in terms of it:
apply_n(0, _, X) -> X ;
apply_n(N, Fun, X) -> apply_n(N-1, Fun, Fun(X)).
apply_twice(Fun, X) -> apply_n(2, Fun, X).
erlang
apply_n(3, fun(X) -> X / 2 end, 10) == 1.25.
lists
module quite recent)lists:map(Fun, List1) -> List2
lists:foreach(Fun, List) -> ok
lists:seq(1,5)
. Use in foreach or comprehension!In each case, say what the return value of the given expression will be.
class Counter implements Runnable {
private int x = 0;
public void run () {
x++;
}
public static void main (String[] args) {
Counter c = new Counter();
(new Thread(c, "thread1")).start();
(new Thread(c, "thread2")).start();
}
}
spawn(foo, hw, [])
spawn(fun() -> ... end)
spawn(fun() -> timer:sleep(2000), io:fwrite("Done\n") end)
Converting from string: list_to_pid("<0.57.0>")
Spawn 5 functions
[spawn(fun() -> io:fwrite("I got the value ~p ~n", [X]) end) || X <- lists:seq(1,5)]
spawn(fun() ->
receive
X -> io:fwrite("I received: ~p~n", [X])
end
end).
i()
erlang:processes/0
and erlang:process_info/1
Pid ! "hello"
Pid ! {message, "Hello"}
Pid ! [1,4,8]
Pid ! fun(X) -> X*X end
receive
{greet, Name} -> "Hello " ++ Name ;
{function, Fun, Args} -> apply(Fun, Args) ;
X -> io:fwrite("I received: ~p~n", [X])
end.
Msg = receive ... end,
io:fwrite(Msg)
recv() ->
receive
...
end,
recv().
self()
recv() ->
receive
{Pid, greet, Name} -> Pid ! "Hello "++Name ;
{Pid, function, Fun, Args} -> Pid ! apply(Fun, Args) ;
_ -> skip
end,
recv().
Pid ! {self(), greet, "everyone"},
io:fwrite("Request sent~n"),
receive
X -> io:fwrite("Server response: ~p~n", [X])
end
process_info(self(), messages)
process_info(self(), message_queue_len)
self() ! foo,
self() ! bar,
process_info(self(), messages),
receive X -> X end,
X,
receive X -> X end. % this blocks even though there's a message waiting
recv(N) ->
receive
...
end,
io:fwrite("Server has handled a total of ~p requests~n", [N+1]),
recv(N+1).
spawn(foo, recv, [0]). % 0 = initial value of server's state