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

> On Tue, Mar 15, 2011 at 03:30:50PM +0100, Torben Hoffmann wrote:
> >
> >      Dictionary1 = ec_gb_trees:new().
> >      Dictionary2 = ec_dict:new().
> >
> >      NewDictionary1 = Dictionary1:put(SomeKey, SomeValue).
> >      NewDictionary2 = Dictionary2:put(SomeKey, SomeValue).
>
> >    You have lost me a bit here... how would the Dictionary1 hold both a
> >    module name and a value?
>
> Its a parameterized type. ec_gb_trees:new would return the
> parameterized type. I guess I can't expect you to see whats in my head
> lol, I forget about that sometimes.
>

We have not had enough beers together to see inside each others heads... ;-)


>
> So because of limitations in parameterized types. There are two
> modules for each type. A non prameterized module used for construction
> and a parameterized module that actually provides the
> impementation. So ec_gb_trees would look like (off the top of my head,
> uncompiled and un tested).
>
> ,----
> | -module(ec_gb_trees).
> |
> | -export([new/0]).
> |
> | -spec new() -> ec_dictionary:dictionary().
> | new() ->
> |       ec_gb_trees_impl:new(gb_trees:new()).
> `----
>
> then ec_gb_trees_impl would look something like
>
> ,----
> | -module(ec_gb_trees_impl, [Data]).
> |
> | -behaviour(ec_dictionary).
> |
> | -export([get/1, put/2, ...]).
> |
> |
> | .....
> `----
>

That looks like a lot of labour, but let's look at the implementations and
their merits before passing judgement.


>
>
> >      In this case it wouldn't matter what the concrete implementation of
> >      dictionary is, as long as it implemented the ec_dictionary
> interface.
> >
> >      I have some utilities that check that a particular module implements
> >      an interface, but in general you just have to trust that that the
> >      caller is passing you the right value. Of course, thats pretty
> normal
> >      in erlang.
> >
> >    Trust it at runtime but test the hell out of it and run dialyzer like
> >    crazy.
>
> Exactly.
>
> >
> >    Well, isn't that a matter of how many layers of indirection you want?
>
> What do you mean?
>

I was rambling about how many layers one wants to put around the thing -
nothing more.
Enough talk - from now on we will let actual code decide.


>
> >    My approach adds the thinnest indirection layer by having everything
> in
> >    the same module.
> >    I like that sort of thing since it makes debugging extremely easy.
> >    Another bonus of coding it so directly as I did is that if you run
> xref on
> >    the module it will actually figure out what is going on! I have done
> some
> >    code where the module was a parameter and that puts a real stick in
> the
> >    wheel of xref.
>
> I agree on all points. However, the inability for folks to extend it
> in thier systems is just a killer for a generalized library. Using
> this approach I haven't found a way around that.
>

The extension problem is why I am now fund of your behaviour based solution!


>
> >    Another thing is dialyzer - I am not quite sure that it handles
> >    parameterized modules very well, so I would experiment with that
> before
> >    playing more with those things...
>
> I am not sure either. I think the tools in general support it much
> better then they used to. However, it is certainly worth testing to
> see where dialyzer might fall down..
>
> >
> >    The testing should not be all that affected by the chosen
> implementation
> >    so I am up for a bit of fun!
>
> sweet!
>
> >
> >      There is one major problem, I think, critical fault in this. That is
> you
> >      must know all the possible implementations at the time you are
> coding
> >      the are coding the interface. I think this is a killer for a set of
> >      types. I believe that client developers need the ability to
> implement
> >      the interface after the creation of the interface for it to be
> >      useful.
>
> >
> >      My first implementation used a similar approach. Though it auto
> called
> >      the function in the module defined by base. So your size looked
> >      something like
> >
> >      size(#my_map{base = Moule , content=C}) -> Module:size(C).
> >
> >      It retained the ability to be extended at run time, but still
> required
> >      that a wrapper be defined to implement the interface. I was coding a
> >      wrapper for assoc lists as a test when I realized I had just
> >      reinvented parametrized modules.
> >
> >    Hmmmm, I am not quite sure that I see the issue here - could you show
> me a
> >    bit of your code?
> >
> >    My approach has - as you point out - the drawback that you have to
> extend
> >    it every time you need a new base module.
> >    This you have to weigh up against benefit of giving xref, dialyzer et
> al
> >    an easier job.
> >
> >    Using your behaviour based solution one could let new return something
> >    like #my_map{} above and then let a generic wrapper module handle the
> >    operations on the data:
> >
> >    Dict1 = ec_dict:new().
> >    Dict2= gen_dict:add(1,Dict1).
> >
> >    or you could - and probably should - change the instantiation to:
> >
> >    Dict1 = gen_dict:new(dict). %% pick implementation at this point.
> >    Dict2= gen_dict:add(1,Dict1).
>
> Thats true, and doable. In this model I like that approach a lot. and
> we would retain the tools compatabliity at the expense of a bit of
> indirection.
>
> >    This might be a more Erlangish way of doing it since it uses a
> behaviour
> >    as restriction for the mapping modules and it wraps the indirection
> with a
> >    simple data structure. (It does make xref unhappy I guess, but
> dialyzer
> >    should be a happy trooper at this point.)
>
> I don't think it would affect xref for the user. For the type
> developer it would, but we would want to ensure good tests there
> anyway. In this model the user matters more.
>

Agreed.


>
> >    This might be exactly the same as using parameterized modules, so it
> would
> >    require an experiment to judge what is the cleaner way of doing it.
> >
> >    I would say that the solution that keeps most of the analysis tools
> happy
> >    is the one to go with. I have not used the tools with parameterized
> >    modules so I have no clue if it makes it a mess or not.
>
> Hmm, then it could be that my original approach is best. I have some
> decent examples of that approach already. Let me send them to the list
> and get some feedback.
>

Looking forward to that!

Cheers,
Torben
-- 
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