How to build a counter?

i am doing excise with these objective:
Based on the Calculator example, define a multiply operation taking two parameter values and return the product.

Modify the Calculator to count how many multiplications it has done for its clients.

Followings are examples of call

> GenServer.call(calc, {:mult, 4, 2})

{1, 8}

> GenServer.call(calc, {:mult, 3, 9})

{2, 27}

> GenServer.call(calc, {:mult, 11, 11})

{3, 121}

and here is what i done for now :
define a multiply operation taking two parameter values and return the product.
still left the counter part anybody know how to do it?

defmodule Calculator do
   use GenServer
      def handle_call({:mult5, n1, n2}, _from, state) do
         {:reply, n1 * n2 , state}
      end
end

here is the step to run the Calculator.exs

iex(1)> c "Calculator.exs"
iex(2)> {:ok,calc} = GenServer.start_link(Calculator, [ ])
{:ok, #PID<0.119.0>}
iex(3)> GenServer.call(calc, {:mult5, 4,2})
8

thanks

You’re going to have to store your state in a more complex data structure that can hold the counter independently from the other value, for example a map, a tuple, or a list. I get that this is a school exercise? I guess, but just a reminder: https://hexdocs.pm/elixir/GenServer.html#module-when-not-to-use-a-genserver

1 Like

so… i should add another def to count like this?

defmodule Calculator do
    use GenServer
	
  def handle_call(:increment, _from, state) do
    sum = state + 1
    {:reply, sum, sum}
  end
	
    def handle_call({:mult5, n1, n2}, _from, state) do
        {:reply, sum , n1 * n2, state}
    end
end

No, he suggested to not use a single integer as the type for state but to use a compund type.

Basically you have 2.5 options which are idiomatic.

  1. Use a tuple which contains individual values,
  2. Use a map which contains individual values in named fields,
  3. Use a proper struct instead of a freeform map.

What happened when you tried to run that code? I can tell you what the error is going to be, but probably it would be better for you to try to figure it out.

I have figured out

here is the update:

defmodule Calculator do
  use GenServer
 
  def handle_call({:mult5, n1, n2}, _from, state) do
     {:reply, {state + 1, n1 * n2}, state + 1}
  end
end
2 Likes

Yes, that works for your purpose. I assume you left out the implementation of init/1, start_link and the client function that invokes handle_call/3 for simplicity here, otherwise your code won’t work. Also, you probably want to have a way to retrieve the count, which again, maybe you just left out for simplicity. I say this for the sake of future readers that might stumble upon this trying to solve the same problem, and would find that this code does not work by itself.

Also, take @ityonemo and @NobbZ consideration about using a compound type for the state into consideration. If the counter is the only state you need to keep, your solution using an integer as the state is good enough. If you need to store more than just the count, you’ll have to switch to a compound type.