[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Managing large LISP code



clin@eng.umd.edu (Charles Lin) writes:

>   Is there any standard technique for managing large amounts
>of Lisp code?   For example, even though people are taught
>C or Pascal or FORTRAN in colleges and universities, it is
>usually at the level that only one file is needed, and maybe
>less than 1000 lines of code.   In that case, there is no
>real need for file management or any special style that
>has to be maintained while writing code.   However, once
>the code gets to be very large, people start using makefiles
>and standard ways of naming functions and variables arise.

There are several applicable techniques.  I'll assume Common
Lisp for the details, but similar things apply to other Lisps
as well.

1. Source-code control systems such as SCCS and RCS can be used
   with Lisp.

2. Makefiles can also be used for some things, but control
   over compilation (what depends on what, etc) is usually
   give to a make-like facility within Lisp, usually called
   DEFSYSTEM.

3. Packages can be used in a fairly module-like way to provide
   some structure above the level of individual procedures.
   A DEFPACKAGE in a separate file is considered the right way
   to define a package these days.

4. Object-oriented programming (as in CLOS) also helps structure
   large programs.

5. Style guidelines are a matter for individual projects, but
   several books, such as Norvig's offer reasonable suggestions.
   The book _Lisp Style and Design_ is also worth checking out.
   Some conventions for commenting and variable-naming (*name*
   for specials) are described in CLtL.

One issue that often comes up is how class definitions should
be distributed among packages.  In my view, it's best to use a
package for a group of related classes (that constitute some
coherent logical unit) rather than use one package per class.

In Lisp, it's usual to use long, descriptive function names such
as remove-if or even remove-if-not, copy-list, or unwind-protect 
-- rather than (say) remif, remnif, cpylst, or uwd_prot.  Variable
names often indicate the "logical" class / type that's typically their
value.  This doesn't have to be the "Lisp" class/type.  E.g.

   (defun transpose-graph (vertices edges)
     ...)

But the following might also be reasonable

   (defun transpose-graph (list-of-vetices list-of-edges)
      ...)

If graphs are important, they might be defined as a struct
or class.  Then you'd probably see

   (defun transpose-graph (graph)
      ...)

Though in this case, the intent may be sufficiently clear that
you could say (defun transpose-graph (g) ...).

There's a lot of reasonably well-written Lisp code on the net that can
be examined for ideas.

-- jd