Thu Sep 4 11:37:08 CEST 2003
On mån, 2003-09-01 at 11:58, Sean Hinde wrote:
> A few thoughts on the proposal for parameterised modules as presented
> at the Erlang Workshop on Friday.
I've been thinking about that presentation too. I think that these
could be very useful in far more places than the examples given. I
definitely want them.
> So in summary the two weaknesses I see are:
> 1. There is no way to provide variable numbers of instantiation
> 2. There is no way to provide default values for instantiation
> Thoughts anyone?
How about static functions? There is no reason that the compiler
couldn't recognise functions that don't use any of the instance
variables, and allow them to be called directly. One could then write
one's own version of new, e.g.
new(UserX) -> new(UserX, defaultY).
Then the user could call either foo:new(X,Y) or foo:new(X). This seems
like a very natural way to do it, and users can write arbitrarily
complex versions of new if they want keywords, etc. I suppose an
-export_static directive could even be implemented, if it's thought to
be useful, but I don't see this as important.
And while on the topic of parameterised modules, an issue that I am
concerned with is the handling of code change. I am not convinced that
the proposed handling is correct. I am not even sure what the
Abstract modules really have (at least) two interfaces: one is the
behaviour(s) that they implement, and the other is their construction
("new" function(s)). Generally these are distinct: the "new" interface
will often be internal to a package, or otherwise specialised for the
module's static clients, i.e. the code that knows specifically what the
module does. The instances are (generally) passed to code that only
knows that it is a module implementing some behaviour. With the current
proposal, any changes in instance variables break the code change, or at
least remove any advantages to it. Yet changes to the internals of a
package are precisely the sort of thing one wants to do with code
e.g. One has an abstract module "foo" which implements various
behaviours. Instances of it are only created by the module "bar", but
are used by various other pieces of code which are unrelated, except for
understanding the behaviours implemented by "foo". One wishes to
support code change for the modules "foo" and "bar".
With the proposed system, the options are:
(1) Make sure that instance variables don't change in number, order,
or definition between versions.
(2) Make sure that all instances of the module are discarded when the
code change is performed.
Option #1 is rather restrictive. When writing version 1 of the code,
one must anticipate any changes that will be made. The customer needs
parameterised logging added for a couple of special cases? Then it
needs to be kludged in, since one can't add parameters to "foo".
Option #2 is more general, but means that the fact that old instances of
"foo" use the new code is useless. Even worse is the case where one of
the instance variables has changed subtly in definition, and one
(incorrectly) fails to discard all existing instances of "foo". Then
the old instances will misbehave in a very hard to diagnose fashion,
rather than just failing.
Perhaps these problems can be lived with, but I think that they should
Ideally, I think one would like an explicit code change interface. i.e.
one can write a static "code_change" function which is automatically
invoked when an old instance of the module is used, and which returns a
new instance to be used. i.e.
foo:code_change(OldVersion,OldVariableList) calls foo:new with the
correct updated parameters, and this value magically replaces the old
instance. Of course, this is asking quite a bit more of the
implementation, and may impact efficiency.
Anyone else have any thoughts on this?
More information about the erlang-questions