Hi,

First: great initiative, but not a small one...

I doubt that parameterized modules will be the right solution to this
problem.
Note: I have nothing against parameterized modules, I just don't think they
are the right tool for this job.

Your problem: common interface to the key-value stores provided by Erlang so
that you can easily change the implementation by changing the initialisation
to use a different background module.

This is what OO dudes do with inheritance. And that can be pretty cool when
done by a good OO-programmer.

Parameterized modules is more like a poor-mans implementation of functors in
SML. Functors are cool, but in practice you tend to avoid the hazzle... at
least I do.

If you have a bunch of modules that all have the same API then it makes
sense to use the parameterized module.

In this case you are facing a wide variety of APIs (this has been on the eq
mailing list numerous times) so you would gain next to nothing by using
parameterized modules since you would have to add exceptions to the code
depending on what base module you are using.

Since the code has to deal with different APIs I would make a regular module
called gen_dict (or gen_map or ...) with the following API (fill out the
blanks...):

-opaque gen_map() :: #my_map{}.

-spec new(base_module()) -> gen_map().
new(dict) -> #my_map{base=dict,content=dict:new()};
new(lists) -> #my_map{base=lists,content=[]}.

-spec size(gen_map()) ->  non_neg_integer().
size(#my_map{base=dict,content=C}) -> dict:size(C);
size(#my_map{base=lists,content=C}) -> length(C).

And I would probably test the implementation with PropEr (
https://github.com/manopapad/proper) to make sure it really works. I can
write the test specificaction for you if you want to take that route since I
have used QuickCheck at work quite a lot (see EUC 2010 for the outcome).

The same thing can be done for sets.

But if you have found some clever way to avoid the branching out on base
module then I would be very interested in seeing that!

Cheers,
Torben

On Tue, Mar 15, 2011 at 02:49, Eric Merritt <[email protected]> wrote:

> >
> > Isn't this just another implementation of a dictionary?
> > Aren't there enough of those in stdlib?
>
> I guess I wasn't clear. I have no interest at all in implementing a
> dict. We have half a dozen different key value style stores in various
> libraries distributed with erlang. My goal is to provide a common
> interface to those implementations. I have a ton of places I just care
> to take a 'map' and don't care about the actual implementation. I want
> to support that use case instead of specializing on gb_trees, or dict
> or what have you.
>
> > How is this better?
>
> Its not better, simply a common interface to these types.
>
> > At least use the same functions names as in the dict API for similar
> > functions.
> >
> > Is the set() type in the specs the same as stdlib:set() or are You
> > defining Your own.
>
> sets:set() in stdlib is a specific implementation of a set. I am not
> planning on defining sets.
>
> > I am not that happy with the name map. Since it seems to be the
> > same thing as what is normally called dictionaries in Erlang I
> > think it would be better to use that. Or relation since that is what it
> > is in a mathematical sense.
>
> That seems reasonable to me, I think dictionary is probably best
> though its a bit more typing. Relation is more correct but I think its
> probably less intuitive.
>
> > Also map is, at least for me, to to closely coupled to the higher order
> > function. I suspect that before the week is over You are going to add
> > the function map/2 and that will just look silly map:map(Fun,Map).
>
> Yes I agree in this case. That particular name collision bothered me
> as well. This why its good to ask for comments ;)
>
> > See more inline below.
> >
> > /Anders
> >
> >>
> >> -opaque map(_KeyT, _ValueT) :: term().
> >>
> >> %% @doc empties the map.
> >> -spec clear() -> map().
> >>
> >
> > Shouldn't this be
> > -spec new() -> map() instead?
> > Or is this really a mutable datatype?
> > In which case I suppose it should be
> > -spec clear(map()) -> map()
> > Or is it just me not understanding parameterized modules?
>
> Semantically its exactly the same. Its probably worth just having new,
> and discarding clear sense it is less meaningful in a language without
> mutation.
>
> >> %% @doc returns a boolean indicating if this map has the specified key
> >> -spec has(term()) -> boolean().
> >
> > Should be has_key
>
> Probably to be clear what it actually does.
>
> >
> >>
> >> %% @doc check to see if the specified value exists in the map
> >> -spec has_value(Term()) -> boolean().
> >>
> >> %% @doc return the key value pairs as a set of {key, value} pairs
> >> -spec as_set() -> set().
> >>
> >> %% @doc get the item from the may
> >> -spec get(term()) -> term().
> >>
> > define types
> > key() = term()
> > value() = term()
> > -spec get(key()) -> value().
>
> Ok, good idea.
>
>
> >> %% @doc return all keys in the map as a set
> >> -spec keys(term()) -> set().
> >
> > What is the parameter here?
>
> lol, nothing. A fat finger on my part.
>
> >>
> >> %% @doc Add a value to the map
> >> -spec put(term(), term()) -> map().
> >
> > -spec add(term(), term()) -> map().
> > To match remove
> >
> >>
> >> %% @doc remove a value from the map
> >> -spec remove(term()) -> map().
> >>
> >> %% @doc get the current number of key value pairs in the map
> >> -spec size() -> number().
> >
> > integer() instead of number()
>
> ok. also good recommendation. I will, post a new spec tomorrow along
> with the interface and implementation.
>
> >>
> >> %% @doc get all the values in the map as a sequence
> >> -spec values() -> sequence().
> >>
> >> As you can tell from the specs I am going to define sets and sequences
> >> very quickly as well.
> >>
> >> --
> >> Eric Merritt
> >> Erlang & OTP in Action (Manning) http://manning.com/logan
> >> http://twitter.com/ericbmerritt
> >> http://erlware.org
> >>
> >> --
> >> You received this message because you are subscribed to the Google
> Groups "erlware-dev" group.
> >> To post to this group, send email to [email protected].
> >> To unsubscribe from this group, send email to
> [email protected].
> >> For more options, visit this group at
> http://groups.google.com/group/erlware-dev?hl=en.
> >>
> >>
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> "erlware-dev" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> [email protected].
> > For more options, visit this group at
> http://groups.google.com/group/erlware-dev?hl=en.
> >
> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "erlware-dev" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/erlware-dev?hl=en.
>
>


-- 
http://www.linkedin.com/in/torbenhoffmann

-- 
You received this message because you are subscribed to the Google Groups 
"erlware-dev" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/erlware-dev?hl=en.

Reply via email to