Skip to content

Internal Representation #16

@OvermindDL1

Description

@OvermindDL1

Right now the internal representation of prod/sum types are structs, however these are not as efficiently matched in the BEAM as raw tuples are (especially since OTP 20 made matching on an atom in the first position of a tuple significantly faster). Have you thought about having the internal representation of sum/prod types be records (I.E. tagged tuples), so something like:

defmodule Light do
  defsum do
    defdata Red    :: none()
    defdata Yellow :: none()
    defdata Green  :: none()
    defdata Custom do
      red   :: non_neg_integer()
      green :: non_neg_integer()
      blue  :: non_neg_integer()
    end
  end
end

Would become basically:

:Red
:Yellow
:Green
{:Custom, red, green, blue}

Or maybe even (slightly slower and more GC work but barely):

{:Red}
{:Yellow}
{:Green}
{:Custom, red, green, blue}

Or perhaps an option on the defsum/defdata to choose the internal representation?

A big bonus with this format is that you could then create guards, so you could have something like:

def myfunc(light) when Light.is(light), do: :blah

def is_specific_light(light) when Light.is(light, [Red, Yellow, Green]), do: true
def is_specific_light(light) when Light.is(light, Custom), do: false

And other such things? Currently it is not possible to do dynamic matching like that on a map/struct without controlling both the matcher and the guard (the best you can do is matching if it is a 'single' type, not one of a set of types, if you have the internal representation as a map/struct), since you can use elem/2 (and tuple_size/1) in a guard to test (make sure to test non-tuple representations first then test via elem as later guards will not run if elem is used when it is not a tuple, or it does not matter if all internal representations are as a tuple. The BEAM is tuned for speed on matching tuples, not maps, and that includes what can be tested in guards as well. :-)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions