Skip to content

Instantly share code, notes, and snippets.

@uri
Last active October 30, 2017 14:12
Show Gist options
  • Save uri/93f95ab98c8cb605122e3815b67863c1 to your computer and use it in GitHub Desktop.
Save uri/93f95ab98c8cb605122e3815b67863c1 to your computer and use it in GitHub Desktop.
Two implementations of a stack in Elixir; one using GenServer and the other with send, receive, and pids.
defmodule StackGenServer do
use GenServer
def start, do: GenServer.start(__MODULE__, [], name: __MODULE__)
def query, do: GenServer.call(__MODULE__, :query)
def pop, do: GenServer.call(__MODULE__, :pop)
def push(element), do: GenServer.call(__MODULE__, { :push, element })
def handle_call(:query, _from, stack), do: {:reply, stack, stack}
def handle_call(:pop, _from, [h|t]), do: {:reply, h, t}
def handle_call(:pop, _from, []), do: {:reply, nil, []}
def handle_call({ :push, element }, _from, stack), do: {:reply, [element | stack], [element | stack]}
end
defmodule StackPid do
def start state do
spawn fn ->
handle state
end
end
def query pid do
send pid, { :query, self }
receive do
{:reply, stack} -> stack
end
end
def push pid, element do
send pid, { {:push, element}, self }
receive do
{:reply, current_stack} -> current_stack
end
end
def pop pid do
send pid, { :pop, self }
receive do
{:reply, element} -> element
{:error, _msg} -> nil
end
end
defp handle current_state do
receive do
{ {:push, element}, from } -> reply_push element, from, current_state
{ :pop, from } ->
if current_state == [] do
send from, {:error, "Stack is empty."}
handle []
else
reply_pop from, current_state
end
{ :query, from } -> reply_query from, current_state
end
end
defp reply_query from, current_state do
send from, {:reply, current_state }
handle current_state
end
defp reply_pop from, [h|t] do
send from, {:reply, h}
handle t
end
defp reply_push element, from, current_state do
new_state = [ element | current_state ]
send from, {:reply, new_state}
handle new_state
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment