[erlang-questions] Reified environments (was: Re: Package Support/Use)
Richard A. O'Keefe
ok@REDACTED
Wed Nov 8 05:49:15 CET 2006
I was going to send part 2 today, but it looks as though part 1A had
better come first.
Interesting proposal, though I haven't absorbed it
fully. Generically, I think there are a few basic
issues to be considered:
1. How are names resolved within a module (scoping)
I explained that. In order to call anything in a module,
that module must be BOUND in an environment. All module names
in that module, whether static or dynamic, are sought in that
environment. That's what it's for.
2. How are names visible outside a module (hiding)
Modules only define functions. They are visible outside the
module (or not) just as they are now. A module is visible under
some name in some environment if and only it is installed in that
environment. Just like now, in fact, except there's more than one
environment.
3. When are names resolved? (e.g., at runtime, compile
time, "package assembly time", ...)
Names that are statically known are resolved to addresses at load
time. Because Erlang allows hot loading, those addresses are only
dereferenced when they are actually used.
4. Also, given that we have a language with code
change, we have to handle "relinking" on code change.
I can see several options for how that should be done.
But that's already in there. Practically nothing changes. Certainly
nothing is _different_.
The drawback is that it seems more complex than the
current model. Not a big problem for me, but I think
the common case should be straightforward and
unsurprising to use. (Your proposal may be perfectly
so, but I haven't really thought it through.)
Yes, but the "common case" of my proposal is (almost) exactly what we
have now. That's the whole point of it, really.
One change is this.
<any module>:module()
returns that module as a module object. This would be a
compiler- generated function like <module>:module_info().
This means that
other_mod(foo, bar, [1,2])
might ask other_mod to invoke foo:bar(1,2) according to the definition
of 'foo' that _it_ sees, whereas
other_mod(foo:module(), bar, [1,2])
would ask other_mod to invoke foo:bar(1,2) according to the defition
of 'foo' that the _caller_ sees. This means that the preferred way
of mentioning the current module changes from
?MODULE
to module().
Also, I'm not sure how it relates to the constructs of
other languages;
Not much. It was partly inspired by a misremembering of Luca Cardelli's
Obliq language, and partly by a Xerox PARC configuration language, and
partly by another latent-typed functional language I can't remember.
There's certainly some atmospheric influence from Tcl nested interpreters,
and if I haven't reinvented *some* aspect of SafeErlang I shall be
astonished.
most seem to be oriented towards
statically building components and assembling them
into an executable.
That's why the reified environments proposal is different.
Erlang would need a bit more dynamism as per point #4.
Dynamism is the *point* of making environments into objects you can
dynamically install stuff in and uninstall it from.
We could also discuss the finer details of code change, such as
how closures or records really should be handled.
Joe Armstrong and I have both proposed essentially the same replacement
for records. The same data type is found in IBM Prolog, and is the
main data structure in Obliq. We could argue about the details, but the
concept is clear. We know what *could* do the job of records, without
-record declarations, and it has been implemented by other people. (Yes,
that's why I decided to look at the Erlang compiler.) As for closures,
the only thing I can say for the reified environments proposal is that it
doesn't change anything relevant to closures, so at least it doesn't make
the problems worse.
At this point, it strikes me that I'd actually like to
see some requirements. The take-home point might be:
"So, what functionality do we expect our reified
environment or packaging system to provide?"
1. Dynamic.
2. No new syntax in modules, only new data types and functions.
3. If you don't use it, you get what you have now, or close enough.
4. No nasty surprises: statically known and dynamically known names
should behave exactly the same.
5. Encapsulation: it should be possible for one module in an application
to access the others without thereby making it possible for every
module in the system to access them.
6. Ease of migration: it should be possible to wrap up a bunch of
modules and stuff them into an environment without changing those
modules (provided they don't use packages).
Those are some of the requirements I had in mind for reified environments.
More information about the erlang-questions
mailing list