by Example

Process Messaging

Processes in Erlang share no memory, hence they
communicate via message passing.

Each process has a mailbox. The `receive` block allows
a process to do something with the messages in its mailbox.

A process can receive different kinds of messages, then
act on them.

To send a message to a process, use the `!` operator,
preceded by the process id you want to send the message to.

How does a process handle received messages?

When a process receives a message, the message is
appended to the mailbox.

The receive block will try each message in the mailbox (one
by one), against that block's sequence of patterns, until
one of the messages matches a pattern.

When there is match, the message gets removed from
the mailbox and the logic corresponding to the matched pattern
will get executed. If there is no match,
then that message remains in the mailbox, and the following
message gets tried sequentially,
against all of the receive block's patterns.

If no messages in the mailbox match any pattern, the process,
having tried all messages, and having exhausted all receive
patterns, will get suspended until a new message arrives,
and the message processing logic starts all over,
beginning with the first message in the mailbox.
-module (send_recv).

serve() ->
        Request ->
            io:format("Handling: ~s~n", [Request]),

math() ->
        {add, X, Y} ->
            io:format("~p + ~p = ~p~n", [X,Y,X+Y]),
        {sub, X, Y} ->
            io:format("~p - ~p = ~p~n", [X,Y,X-Y]),

make_request(ServerId, Msg) ->
    ServerId ! Msg.

run() ->
    Pid = spawn(?MODULE, serve, []),
    make_request(Pid, request1),
    make_request(Pid, request2),


    Pid2 = spawn(?MODULE, math, []),
    Pid2 ! {add, 1, 2},
    Pid2 ! {sub, 3, 2},

1> c(send_recv).
2> send_recv:run().
Handling: request1
Handling: request2
1 + 2 = 3
3 - 2 = 1