Will parameterized modules become an official part of Erlang?
John Hughes
john.hughes@REDACTED
Tue Feb 23 16:18:22 CET 2010
There is one thing I don't understand here. For a gen_server or
gen_fsm why can't you just put the module parameters, or there values
at least, into the state parameter the gen_server passes around for
you. I don't feel it would be so much more difficult to use that it
would warrant a whole new feature. And it would allow you to change
it.
Of course I may have missed something here,
Robert
Hmmm.
Well, I'm really thinking of our eqc_statem module. That also passes a state around for you, just as gen_server does. But it also initialises the state for you, using an initial_state() callback in your module. It's that initialisation that's the problem--if only you could make the initial_state() callback return a state containing your module parameters, then you'd be fine... but you can't, or at least I can't think how to without using side-effects in some form. Actually, we have another way of setting the initial state which WOULD enable one to get those parameters in there... but QuickCheck users would need to actually do this explicitly, which would complicate the interface somewhat.
Then again I don't WANT to complicate the state with internal QuickCheck information (because users see it).
So I guess one could make this idea work, but it wouldn't be as smooth to use as the solution based on parameterized modules.
John
On 23 February 2010 14:55, John Hughes <john.hughes@REDACTED> wrote:
>
>
>>> The reason is that we need to supply a call-back module implementing a
>>> behaviour to a generic module like gen_server or gen_fsm, and the
>>> callback
>>> module needs access to parameters that aren't fixed. So we use a
>>> parameterised call-back module and pass that to the generic one. This is
>>> the
>>> same kind of example that motivated Richard Carlsson's paper in the first
>>> place... and there isn't any other good way of solving the problem.
>>> Making
>>> the parameterised module into a gen_server instead, which has been
>>> suggested, isn't a good solution in this case because it's not
>>> reentrant--you can then only have one "instance" of the parameterised
>>> module
>>> at a time. What if you need more?
>>
>> I'm not sure I fully understand all of this, but couldn't you just
>> spawn more servers/processes?
>
> Well, no.
>
> I'm assuming a situation in which a generic module is fixed... maybe it's
> gen_server or gen_fsm in the OTP libraries, or maybe it's the eqc_statem
> module we use for testing state machines with QuickCheck. In either case,
> the generic code contains calls to callback functions which look like
> M:handle_call(...Params...), where M is the module name I pass in. I'm not
> going to change those calls--they're part of the published interface of the
> generic module.
>
> Now, when I use a parameterised module, then M will be something like
> my_parameterised_module:new(ModuleParams), and of course I can construct
>
> M1 = my_parameterised_module:new(ModuleParams1),
> M2 = my_parameterised_module:new(ModuleParams2),
> M3 = my_parameterised_module:new(ModuleParams3)
>
> and use them all at the same time. If my parameterised module implements the
> gen_server behaviour, for example, then I could create servers running the
> same code with different ModuleParams at the same time. What happens
> implicitly is that the value of M1 for example is a tuple
> {my_parameterised_module,ModuleParams1}, so the module parameters are
> carried with the module name to the point of call in the generic code.
>
> Now the idea of replacing a parameterised module by a gen_server is based on
> saving the ModuleParams as the state of the server, so that they don't need
> to be supplied on each call. So now I can just call
> my_parameterised_module:foo() instead of M1:foo(), and the foo function can
> pick up ModuleParams1 from the server state. Of course, I could spawn
> several processes all running the same code with different states--but how
> would I tell the generic code which process to talk to? All I can do is pass
> in my_parameterised_module as the module name, then generic code will call
> my foo function, and then I have to somehow figure out which process to talk
> to, in order to pick up the right state. There's no information available to
> enable me to do so. That's why this idea works fine for a single process
> (just register it with the module name), but fails as soon as you want to
> support multiple instances.
>
> I think you're imagining changing the calls in the generic code--passing a
> Pid as an extra argument, for example. Of course, if you do that, then you
> can use multiple processes to represent multiple instances. But now you're
> not reusing the generic code any more. With parameterised modules, we don't
> NEED to change the generic code at all, which is a big advantage.
>
> John
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>
>
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
More information about the erlang-questions
mailing list