bowen@cs.Buffalo.EDU (Devon E Bowen) (05/10/91)
What are the rules regarding circular imports? For example, the following code must be invalid because 'a' is never declared. DEFINITION MODULE file1; FROM file2 IMPORT a; END file1. DEFINITION MODULE file2; FROM file1 IMPORT a; END file2. Yet it seems like the following should be valid because there is no such conflict. DEFINITION MODULE file1; FROM file2 IMPORT b; VAR a : INTEGER; END file1. DEFINITION MODULE file2; FROM file1 IMPORT a; VAR b : INTEGER; END file2. I haven't been able to find anywhere in Wirth's 4th edition that addresses this issue. So what are the formal rules in this situation and what techniques do most Modula-2 compilers use to implement them? Devon
gmurray@ibmpcug.co.uk (G Murray) (05/12/91)
In article <75730@eerie.acsu.Buffalo.EDU> bowen@cs.Buffalo.EDU (Devon E Bowen) writes: > > What are the rules regarding circular imports? For example, the following Stony Brook explicitly states that circular imports are not allowed. The general rule that they apply is that the order of compilation is such that the definition modules for all modules are imported *must* be compiled before the module that imports them. I would think that most, if not all, compilers imposed similar restrictions on circular imports. ---------------------------------------------------------------------- Graham Murray Email gmurray@ibmpcug.co.uk Senior Programmer OR gmurray@cix.compulink.co.uk Gravatom Technology Ltd Voice +44 329 823986 ---------------------------------------------------------------------- -- Automatic Disclaimer: The views expressed above are those of the author alone and may not represent the views of the IBM PC User Group. --
bowen@cs.Buffalo.EDU (Devon E Bowen) (05/13/91)
In article <1991May12.071720.29928@ibmpcug.co.uk>, gmurray@ibmpcug.co.uk (G Murray) writes: |> Stony Brook explicitly states that circular imports are not allowed. Sounds good to me (a lot easier to implement). But at the end of section 14 of the Report on The Programming Language Modula-2 in Wirth's book, he says If circular references occur among modules, their order of initialization is not defined. Which implies this circular nature does exist. Well, I guess I'll just leave this feature out until there is a definte need shown for it. Thanks for the help. Devon
eepjm@cc.newcastle.edu.au (05/13/91)
In article <76170@eerie.acsu.Buffalo.EDU>, bowen@cs.Buffalo.EDU (Devon E Bowen) writes: > > In article <1991May12.071720.29928@ibmpcug.co.uk>, gmurray@ibmpcug.co.uk (G Murray) writes: > |> Stony Brook explicitly states that circular imports are not allowed. > > Sounds good to me (a lot easier to implement). But at the end of section > 14 of the Report on The Programming Language Modula-2 in Wirth's book, he > says > > If circular references occur among modules, their order of > initialization is not defined. > > Which implies this circular nature does exist. Well, I guess I'll just There are two separate issues here. To determine the order of initialisation, you need to look at the definition modules AND the implementation modules. The original question was about definition modules only. My impression is that the difficult sort of circularity (involving definition modules) is always illegal, and the other sort is legal. Peter Moylan eepjm@cc.newcastle.edu.au
protonen@daimi.aau.dk (Lars J|dal) (05/13/91)
bowen@cs.Buffalo.EDU (Devon E Bowen) writes: >In article <1991May12.071720.29928@ibmpcug.co.uk>, gmurray@ibmpcug.co.uk (G Murray) writes: >|> Stony Brook explicitly states that circular imports are not allowed. >Sounds good to me (a lot easier to implement). But at the end of section >14 of the Report on The Programming Language Modula-2 in Wirth's book, he >says > If circular references occur among modules, their order of > initialization is not defined. ... As far as I know, this corresponds to the implementation modules, not the definition modules. That is, suppose you have the following modules: DEFINITION MODULE m1; VAR x:CARDINAL; END m1. DEFINITION MODULE m2; VAR y:CARDINAL; END m2. IMPLEMENTATION MODULE m1; FROM m2 IMPORT y; VAR x:CARDINAL; BEGIN x:=1; y:=1; END m1. IMPLEMENTATION MODULE m2 FROM m1 IMPORT x; VAR y:CARDINAL; BEGIN x:=2; y:=2; END m2. If they are compiled in the above order the definition modules will not use anything undefined. The implementation modules know the type of the foreign variable (x or y), so there is no problem either. But it is undefined whether the body of m1 or m2 is executed first, so if one compiler ends up with x=1 and y=1, you have no guarantee another compiler will do the same. (Only Wirth know if that was what he meant so please correct me if I'm wrong :-) ) Good luck with the implementation! +--------------------------------------------------------------------------+ | Lars J|dal | (put your favourite quotation here) | | protonen@daimi.aau.dk | | |--------------------------------------------------------------------------| | Computer Science Department - Aarhus University - Aarhus - Denmark | +--------------------------------------------------------------------------+
protonen@daimi.aau.dk (Lars J|dal) (05/13/91)
I forgot to define a main program to use the modules. The modules should be DEFINITION MODULE m1; VAR x:CARDINAL; END m1. DEFINITION MODULE m2; VAR y:CARDINAL; END m2. IMPLEMENTATION MODULE m1; FROM m2 IMPORT y; VAR x:CARDINAL; BEGIN x:=1; y:=1; END m1. IMPLEMENTATION MODULE m2 FROM m1 IMPORT x; VAR y:CARDINAL; BEGIN x:=2; y:=2; END m2. MODULE main_program; FROM m1 IMPORT x; FROM m2 IMPORT y; FROM InOut IMPORT WriteCard; BEGIN WriteCard(x,0); WriteCard(y,0); END main_program. >If they are compiled in the above order the definition modules will not >use anything undefined. The implementation modules know the type of the >foreign variable (x or y), so there is no problem either. But it is >undefined whether the body of m1 or m2 is executed first, so if one >compiler ends up with x=1 and y=1, you have no guarantee another compiler >will do the same. So the output should be 11 or 22, but the one is as correct as the other. >(Only Wirth know if that was what he meant so please correct me if I'm >wrong :-) ) >Good luck with the implementation! +--------------------------------------------------------------------------+ | Lars J|dal | (put your favourite quotation here) | | protonen@daimi.aau.dk | | |--------------------------------------------------------------------------| | Computer Science Department - Aarhus University - Aarhus - Denmark | +--------------------------------------------------------------------------+
schoebel@bs3.informatik.uni-stuttgart.de (Thomas Schoebel) (05/13/91)
In article <76170@eerie.acsu.Buffalo.EDU> bowen@cs.Buffalo.EDU (Devon E Bowen) writes: >Sounds good to me (a lot easier to implement). But at the end of section >14 of the Report on The Programming Language Modula-2 in Wirth's book, he >says > > If circular references occur among modules, their order of > initialization is not defined. > >Which implies this circular nature does exist. Well, I guess I'll just >leave this feature out until there is a definte need shown for it. Perhaps the distiction between definiton and implementation modules will make it more clear: In most current compilers, circular imports amoung definition modules are disallowed (even if the imported objects would not cause a cycle by their real definition); however, cycles amoung implementation modulues are possible. If you divide the definition and implementation parts logically into different modules, you may view the dependency graph in such a way that all sorts of modules are always importing from definition modules. Then there is never an import from an implementation module, so there is logically never a cycle. However, the initialization order amoung the modules in the cycle is undefined; this is the only problem I can see. As my opinion, in larger systems cycles amoung implementation modules are nearly unavoidable, but I cannot prove this. It is just an experience from practice. Theoretically, you can always break down any well-defined structure into smaller and smaller submodules, so there would be no need to allow circular imports. --Thomas
gkt@iitmax.iit.edu (George Thiruvathukal) (05/14/91)
In article <76170@eerie.acsu.Buffalo.EDU>, bowen@cs.Buffalo.EDU (Devon E Bowen) writes: > > In article <1991May12.071720.29928@ibmpcug.co.uk> > gmurray@ibmpcug.co.uk (G Murray) writes: > If circular references occur among modules, their order of > initialization is not defined. > > Which implies this circular nature does exist. I would take Dr. Wirth's comment to mean that circular references cannot be depended upon as a language feature in any given implementation of Modula-2. It is just too bad that we language implementators have to deal with such ambiguity in language definitions, especially since it is not a complicated issue to define. Circular imports should be outlawed. -- George Thiruvathukal Laboratory for Parallel Computing and Languages Illinois Institute of Technology Chicago
reid@CTC.CONTEL.COM (Tom Reid x4505) (05/17/91)
= I would take Dr. Wirth's comment to mean that circular references cannot be = depended upon as a language feature in any given implementation of Modula-2. = It is just too bad that we language implementators have to deal with such = ambiguity in language definitions, especially since it is not a complicated = issue to define. Circular imports should be outlawed. = -- = George Thiruvathukal I wouldn't be so hasty. Mutual importation is not frequent but is still legitimate. For example, consider an object-oriented system in which classes are implemented by modules. It is perfectly legitimate for two classes to exchange messages and thus, do mutual importation. It is also legitimate for each module/class to initialize itself. However, it still does not seem practical for either one of the two module to reference the other during initialization (i.e., each create an instance of the other during initialization). Even that may be correct (actually, not lead to potential nondeterminism) if no reference uses information set at initialization. The bottom line is that one should not disparage a construct just because one does not see a use for it. This particular construct does lead to an insecurity, but Modula-2 (for all of its typechecking, et.al) has many others. Tom Reid (Reid@ctc.contel.com)
gkt@iitmax.iit.edu (George Thiruvathukal) (05/17/91)
In article <9105161749.AA06495@ctc.contel.com>, reid@CTC.CONTEL.COM (Tom Reid x4505) writes: > It is perfectly legitimate for two > classes to exchange messages and thus, do mutual importation. It is also > legitimate for each module/class to initialize itself. > The bottom line is that one should not disparage a construct just because > one does not see a use for it. Actually, I saw the "use" for it, but I disagree with the notion that the "use" is all that useful. Modules which are so tightly coupled should be collapsed onto one module. On further examination, I would suggest that what ought to be disallowed are cycles which arise in the "import" graphs (whose nodes are both definition and implementation modules) and edges are "imports." Thus, two different modules (implementation parts) can borrow definitions and procedures from each other. However, their definition modules cannot do the same. It goes without saying that this restriction is NOT severe, because there are no mechanisms in Modula-2 for conditional compilation. Thanks for your comments. It is somewhat refreshing to see some positive and scientific discussion occurring in this newsgroup. -- George Thiruvathukal Laboratory for Parallel Computing and Languages Illinois Institute of Technology Chicago
news@m2xenix.psg.com (Randy Bush) (05/18/91)
gkt@iitmax.iit.edu (George Thiruvathukal) writes: > I would suggest that what ought to be disallowed are cycles which arise in > the "import" graphs (whose nodes are both definition and implementation > modules) and edges are "imports." Thus, two different modules > (implementation parts) can borrow definitions and procedures from each other. Watch out. Their initialization bodies should not depend on [ procedures which use or ] values provided by the other. This is non-trivial to detect, even without worrying about type transfer and other sinful acts. -- Randy Bush / news@psg.com / ..!uunet!m2xenix!news