MapSet on steroids

226 views
Skip to first unread message

Andrea Leopardi

unread,
Oct 26, 2015, 8:17:52 AM10/26/15
to elixir-lang-core
I love the new MapSet and even more I love its implementation which is very concise, leveraging all the functions that Elixir (Erlang) has for maps. For obvious reasons, elements in a MapSet are keys in the map and values in that map are just nils. This makes sense.

However, I often found myself wanting a more flexible set implementation where elements wouldn't be compared by === but by a provided function instead (comparing f(el1) === f(el2)). Maybe I'm missing an obvious reason why this isn't a good idea, but we could implement such a set type very very easily: we would just leverage the concept behind MapSet, but the map wouldn't have elements as keys and nils as values. It would instead have f(element) as keys and element as values. MapSet would be implemented trivially on top of this (f = fn(el) -> el end) or could be left as is for performance reasons (all keys to nil?).

What does the Elixir community thinks?

Myron Marston

unread,
Oct 26, 2015, 9:41:37 PM10/26/15
to elixir-lang-core

I think such a change would lead to a MapSet that would no longer act like a set. Consider, for example:


set = MapSet.new(fn string -> String.length(string) end) |> MapSet.put("foo") |> MapSet.put("bar")


With such a set, only one of MapSet.member?(set, "foo") or MapSet.member?(set, "bar") could return true (and it’s not clear to me which one would) but an invariant of sets is that set |> MapSet.put(val) |> MapSet.member?(val) should return true for any val.


Using a set that doesn’t act like a set would be confusing, so I think you’d be better off writing your own abstraction that provides the functionality you need on top of Map.

Reply all
Reply to author
Forward
0 new messages