Article View: comp.lang.clos
Article #129Re: CLOS Stylistic Questions -- Program Structuring
From: Jeff Dalton
Date: Mon, 17 Aug 1992 11:24
Date: Mon, 17 Aug 1992 11:24
107 lines
5244 bytes
5244 bytes
> >1. Load/Compile order dependencies > > > > Certain things need to be loaded before others can be loaded > > or compiled. For example, class definitions must occur before > > the class name can be used as a method specializer. > > > > 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). > > This intricate solution seems tedious, hard to document, hard to > maintain. Unfortunately, I bet this solution is the most common. I think you're being a bit hard on defsystem. Is it really so bad? It shows the dependencies between files all in one place. It allows you to partially recompile a system (recompiling only the files that need to be recompiled). (Which might happen just because an error occurred in the middle of compiling all the files.) And it means you don't have to write your own special-purpose functions for compiling and loading your system. I don't see why it would be tedious, hard to document, or hard to maintain. > > 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. Modularity will often lead to there being several header files. Then there will be files of macros, etc. You also may have macros that depend on other macros (suppose you define an extend-syntax as used in some Schemes). (BTW, C programming, which involves extensive use of header files, also tends to involve makefiles.) > > The advantage of this approach is that load/compile order, > > after loading this header, is unimportant. A disadvantage is > > that each class gets defined and redefined (eliciting regular > > warnings from some compilers such as Lucid) which I imagine is > > not very efficient. If you always write systems that follow a simple pattern, then you can use a simple version of defsystem. > package definitions > exports and imports Why aren't the exports and imports part of the package definition? (They more or less have to be if you use defpackage.) > For instance, utility macros would go before everything with > their own set of four file groups. Why do you need four file groups just to define macros? > >2. Subclasses in new packages > > > > ...[handling packages]... > > It seems that there are a few options, and I'm interested in > > which ones other people tend to use: > > > > a) Forget the modularity, just use a single package > > Perhaps an ugly solution, but it codes and debugs > > easily. > > > > b) Compromise the modularity and export the slot names, etc. > > Also ugly, but relatively simple. > > > > c) Use the :: naming withing the SPECIAL-AGENT packages > > > > d) Specifically import the desired symbols into the > > SPECIAL-AGENT packages either as an import-from clause in > > the defpackage or with an import call > > This seems like the best solution I've found. I > > imagine it would also be pretty easy to design > > standard :import-from clauses for packages so all > > children of AGENT in other packages would use the same > > clause. > > I too think that the best solution is d) as long as no name conflicts > result. Resort to c) for conflicting names. a) and b) seem like > pretty low quality options. I don't think it works very well to have a separate package for each class. A separtate package for a group of related classes would usually work better, because otherwise the package structure gets too complex. You also tend to start referring to internal names (by using "::" or by importing them), which violates the modularity of your packages, or else exporting names that should really be internal, thus violating the modularity of your class definitions. The problem is that you want some names to be available only to certain packages (the ones that define subclasses) but Common Lisp provides only "available to everyone" (exported) and "available to no one" (not exported). I'm not sure there is a very good solution to this in general, but the problem can be avoided when there is a group of related classes that can be considered as a single "service". (Eg, if you want to provide a graphics service, you might have several class definitions in the "GRAPHICS" package.) -- jd
Technical Details
Message-ID:
<4948.9208171124@subnode.aiai.ed.ac.uk>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!aiai.edinburgh.ac.uk!jeffShow Full Headers
Complete Article Headers
Newsgroups: comp.lang.clos Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!aiai.edinburgh.ac.uk!jeff From: jeff@aiai.edinburgh.ac.uk (Jeff Dalton) Subject: Re: CLOS Stylistic Questions -- Program Structuring Message-ID: <4948.9208171124@subnode.aiai.ed.ac.uk> Sender: daemon@cis.ohio-state.edu Organization: The Ohio State University Department of Computer and Information Science Date: Mon, 17 Aug 1992 11:24:56 GMT Lines: 110