Skip to content

Instantly share code, notes, and snippets.

@bdanklin
Last active January 10, 2023 23:59
Show Gist options
  • Save bdanklin/f4fc015fa90e9b33bb8cb580344e1258 to your computer and use it in GitHub Desktop.
Save bdanklin/f4fc015fa90e9b33bb8cb580344e1258 to your computer and use it in GitHub Desktop.

MapSet

Mapsets are said to be the “go-to” set structure in Elixir, yet they offer none of the pattern match beauty afforded to our other base data structures Maps, Lists and Tuples. I assert that this is the main reason they are under utilized, and often overlooked.

What could sets look like if they had those features?

iex> %[]
%[]

iex> enum = [:foo, :bar, "set"]
...> set = %[enum]
...> set
%[:foo, :bar, "set"]
iex> set = %[:foo, :bar, "set"]
...> %[set | :foo] # no-op
%[:foo, :bar, "set"]

iex> %[set | :foo, :buzz, %Bang{}]
%[:foo, :bar, "set", :buzz, %Bang{}]

iex> %[set | set]
%[:foo, :bar, "set", %[:foo, :bar, "set"]]
iex> term = [%Bang{}, :foo]
...> %[term | set]
%[:foo, :bar, %Bang{}, "set"]

iex> Enum.into(term, set)
%[:foo, :bar, %Bang{}, "set"]
iex> def function_1(%[]), do: :match
...> def function_1(_), do: :error
...> %[:foo, :bar, "set"]
...> |> function_1()
:match

iex> def function_2(%[:foo]), do: :match
...> def function_2(_), do: :no_match
...> %[:foo, :bar]
...> |> function_2()
:match

iex> %[:bar]
...> |> function_2()
:no_match

iex> def function_3(%[:foo, %User{} = user]), do: user.id
...> %[:foo, %User{id: 1}]
...> |> function()
1

Why?

Mapsets feel incomplete. Aesthetics matter, and this would bring MapSets in line with our other data structures.

Why not?

Some comments when this was brought up are below

Mapset is just a map under the skin.

Does that matter? A range also has this trait but has at least some of these affordances mentioned.

Because you cannot create a type in Erlang.

Do we need to? Can the elixir compiler convert %[:foo] into %{map: %{:foo => []}}?

Where to next?

I am happy to work on this if its a desired feature. Any and all direction is welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment