From 73653f078ed55f136a8af1ee4140ca2667189e25 Mon Sep 17 00:00:00 2001 From: Braeden Sowinski Date: Tue, 20 Oct 2026 11:28:07 -0700 Subject: [PATCH] lecture 07 --- .gitignore | 1 + lectures/07/arith.erl | 28 ++++++++++++++++++ lectures/07/counter.erl | 23 +++++++++++++++ lectures/07/counter_supervisor.erl | 14 +++++++++ lectures/07/counter_worker.erl | 30 +++++++++++++++++++ lectures/07/echo.erl | 22 ++++++++++++++ lectures/07/lec7.erl | 47 ++++++++++++++++++++++++++++++ 7 files changed, 165 insertions(+) create mode 100644 .gitignore create mode 100644 lectures/07/arith.erl create mode 100644 lectures/07/counter.erl create mode 100644 lectures/07/counter_supervisor.erl create mode 100644 lectures/07/counter_worker.erl create mode 100644 lectures/07/echo.erl create mode 100644 lectures/07/lec7.erl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..17278c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.beam diff --git a/lectures/07/arith.erl b/lectures/07/arith.erl new file mode 100644 index 0000000..febf9ea --- /dev/null +++ b/lectures/07/arith.erl @@ -0,0 +1,28 @@ +-module(arith). +-export([start/0, square/2, sqrt/2]). + +start() -> + {ok, _Pid} = spawn(fun loop/0). + +square(Pid, N) -> + Pid ! {square, self(), N}, + receive + {Pid, Reply} -> Reply + end. + +sqrt(Pid, N) -> + Pid ! {sqrt, self(), N}, + receive + {Pid, Reply} -> Reply + end. + +loop() -> + receive + {square, From, N} -> + From ! {self(), N * N}; + {sqrt, From, N} when N < 0 -> + From ! {self(), error}; + {sqrt, From, N} -> + From ! {self(), math:sqrt(N)} + end, + loop(). diff --git a/lectures/07/counter.erl b/lectures/07/counter.erl new file mode 100644 index 0000000..445e557 --- /dev/null +++ b/lectures/07/counter.erl @@ -0,0 +1,23 @@ +-module(conuter). +-behaviour(gen_server). +-export([init/1, handle_cast/2, handle_call/3]). +-export([start/1, value/1, inc/1, inc/2]). + +start(N) -> + gen_server.start(?MODULE, N, []). + +inc(Pid) -> inc(Pid, 1). +inc(Pid, Amt) -> + gen_server:cast(Pid, {inc, Amt}). + +value(Pid) -> + gen_server:call(Pid, value). + +init(N) -> + {ok, N}. + +handle_call(value, _From, N) -> + {reply, N, N}. % {reply, actual_reply, state} + +handle_cast({inc, Amt}, N) -> + {noreply, N + Amt}. diff --git a/lectures/07/counter_supervisor.erl b/lectures/07/counter_supervisor.erl new file mode 100644 index 0000000..37ab5a7 --- /dev/null +++ b/lectures/07/counter_supervisor.erl @@ -0,0 +1,14 @@ +-module(counter_supervisor). +-behaviour(supervisor). +-export([start_link/0, init/1]). +-define(TABLE, counter_table). + +start_link() -> + ets:new(?TABLE, [named_table, public]), + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +init(_) -> + Flags = #{strategy => one_for_one}, + ChildSpecs = [#{id => worker1, + staart => {counter_worker, start_link, [0]}}], + {ok, {Flags, ChildSpecs}}. diff --git a/lectures/07/counter_worker.erl b/lectures/07/counter_worker.erl new file mode 100644 index 0000000..fe7a53b --- /dev/null +++ b/lectures/07/counter_worker.erl @@ -0,0 +1,30 @@ +-module(counter_worker). +-behaviour(gen_server). +-export([init/1, handle_call/3, handle_cast/2]). +-export([start_link/1, inc/1, value/0]). +-define(SERVER, ?MODULE). +-define(TABLE, counter_table). + +start_link(N) -> + gen_server:start_link({local, ?SERVER}, ?MODULE, N, []). + +inc(Amt) -> + gen_server:cast(?SERVER, {inc, Amt}). + +value() -> + gen_server:call(?SERVER, value). + +init(N) -> + case ets:lookup(?TABLE, value) of + [] -> {ok, N}; + [{_, M} | _] -> {ok, M} + end. + +handle_call(value, _From, N) -> + {reply, N, N}. % {reply, actual_reply, state} + +handle_cast({inc, Amt}, N) -> + {noreply, N + Amt}. + +termintate(_Reason, N) -> + ets:insert(?TABLE, {value, N}). diff --git a/lectures/07/echo.erl b/lectures/07/echo.erl new file mode 100644 index 0000000..aeb32da --- /dev/null +++ b/lectures/07/echo.erl @@ -0,0 +1,22 @@ +-module(echo). +-export([start/1]). + +start(Port) -> + Opts = [binary, {active, once}, {packet, line}, {reuseaddr, true}], + {ok, Listen} = gen_tcp:listen(Port, Opts), + accept(Listen). + +accept(Listen) -> + {ok, Socket} = gen_tcp:accept(Listen), + spawn(fun() -> accept(Listen) end), + loop(Socket). + +loop(Socket) -> + receive + {tcp, Socket, Data} -> + inet:setopts(Socket, [{active, once}]), + gen_tcp:send(Socket, Data), + loop(Socket); + {tcp_closed, Socket} -> + gen_tcp:close(Socket) + end. diff --git a/lectures/07/lec7.erl b/lectures/07/lec7.erl new file mode 100644 index 0000000..f42c94f --- /dev/null +++ b/lectures/07/lec7.erl @@ -0,0 +1,47 @@ +-module(lec7). +-export([fact/1, qsort/1, fizzbuzz/1, dedup/1]). + +fact(N) when N =< 0 -> 1; +fact(N) -> N fact(N - 1). + +qsort([]) -> []; +qsort([H | T]) -> + qsort([X || X <- T, X =< H]) ++ [H] ++ qsort([X || X <- T, X > H]). + +fizzbuzz(N) -> fizzbuzz(1, N); +fizzbuzz(I, N) when I > N -> ok; +fizzbuzz(I, N) -> + % ~n is newline in erlang, not \n + if + I rem 15 == 0 -> io.format("fizzbuzz~n"); + I rem 5 == 0 -> io.format("buzz~n"); + I rem 3 == 0 -> io.format("fizz~n"); + true -> io.format("~p~n", [I]) + end, + fizzbuzz(I + 1, N). + +dedup([]) -> []; +dedup([X, X | R]) -> dedup([X|R]); +dedup([X|R]) -> [X | dedup(R)]. + +dedup2(L) -> + case L of + [] -> []; + [X, X | R] -> dedup2([X|R]); + [X | R] -> [X | dedup2(R)] + end. + +% compile +% c(lec7) +% lec7:fact(100) +% lec7:qsort([3,2,7,6,8]) + +F = fun(X) -> X * X end. +lists:map(F, [1,3,2]). +lists:map(fun string:length/1, ["hello", "goodbye"]). + +% accessing maps + +M = #{"bart" => 77, "homer" => 25}. +#{"homer" := X} = M. +X.