[net.lang.mod2] id AA11814; Sun, 19 Feb 84 21:02:32 pst

ags@pucc-i (Seaman) (02/23/84)

When I said that Volition Systems' Modula-2 Compiler allowed cyclic
dependencies, I did not mean to imply that two definition modules could
import from each other.  This does indeed seem difficult, since neither
could be compiled unless the other has been compiled first.

What I meant, of course, is that at least part of the cycle has to be
hidden in implementation modules.  I have not found a statement on this
in Wirth's book, but the Volition Systems manual explicitly says that
two implementation modules can import from each other.  There is a note
that this dictates arbitrary module initialization order (Which is more
nested?), implying that the initialization bodies cannot depend on
objects imported from the other module.
-- 

Dave Seaman
..!pur-ee!pucc-i:ags

"Against people who give vent to their loquacity 
by extraneous bombastic circumlocution."

powell@decwrl.UUCP (02/26/84)

Date: Sun, 19 Feb 84 21:02:32 pst
From: powell (Mike Powell)
Message-Id: <8402200502.AA11814@decwrl.arpa>
To: net.lang.mod2
Subject: Circularity Peculiarity

As an implementer of a Modula-2 compiler, I would be interested to know
exactly what sort of "cyclic dependency" is permitted by the Volition (or
any other) compiler.  A reference to Wirth's book indicating where it says
it's legal would also be helpful.

It seems to me that allowing the following is hard:

definition module a;
from b import BType;
export qualified AType;
type
    AType = pointer to record
	b : BType;
    end;
end a;

definition module b;
from a import AType;
export qualified BType;
type
    BType = record
	a : AType;
    end;
end b;

I've supported a compiler (for the Model programming language) which allowed
such things, and the type resolution procedures were the largest single source
of bugs.  The problem is that an additional pass is required to resolve types.
The walk over the type graph is complicated because there may be recursions
(as above).  If there is a loop, there must be a pointer (otherwise, it's
an error), and the loop must be broken at that point.  Anyhow, it turned out
to be expensive to do it right (if the fact that we don't know of any bugs at
the moment means it does it right).

Moreover, if Wirth's intent were to allow such circularity, there would be no
need for rule 1 in section 4 of the report, since forward references to types
would be handled by the same mechanism.

What I think is easy to do is to allow the following:

definition module a;
(* no imports from b *)
    ...
end a;
implementation module a;
from b import WhateverYouLike;
    ...
end a;

definition module b;
from a import Anything;
    ...
end b;
implementation module b;
    ...
end b;

In this case, the only potential question is about which initialization routine
is executed first.  Again, if anyone has a concrete answer, I'd be interested.
For local modules, they are supposed to be initialized in declaration order
(Report section 11), not dependency order, which could allow a procedure in a
local module to be called before its initialization is executed!

Anyhow, opinions or citations would be appreciated.

					Michael L. Powell
					Western Research Laboratory
					Digital Equipment Corporation
					Los Altos, CA
					{ucbvax,decvax}!decwrl!powell