Skip to content

Instantly share code, notes, and snippets.

@driv3r
Created March 11, 2019 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save driv3r/3881256a1dfbcec33a3bfa9f9b8595b8 to your computer and use it in GitHub Desktop.
Save driv3r/3881256a1dfbcec33a3bfa9f9b8595b8 to your computer and use it in GitHub Desktop.
Going functional with elixir & otp
defmodule KV do
@moduledoc """
Key value store.
## Examples
Basic usage
iex> {:ok, pid} = KV.start_link()
iex> KV.put(pid, "foo", :bar)
iex> KV.get(pid, "foo")
What if key is missing?
iex> {:ok, pid} = KV.start_link()
iex> KV.get(pid, "foo")
nil
Remember to `flush()` after yourself to see the messages ;-)
"""
def start_link do
Task.start_link(fn -> loop(%{}) end)
end
def put(pid, key, value) do
send(pid, {:put, key, value})
end
def get(pid, key) do
send(pid, {:get, key, self()})
end
defp loop(map) do
receive do
{:get, key, caller} ->
send(caller, Map.get(map, key))
loop(map)
{:put, key, value} ->
loop(Map.put(map, key, value))
end
end
end
defmodule Stack.Client do
def pop(server) do
GenServer.call(server, :pop)
end
def push(server, value) do
GenServer.cast(server, {:push, value})
end
end
defmodule Stack.Server do
use GenServer
def start_link(opts) do
GenServer.start_link(__MODULE__, :ok, opts)
end
def init(:ok) do
{:ok, []}
end
def handle_call(:pop, _from, [head | tail]) do
{:reply, head, tail}
end
def handle_cast({:push, value}, stack) do
{:noreply, [value | stack]}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment