I would like to propose that we change the base example for GenServer. For those not familiar with it, here it is:
defmodule Stack do use GenServer # Callbacks @impl true def init(stack) do {:ok, stack} end @impl true def handle_call(:pop, _from, [head | tail]) do {:reply, head, tail} end def handle_cast({:push, element}, state) do {:noreply, [element | state]} end end These are the problems as I teach new Elixir developers OTP. First, the purpose of init is not clear. It simply returns a stack, and does not indicate that this is an opportunity to transform the input in some way: def init(stack) do {:ok, stack} end As a result, it's not clear what to use init for. Second, we don't label the state of the GenServer appropriately, and worse, we do work in the function head, making it harder for users to grasp the central ideas that GenServers carry state and offer the opportunity to transform it: def handle_call(:pop, _from, [head | tail]) do {:reply, head, tail} end As a result, it's too hard for users to understand what this does without already knowing. Third, the return tuples are not explicitly labeled, forcing the reader to work harder to understand what the tuples actually do. Summarizing the problems: - The example doesn't use init to transform the initial value to the genserver state. - The example doesn't consistently label the last argument of the two handlers. - The example does work in the "pop" function head, limiting our opportunity to label concepts. - The example doesn't explicitly label the elements of the reply and noreply tuples. I would like to propose these changes: defmodule Stack do use GenServer # Callbacks @impl true def init(string) do {:ok, String,split(string, ",", trim: true)} end @impl true def handle_call(:pop, _from, state) do [to_client | to_server] = state {:reply, head, tail} end def handle_cast({:push, element}, state) do to_server = [element | state] {:noreply, to_server} end end I don't really care whether we label the state with state or stack. I have a slight preference for state because we're labeling the genserver concept, not the domain concept. Likewise, I don't care whether we use to_server or new_genserver_state on the server side, or the to_client or to_caller to discuss the results of the reply and noreply tuples. I should also point out that we don't handle the error state and it's easy to do so. I mainly care that this example communicates with more clarity. Feedback is welcome. -bt Regards, Bruce Tate CEO Groxio, LLC. 512.799.9366 br...@grox.io grox.io -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAFXvW-5%2B3ECDYi76eENLEEfHDCyRfkNjX-A%3DHCKtxqFy%2BCATSQ%40mail.gmail.com.