Child modules draft feedback wanted

Richard A. O'Keefe <>
Fri Mar 31 07:10:02 CEST 2006


Romain Lenglet <> wrote
a reply to my request for comments.  Unfortunately, he
sent two copies, and I replied privately to what looked like
private mail before seeing it again in this mailing list.

I enclose a copy of my reply.  In brief, his counter-proposal
doesn't seem to do anything for most of the problems I am trying
to solve.  PERHAPS I AM TRYING TO SOLVE THE WRONG PROBLEMS.
My basic question is "how can I get rid of -include and -ifdef and
system-dependent file names in source code?"  Maybe that's the
wrong question.

... begin extract from reply ...

Let me just repeat back what I have understood from your mail:
	-module(client).
	-require(fred, [roast/1,]).
	...
	dosmthng(Foo) ->
	    fred:roast(Foo).
	
Your proposal is to add just one construction,

    -require(Logical_Module_Name, Imports).

Except for this being a "logical" module name, it is not clear
whether or how this differs from the existing -import directive.

	My -require clause is almost identical to your -use_child 
	directive, and the module name is not a real module name, but 
	rather a "logical" one which scope is limited to the declaring 
	module.
	
But this now GREATLY complicates the implementation.
In my proposal, I was extremely careful to ensure that NOTHING about
the way module: prefixes currently work would have to change.  There
would continue to be a single flat global name space for modules and
the interpretation of a module name would NOT be in any way context-
dependent.  [Added in this copy:]  I want it to be as easy as possible
to add the new constructs to Erlang; the more that changes can be
limited to the compiler, with *no* change to the semantics of full
modules as such, the happier I will be.

You are offering something as a feature that I regarded as a serious
problem to be avoided.

	And an ADL (yes, the "configuration language" here is in fact an 
	Architecture Description Language) would allow to specify the 
	dependencies *outside* of the code, as bindings between the 
	-requires clauses' logical module names and actual module names.

Either you have missed the point of my configuration language or I have
missed the point of your ADL.  I am trying to solve two problems with
the (as yet unwritten-up) configuration language:

    (1) I am trying to remove *FILE* names from the source files.
        I don't see where you say anything about file names.

    (2) I am trying to provide an alternative to -ifdef.
        Your ADL (no more described than mine) would appear to deal
        with that issue.

There's an anti-point:

    (3) I *don't* want dependencies stated outside the source code;
        I want dependencies very explicit *in* the source code.

	Just like your proposal, this follows the Principle of Separation 
	of Concerns, hence it allows to modify dependencies without 
	modifying the code and recompiling.

Maybe we are using the word "dependencies" to mean different things.

	And 'actualfred' would be a normal module.

No, that's precisely what I *don't* want.  I am NOT trying to set up
some kind of hierarchy of normal modules.  I am trying to design a
principled replacement for -include AND I am trying to meet a
frequently expressed "need" for some kind of hierarchical name scope
WITHIN a single module.

In particular, there are *TWO*-way links between an -include file and
its host, and that's why -use_child and -begin_child have *two*
interface lists.

	If 'actualfred' has dependencies itself (as were expressed with 
	"To_The_Child" declarations in your proposal), then those can be 
	expressed with -require likewise:: (there is no need to 
	distinguish between dfferent "kinds of depencencies", and 
	between "parent" and "child" modules)
	
	-module(actualfred).
	-require(parent, [beef/1]).
	...
	bar(Bar) ->
	    parent:beef(Bar).
	
You seem to be taking the present system of modules and adding two things:
(1) a module might be known by different names in other modules
(2) the mapping "In real module X, logical module name Y means real module Z"
    is expressed outside the source files.

It is as if you are asking "How could we make the present system more
flexible?"  But I am saying "the present system of relying on -include
files is intolerable; how can we replace -include?"

	I believe that we don't need any more concepts in the ADL so far.
	Except perhaps your concepts of replaceable / integrated. But I 
	believe that such things should be specified in an ADL spec 
	rather than in the code:

That won't work.  Remember, the heart and soul of my proposal is GETTING
RID OF -include.  There are things that -include can do which normal
imports CANNOT DO AT ALL.  Many of them are things that shouldn't be done.
Long term, we might even hope to replace -record with psi-terms or abstract
patterns.  But short term we are stuck with -record.  And we need to bind
a module to *some* kind of entity which can declare records, so that the
module can use those record declarations.  Your -require only provides a
way to import functions from a logical module.  That means that the
-record problem is left RIGHT WHERE WE STARTED and -include is STILL needed
to solve it.

This creates an absolute distinction between integrated child modules
and full modules:  integrated child modules *CAN* provide -record
information to their host, but full modules CANNOT.  The fact that you
*need* a record definition from somewhere is something that should be
stated explicitly in the source code.  The distinction between -record
declarations and ordinary functions drives a distinction between child
modules and full modules.

	IMHO, my proposal:
	1- is simpler than your proposal: only one new clause is added to 
	the syntax (-require);

Yes, but it's simpler because it solves at most one of the problems I
am trying to solve.

	2- does not distinguish between "parent" and "child" modules: 
	such a distinction is not necessary;

But as I have just argued, it IS necessary.

	3- allows all that your proposal allows.
	
It doesn't seem to allow hardly anything of what my proposal allows.

On the other hand, my proposal doesn't allow what your proposal does.
My proposal does not allow a full module to be known by different names.
I'm not sure how badly I want to prevent that, but it's certainly not a
solution to any problem I'm trying to solve.

That sounds rather negative.

+ Thank you VERY much for thinking about this.
  Even if we don't agree, the next version of the draft will be improved
  by me trying to clear things up.

+ My proposal certainly could be simplified.  (In particular, there is
  no actual necessity for in line children, although other languages
  have them and they do meet a frequently expressed desired for something
  like block structure.)  It is entirely credible that something not
  wholly dissimilar to your proposal COULD do the job.




More information about the erlang-questions mailing list