Newsgroups: comp.lang.dylan
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!nntp.sei.cmu.edu!cis.ohio-state.edu!math.ohio-state.edu!howland.reston.ans.net!ix.netcom.com!netcom.com!netcom8.netcom.com!haahr
From: haahr@netcom.com (Paul Haahr)
Subject: Re: Module dependency cycle with Mindy ?
In-Reply-To: egouriou@hawk.cs.ucla.edu's message of 2 Oct 1995 02:18:33 GMT
To: egouriou@hawk.cs.ucla.edu (Eric Gouriou)
Message-ID: <HAAHR.95Oct2131823@netcom8.netcom.com>
Sender: haahr@netcom8.netcom.com
Organization: NETCOM On-line services
References: <44ni5p$n9i@delphi.cs.ucla.edu>
Date: Mon, 2 Oct 1995 12:18:23 GMT
Lines: 158

Eric Gouriou <egouriou@hawk.cs.ucla.edu> wrote:
> In the Module Declarations section, I found:
> 
> > Circular use relationships among modules are not allowed. 
> > The graph of the module-uses-module relation must be a directed 
> > acyclic graph. 
> 
> Has this restriction been removed from the "secret" final Dylan manual ?

No.

The module create clause often obviates the need for such circularities.
It's not very well explained in the DIRM.

With a create clause, you can declare that a module exports a name which
will be defined later by another module.  That way, you can have an
interface which exports a name but doesn't need to import anything, and
thus doesn't raise circularity problems.  The implementation module for
the interface imports both the interface module and any modules needed
in the implementation.

> I understand that such restrictions help greatly the task of the
> compiler writer but if I remember well Eiffel permits such cycles
> at a module level if the analysis of the code shows it to be legal.

It's not only there for the compiler writers.  It makes it much easier
to describe how modules work.  Eiffel effectively has to support such a
thing because of its static typing and classes-are-modules approach.

Paul

[Long example follows.]

> example of legal cycle (in dylan, I don't remember the Eiffel syntax):

Again, this may be legal for Eiffel but it isn't valid Dylan.

> module: A
> 
> define module A
> 	use C;
> 	export <A>,<B>;
> end module
> 
> class <A> (<object>)
> end class;
> 
> class <B> (<object>)
> 	slot c :: <C>
> end class;
> --------------------
> module: C
> 
> define module C
> 	use A;
> 	export <C>;
> end module
> 
> define class <C> (<object>)
> 	slot a :: <A>;
> end class;

I belive mindy allows the module definition for A to appear inside
module A, but I don't think that's legal Dylan, because you can't have
any code in a module before the module definition.  Most Dylan code I've
seen puts all library and module definitions in a separate file in the
dylan-user module;  that's what dylan-user is for.  You also need to
define the library.  So I'd write your example as:

  // still illegal

  Module: dylan-user

  define library A-and-C
    use dylan;
    export A, C;
  end library A-and-C;

  define module A
    use dylan;
    use C;
    export <A>, <B>;
  end module A;

  define module C
    use dylan;
    use A;
    export <C>;
  end module C;
  -----
  Module: A

  define class <A> (<object>)
  end class <A>;

  define class <B> (<object>)
    slot c :: <C>
  end class <B>;
  -----
  Module: C

  define class <C> (<object>)
    slot a :: <A>;
  end class <C>;

This clearly violates the ``no circular module usage'' prohibition.
Here's how I'd write it, using create:

  Module: dylan-user

  define library A-and-C
    use dylan;
    export A, C;
  end library A-and-C;

  define module A
    create <A>, <B>;
  end module A;

  define module C
    create <C>;
  end module C;

  define module A-implementation
    use dylan;
    use A;
    use C;
  end module A-implementation;

  define module C-implementation
    use dylan;
    use A;
    use C;
  end module C-implementation;
  -----
  Module: A-implementation

  define class <A> (<object>)
  end class <A>;

  define class <B> (<object>)
    slot c :: <C>
  end class <B>;
  -----
  Module: C-implementation

  define class <C> (<object>)
    slot a :: <A>;
  end class <C>;

Note 1:  There is no code that goes with the A and C modules.  They're
just interfaces.

Note 2:  The A-implementation and C-implementation modules aren't
exported.  They're not interfaces, just implementations.

Note 3:  There is no create clause for libraries, because that would
break the Dylan's library-at-a-time compilation model.
