[erlang-questions] Request for comment: A proposal to introduce the concept of function domains

Richard A. O'Keefe ok@REDACTED
Mon Apr 29 01:28:10 CEST 2013


On 25/04/2013, at 7:21 PM, Thomas Järvstrand wrote:
> The rationale is that encapsulation is a good thing and that code should not be allowed to depend on library functions that the library's author did not intend to expose to the outside world. Because of this I would like to introduce the idea of exporting functions into different domains.

"Domain" here appears to mean "scope".

There has been a proposal for many years now,
inspired by Eiffel, to have

-export_to(Module, [F1/N1,...,Fk/Nk]).

You'll find it written up as EEP 5
http://www.erlang.org/eeps/eep-0005.html
but it is at least 10 years older than that.

The original proposal came with a variant that said
"these are callback functions for such-and-such a behaviour",
with the intention that it would be checked at compile
and/or load time that such a behaviour existed and wanted
those functions.

The Eiffel approach is organised around what is to be exported:
  feature {<set of classes>}
    <definitions of features>

The EEP5 approach is organised around the destination of exports:
  -export_to(<single destination>, [<set of exports>]).

If EEP5 is extended slightly to allow

  -export_to([<set of destinations>], [<set of exports>]).

and to allow [X] to be simplified to X when there is a single X,
then either way of slicing up the export matrix could be used,
whichever the programmer thought clearer.

> There will be three predefined function domains: one will allow the function to be called from anywhere,

I take it this has the same effect as -export does now.

> one will allow the function to be called from within its own application

The trouble is that "application" is an OTP concept, not an Erlang
concept, in that the Erlang compiler otherwise has no knowledge of
"applications".

Now, suppose we take the slightly extended EEP5.  Can that do this job?

Well, suppose we set up a convention, that an application foo
has a foo_modules.hrl file containing

    -define(FOO_MODULES, [<set of module names>]).

Then you will be able to do

    -include('foo_modules.hrl').
    -export_to(?FOO_MODULES, [<set of functions>]).

Some good things about this are
 * no requirement for a run-time test 'are these two modules part
   of the same application', which I am not sure is implementable
   in principle
 * you can export to *less* than a whole application but more than
   a single module
 * you can export to more than one application but less than the
   entire universe

> and one to  disallow the function from being explicitly referenced anywhere outside its module (this is for behaviour callbacks, functions passed/returned as funs etc.)

Ah, this is a tricky one.  You're talking about allowing something to be
called elsewhere, but not explicitly.  But that's rather a fragile concept.

	m:f(X1, X2)			% explicit
	M = m, M:f(X1, X2)		% not explicit
	F = f, m:F(X1, X2)		% not explicit
	M = m, F = f, M:F(X1, X2)	% not explicit

But if the compiler front end does constant propagation (and why shouldn't it?)
all of these would look identical to the back end.

Do we really have a problem here that needs solving?

In any case, doesn't this conflict with export_all?

> Suggestions for what to call the predefined domains are:
> 
> public, restricted, private
> The rationale is that due to how the language works, a domain-declaration will only specify where we allow the  function to be referenced with its fully qualified name we can't detect other any other references anyway.

But a private function under your scheme would in no sense be private;
it is after all a kind of _export_.  What's more since you say that
"private" is for "behaviour callbacks ... etc" and since existing
behaviour modules are outside your application, "private" actually
makes a function available to the *same* modules that "public" does.

It seems to me that you are mixing up two very different things here:
 - WHICH other modules may call a function
 - HOW may they call it.

I think a coherent design needs to separate these issues.





More information about the erlang-questions mailing list