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

[no subject]

This is yet another message about defsystem. I also found the system
difficult to learn. Of course it is desirable to have some facility
for ensuring system consistency and for incorporating patches.
I however question the wisdom of defining what is essentially
a new restrictive declarative language with obscure procedural
interpretations. This message proposes an alternative approach in which the
user is presented with a set of simple primitive functions for
querying the state of files and the LISP environment. These functions
could be readily used to construct utilities for ensuring the consistency
of systems. The advantage of this approach is that the language in which
system definitions are written is simply LISP with all of its advantages
and flexibility. The following is a detailed presentation of the proposal.

Suppose one was provided with the following four functions:

qfasl-date (filename)

	This function gives the creation date of the qfasl file.

source-date (filename)

	This function gives the creation date of the source file.

loaded-date (filename)

	This function gives the creation date of file from which the
definitions in the current environment were derived (the creation date
of the last loaded version).  If no version has been loaded this
function returns nil.

qc-loaded? (filename)

	This predicate is t if the last loaded version was a qfasl

One could then define the following functions

(defun load-latest (filename)
  (if (or (null (loaded-date filename))
	  (> (source-date filename)
	     (loaded-date filename)))
      (if (> (source-date filename)
	     (qfasl-date filename))
	  (load-source filename)
	  (load-qfasl filename))))

	This function checks to see if the file has not been loaded or
if the loaded version is out of date and in either case loads a current
version of the file. 

(defun compile&load (file compile-requirements)
  (cond ((or (> (source-date file)
		(qfasl-date file))
	     (exists compile-requirements
		     '(lambda (req) (> (source-date req) (qc-file-date file)))))
	 (mapc 'load-latest compile-requirements)
	 (qf-file-load file))
	((or (null (loaded-date file))
	     (not (qc-loaded? file))
	     (not (= (loaded-date file) (qfasl-date file))))
	 (load-qfasl filename))))

	This function checks to see if the compiled version is out of
date (either because of changes to the source or changes to the
compile dependencies) and if so it first loads the latest version of
the compile dependencies and then compiles and loads the file. If the
qfasl file is current the function checks to make sure that this
version of the qfasl file has been loaded and if not loads it.

A "system definition" for a system I have been working on could now be written
as follows:

(defun make-rup ()
  (let ((*directory-defaults* "ai:rup;") ;or some such thing
	(macros '(utgtal utgmac utgmpc utils)))
    (mapcar '(lambda (file) (compile&load file macros))
    (compile&load "brque" macros)
    (compile&load "brtms" macros)
    (compile&load "breq" macros)
    (compile&load "brrup1" (list* "brtms" "breq" macros))
    (compile&load "brntcr" macros)
    (compile&load "brpnot" (list* "brntcr" macros))))

Load dependencies are handled by the execution order.

Note that the macros must be loaded before they are compiled and that this is
naturally handled by the load-latest function. I have talked to many people who
have had to use the obscure :skip transformation in order to achieve a similar

Of course I have not included any options as arguments to make-rup but
this could be arranged. A patches facility could be built by using a
second filename convention "patches" and the following primitives:

patch-from (file)

	This function returns a date such that files created after
that date can be patched via the patch version of file.

patch-to (file)

	This function returns a the date that the patch file was
created. Loading a patch file to an environment created after
(patch-from file) brings the system up to (patch-to file) such that
(loaded-date file) thereafter is the same as (patch-to file).

The function load-current and load&compile could be changed to check
for current patches (or given a switch to do so).

This is of course not a complete specification for system defining utilities.
However I think that such a utility could be constructed in the spirit of
LISP, specifically by providing a set of simple primitives and a few higher
level functions and then letting users write code in a powerful wide spectrum
language that they already know (LISP). I have no intention of working on
this facility and competeing with existing supported software However I
hope that this message will be taken into account if defsystem is ever

David McAllester