Skip to content

Instantly share code, notes, and snippets.

@dnet
Created January 22, 2014 22:10
Show Gist options
  • Save dnet/8568440 to your computer and use it in GitHub Desktop.
Save dnet/8568440 to your computer and use it in GitHub Desktop.
Test module created on an Erlang workshop for HSBXL https://hackerspace.be/Erlang-workshop
-module(test).
-export([foo/1, proc/0, price/1]).
-export([init_queue/0, queue_server/1, srv_enqueue/2, srv_dequeue/1]).
%% A function that returns a function, demonstrating that functions are
%% first-class citizens in the Erlang world.
%%
%% Example:
%% > SixMultiplier = test:foo(6).
%% #Fun<test.0.23908741>
%% > SixMultiplier(7).
%% 42
%%
foo(X) ->
fun (Y) -> X * Y end.
%% Beer is 5 euros, wine is 4, and everything represented as a string
%% (list) costs 10. This demonstrates pattern matchin in function heads.
%%
%% Example:
%% > test:price("Club-Mate").
%% 10
%% > test:price(beer).
%% 5
%% > test:price(vodka).
%% ** exception error: no function clause matching test:price(vodka) (test.erl, line 8)
price(Str) when is_list(Str) -> 10;
price(beer) -> 5;
price(wine) -> 4.
%% A simple process body that prints values sent to it in messages.
%%
%% Example:
%% > P = spawn(test, proc, []).
%% <0.47.0>
%% > P ! {print, foo}.
%% foo
%% {print,foo}
%% > P ! {print, 5}.
%% 5
%% {print,5}
proc() ->
receive
{print, X} -> io:format("~p\n", [X]), proc();
quit -> quit
end.
%% A simple queue server that uses a plain list, so enqueueing is
%% performed in O(1), while dequeueing costs O(n).
%%
%% Example:
%% > Q = test:init_queue().
%% <0.63.0>
%% > test:srv_enqueue(first, Q).
%% ok
%% > test:srv_enqueue(2, Q).
%% ok
%% > test:srv_dequeue(Q).
%% first
%% > test:srv_dequeue(Q).
%% 2
init_queue() -> % insert node@host before the first parameter to spawn on another node
spawn(?MODULE, queue_server, [new_queue()]).
queue_server(Queue) -> % this is the infinitely tail-recursive server process body
receive
{en, Item} -> queue_server(enqueue(Item, Queue));
{de, Pid} ->
{Item, NewQueue} = dequeue(Queue),
Pid ! Item,
queue_server(NewQueue)
end.
%% These are the procedural API to hide the message passing internals
srv_enqueue(Item, Queue) -> Queue ! {en, Item}, ok.
srv_dequeue(Queue) ->
Queue ! {de, self()},
receive Item -> Item end.
%% These are the internal calls, hence not exported
new_queue() -> [].
enqueue(Item, Queue) -> [Item | Queue]. % O(1)
dequeue(Queue) -> % 2 * O(n) + O(1) = O(n)
[Last | Rest] = lists:reverse(Queue),
{Last, lists:reverse(Rest)}.
@gratefulfrog
Copy link

Hi!
Thanks for the workshop and the code.
Could you show how to create a second node and address it also please?
Thanks,
Bob

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment