Simple Memoization in Elixir (Using FastGlobal)

Elixir is a functional language, where modules can’t have “state”. State can only be wrapped in processes, and this seems a bit weird to people coming from an OOP background and can be a bit of hassle when all you need to do is quickly memoize something in your code.

If you don’t need something fancy, you could write up a simple module that handles it for you. I’ve done that here using FastGlobal, but you could just as easily use ETS if you don’t want any external dependencies. If you want something much more powerful, I highly recommend you check out the memoize package.

First add it to your dependencies:

1
2
3
  defp deps do
    [{:fastglobal, "~> 1.0"}]
  end

and add this module:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
defmodule Memoize do
  @moduledoc """
  Simple memoization helper built on top of FastGlobal.
  """



  @doc """
  If previously saved value exists, return that else
  perform memoization for given key and function.
  """
  def run(key, fun) when is_atom(key) do
    case get!(key) do
      nil ->
        value = fun.()
        put!(key, value)
        value

      result ->
        result
    end
  end


  @doc "Force get value"
  defdelegate get!(key),        to: FastGlobal, as: :get

  @doc "Force put value"
  defdelegate put!(key, value), to: FastGlobal, as: :put

end

To use it simply call the Memoize.run method:

1
2
3
4
5
def my_method do
  Memoize.run :my_method, fn ->
    # return something
  end
end

Find updates to this on Github.