[erlang-questions] towards a unified dict api

Richard Carlsson carlsson.richard@REDACTED
Fri Jan 13 14:57:08 CET 2012


On 01/13/2012 12:44 PM, José Valim wrote:
> I agree with the general direction of creating another module called
> gen_dict that adds a level of indirection instead of changing dict
> implementation. So developers can choose between transparency (gen_dict)
> and performance (dict).
>
> But the truth is that Erlang lacks the proper abstractions to
> (elegantly) solve this problem. Even if we create a module that properly
> wraps gb_trees, orddict and dict, if the developer decides to create a
> new dictionary (for example, a red black tree based implementation)
> there is no way the developer will be able to hook his own dictionary
> into the gen_dict API. An abstraction like Clojure's protocols would be
> able to solve this more elegantly.
>
> Tuple modules could be a possible solution to this problem, so one would
> be able to call Dict:find(Key) and not worry about what a Dict really
> is, but they wouldn't work for orddicts or gbtrees unless they are
> rewritten to be in the tuple module format and I doubt this is a
> direction people would like OTP libraries to move towards to (I
> certainly don't).

There seems to be a lot of confusion going on here between *interface* 
(API) and *dispatch* (redirecting the API calls to the actual 
implementation depending on the data structure). I have only suggested a 
unified API; not a generic dispatch mechanism.

"Tuple modules" (please call them Parameterized modules or Abstract 
modules - the implementation-as-tuples is a temporary hack, and you 
should treat them as opaque objects just like funs) are not needed, 
because there is nothing here to parameterize. If all dict-like modules 
implement the same API, it's enough to use the module's name. For example:

    MyDict = orddict,
    ...
    D = MyDict:new(),
    ...

What you *could* do is to parameterize the module that uses the dictionary:

   -module(my_module, [SomeDict]).
   ...
   foo() ->
       D = SomeDict:new(),
       ...

and then you could easily change implementation as you like:

   M1 = my_module:new(orddict),
   M1:foo(),
   M2 = my_module:new(ets),
   M2:foo(),
   ...

That said, I think Clojure's protocols (which are a way of dynamically 
getting the same effect that you get with Haskell's type classes) are a 
neat idea that would probably work well with Erlang. But that's a 
different story.

    /Richard



More information about the erlang-questions mailing list