From: ajw@Think.COM (Andy Wilson)
Newsgroups: comp.lang.clos
Subject: Re: CLOS Stylistic Questions -- Program Structuring
Date: 25 Aug 92 23:31:23 GMT
Organization: Thinking Machines Corporation, Cambridge MA, USA
NNTP-Posting-Host: custard.think.com

In article <9208171603.AA15940@thelonius.mitre.org>, john@linus.mitre.org writes:
|> Joe Konstan (konstan@cs.berkeley.edu) writes:
|> 
|>   Certain things need to be loaded before others can be loaded
|>   or compiled.
|> 
|>   One solution is to use some version of defsystem and to
|>   carefully assure that the dependencies can be met on a
|>   per-file basis (i.e., no circular dependencies between files).
|> 
|>   A second alternative (which I've been using) is to create a 
|>   "header" file with all of the needed declarations and
|>   definitions.  This includes "empty" defclasses (no contents, 
|>   just the class name and superclass names), macro definitions,
|>   and some defgenerics and proclamations.  
|> 
|> I agree with Jeff Dalton's comments, especially the observation that
|> the C world essentially uses a DEFSYSTEM facility.  Here are some of
|> my own comments.
|> 
|> Many of the systems I've developed use macros or DEFVARs that require
|> other macros, or even classes and methods, to be loaded before they
|> can be compiled or loaded.  For example, a computed macro expansion
|> may contain an embedded constant CLOS instance.  This would seem to
|> require interleaving your header files with non-headers.  Also, some
|> meta-object programming might require the full class definition, not a
|> stub, to be loaded when a referring method is compiled or loaded.
|> 
|> An implicit assumption in your second alternative is the existence of
|> a load file or load function, which refers to all the files.  I find
|> it MORE modular, maintainable and declarative to use a DEFSYSTEM
|> facility.  Otherwise you must maintain separate functions for each
|> operation (load, compile, dump-to-tape, and so on), with many of the
|> same dependencies duplicated in those functions.  These functions
|> become one more piece of code you must worry about maintaining, with
|> the added complication that not one, not two, but, by definition,
|> EVERY person working on the system has reason to make changes.  This
|> is true for a DEFSYSTEM declaration as well, but I find the latter
|> much more maintainable in a multi-person project.
|> 
|> Also, a DEFSYSTEM lets you declare local dependencies, rather than
|> requiring the computational closure of all dependencies.  For example,
|> compiling "GAMMA.LISP" directly requires loading "BETA.LISP", but
|> loading "BETA.LISP" requires loading "ALPHA.LISP".  Thus, compiling
|> "GAMMA.LISP" requires loading "ALPHA.LISP".  The system we're working
|> on now comprises over 500 files.  We'd rather not figure this stuff
|> out for each of them.
|> 
|> A DEFSYSTEM also (presumably) lets you define modules, subsystems and
|> utility systems, allowing you to modularize dependency declarations
|> appropriately.  This in turn makes it easier to have several different
|> versions of a system, each of which may load some files that others do
|> not.
|> 

I agree wholeheartedly.  There is no need to go off making up new,  nonstandard
ways of doing system building.

I've worked with an advanced version of DEFSYSTEM that flagged circular dependencies
as an error;  it generates the defsystem files by doing a code walk.  It would
be good to have a public domain defsystem that does this.  Much too much time
is spent dealing with system building and maintanence of Lisp systems.

This problem is not new with CLOS,  incidentally.

|> John Burger
|> john@mitre.org