Zero-cost abstraction for NewTypes in Elixir

After reading more I finally came up with a small macro that can be used as a proof of concept, a trivial implementation of the NewType in Elixir.

While it is not a zero cost abstraction, it is very lightweight and I seriously doubt anyone would run into considerable performance issues using it.

I expanded over the idea of @tomekowal and used tuples, mainly to check for type validation. I am sure there is another way of doing the same is_type?/2 function without using tuples, but I think this is fast enough and the code is clear enough, so no harm done:

defmodule NewType do
  defmacro deftype(name, type) do
    quote do
      defmodule unquote(name) do
        @opaque t :: {unquote(name), unquote(type)}

        @spec new(value :: unquote(type)) :: t
        def new(value), do: {unquote(name), value}

        @spec extract(new_type :: t) :: unquote(type)
        def extract({unquote(name), value}), do: value
      end
    end
  end

  @spec is_type?(data :: {atom, any}, new_type :: atom) :: boolean
  def is_type?({type, _data}, new_type) when type == new_type, do: true
  def is_type?(_data, _new_type), do: false
end

To see the full context:

1 Like