| Author: | Bob Ippolito | 
|---|---|
| Date: | August 2007 | 
| Venue: | C4[1] | 
MochiAds, MochiBot
 
A = some_atom,
B = some_atom,
A = B,
{some_atom, some_atom} = {A, B},
%% _ (underscore) matches anything
{A, _} = {some_atom, has_a_bucket},
%% Next line will fail with a bad match
A = another_atom.
case date() of
    {2007, 8, N} when N >= 10, N =< 12 ->
        c4_1;
    {2006, 10, N} when N == 20; N == 21 ->
        c4_0;
    _ ->
        not_c4
end.
<<Bits:5, _:3, _/binary>> = Binary, Padding = (8 - ((5 + Bits * 4) band 7)), <<Bits:5, 0:Bits, Width:Bits/signed, 0:Bits, Height:Bits/signed, _:Padding, FrameRate:16/little, FrameCount:16/little>> = Binary.
 
function sum(list) {
    var acc = 0;
    for (var i = 0; i < list.length; i++) {
        acc += list[i];
    }
    return acc;
}
sum([]) ->
    0;
sum([N | Rest]) ->
    %% Not a tail call.
    N + sum(Rest).
Shouldn't do this - use tail calls instead.
sum(L) ->
    sum(L, 0).
sum([], Acc) ->
    Acc;
sum([N | Rest], Acc) ->
    sum(Rest, N + Acc).
Better:
lists:sum(L)
function seq(min, max) {
    var acc = [];
    for (var i = min; i <= max; i++) {
        acc.push(i);
    }
    return acc;
}
seq(Min, Max) ->
    seq(Min, Max, []).
seq(N, Max, Acc) when N =< Max ->
    seq(1 + N, Max, [N | Acc]);
seq(_N, _Max, Acc) ->
    lists:reverse(Acc).
Better:
lists:seq(Min, Max)
-module(c4).
-export([hello_world/0]).
%% Call this with c4:hello_world().
hello_world() ->
    hello_world.
1> c(c4).
{ok,c4}
2> c4:hello_world().
hello_world
1> make:all([load]). Recompile: c4 up_to_date 2> c4:hello_world(). hello_world
-module(c4_adder). -export([start/0, loop/1, add/2]). start() -> spawn(?MODULE, loop, [0]).
add(N, Pid) ->
    Pid ! {{add, N}, self()},
    receive
        {add_result, Result} ->
            {ok, Result}
    after
         10 ->
            {error, timeout}
    end.
loop(Count) ->
    receive
        {{add, N}, Sender} ->
            Sender ! {add_result, N + Count},
            ?MODULE:loop(N + Count);
        Unknown ->
            io:format("UNKNOWN: ~p~n",
                      [Unknown]),
            ?MODULE:loop(N + Count)
    end.
1> Adder = c4_adder:start().
<0.35.0>
2> c4_adder:add(10, Adder).
{ok,10}
3> Adder ! unexpected_message.
unexpected_message
UNKNOWN: unexpected_message
4> c4_adder:add(20, Adder).
{ok,30}
1> register(my_adder, c4_adder:start()).
true
2> whereis(my_adder).
<0.35.0>
3> c4_adder:add(10, my_adder).
{ok,10}
4> exit(whereis(my_adder), kill).
true
 
$ erl -name bob@127.0.0.1 -cookie secret
1> register(adder, c4_adder:start()).
true
2> c4_adder:add(10, adder).
{ok,10}
$ erl -name alice@127.0.0.1 -cookie secret
1> c4_adder:add(10, {adder, 'bob@127.0.0.1'}).
{ok,20}
 
1> register(my_adder, c4_adder:start()).
true
2> Mon = erlang:monitor(process, my_adder).
#Ref<0.0.0.117>
3> exit(whereis(my_adder), kill).
true
4> receive Msg -> io:format("~p~n", [Msg]) end.
{'DOWN', #Ref<0.0.0.117>, process,
 {my_adder, nonode@nohost}, killed}
ok
 
-module(c4_adder_otp).
-behaviour(gen_server).
-export([start/0, add/2, stop/1]).
-export([init/1, terminate/2,
         handle_cast/2, handle_call/3]).
start() ->
    gen_server:start_link(?MODULE, 0, []).
add(N, Pid) ->
    gen_server:call(Pid, {add, N}).
stop(Pid) -> gen_server:cast(Pid, stop).
init(Count) ->
    {ok, Count}.
terminate(_Reason, _Count) ->
    ok.
handle_cast(stop, Count) ->
    {stop, normal, Count}.
handle_call({add, N}, _From, Count) ->
    {reply, N + Count, N + Count}.
1> {ok, Adder} = c4_adder_otp:start().
{ok,<0.35.0>}
2> c4_adder_otp:add(10, Adder).
10
3> c4_adder_otp:add(10, Adder).
20
4> c4_adder_otp:stop(Adder).
ok
