[erlang-questions] Parameterized module idioms

Garrett Smith g@REDACTED
Sat Apr 17 03:34:58 CEST 2010


On Fri, Apr 16, 2010 at 8:04 PM, Bob Ippolito <bob@REDACTED> wrote:
> On Fri, Apr 16, 2010 at 5:13 PM, Fred Hebert <mononcqc@REDACTED> wrote:
>> On Fri, Apr 16, 2010 at 8:06 PM, Bob Ippolito <bob@REDACTED> wrote:
>>>
>>> Technically speaking the difference is:
>>>
>>> E:echo("hello") vs. some_module:echo(E, "hello")
>>>
>>> The biggest reason I've seen to use parameterized modules is that you
>>> could have a different module that implements the same interface, e.g.
>>> sets and gb_sets and you could change which one you're using without
>>> changing any of the code that consumes it.
>>>
>>> I would definitely change the original code to use two modules, one
>>> module to do the start_link stuff, and another module to actually
>>> implement the interface.
>>>
>> M = sets,
>> D = M:new().
>> M:add_element(10, D).
>>
>> This works as well without a problem. Switch the value of M and if the
>> interface is the same, nothing changes.
>
> Yes, but now you're passing around two variables instead of one.

I'd be tempted to create a wrapper that took the impl module in its
new function and maintained it as internal state.

-module(gen_dict).

-define(state, {impl, impl_state}).

new(Impl) ->
    #state{impl=Impl, impl_state=Impl:new()}.

store(Key, Val, #state{impl=Impl, impl_state=ImplState}=S) ->
    S#state{impl_state=Impl:store(Key, Val, ImplState)}.

... and so on...

And to use (obviously):

D = gen_dict:new(dict),
D2 = gen_dict:store(foo, bar, D)

Granted, there's a fair amount of horsing around, but not terrible.
And your generic API is explicit.

Behaviors should work for this as well as they just enforce an exported API.

Garrett


More information about the erlang-questions mailing list