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

proposal for modifying behavior of REQUIRE



Issue:         REQUIRE-PATHNAME-DEFAULTS

References:    CLtL p. 188

Category:      CHANGE, ADDITION

Edit history:  V1, 15 Oct 1987  Sandra Loosemore (sandra@cs.utah.edu)

Related issues: none

Problem description:

If an explicit pathname is not given to the function REQUIRE, it decides
what files to load in an implementation-specific manner.  The proposal
specifies a portable mechanism for locating modules intended to augment
current nonportable mechanisms.


Proposal:

*REQUIRE-PATHNAME-LIST* [Variable]

The variable *REQUIRE-PATHNAME-LIST* is a list of pathnames.  This
list is used by the function REQUIRE in determining where to look for
modules an explicit pathnames are not specified.

REQUIRE tests for the following cases:

(1) If the pathname argument is present and non-NIL, it is a single
pathname or a list of pathnames whose files are to be loaded in order, left
to right.

(2) A pathname is constructed from the module name and merged with
successive pathnames from the list *REQUIRE-PATHNAME-LIST*, until
a matching file is found and loaded.

(3) The system will determine, in some system-dependent manner, which files
to load.  This will typically involve some central registry of module names
and the associated file lists.

Users will typically wish to push new pathnames onto the front of 
*REQUIRE-PATHNAME-LIST* to specify alternate locations where modules
may be found.


Test Case:



Rationale:

Because of the wide variation between implementations, leaving it up to
REQUIRE to determine which files to load is very nonportable.  Providing an
explicit pathname is often impractical as well; for example, the same code
may run under two implementations with different operating systems and
different file naming conventions; the modules may reside in different
places on different machines; or it may be desirable to support alternate
versions of some modules (such as a release version and an experimental
version).

This proposal provides a portable way of describing where modules can be
found.  The value of the *REQUIRE-PATHNAME-LIST* can be established in a
startup or initialization file, keeping a system-specific detail separate
 from portable code files.  Allowing a search list rather than a single
default pathname gives users extra flexibility to customize the behavior of
REQUIRE.  Moreover, the current default behavior is still supported for
those programs which depend on it.


Current practice:

The idea of using a search list for loadable modules is modeled after the
LoadDirectories* variable used by Portable Standard Lisp.  PCLS, the CL
compatibility package layered on top of PSL, currently uses a variable
SYS:*REQUIRE-PATHNAME-LIST* as described in this proposal.

VaxLisp (under VMS) looks for a module with the specified name first in the
current directory, then in the place specified by the logical name
LISP$MODULES, then in LISP$SYSTEM.

Lucid's documentation does not specify how their implementation of REQUIRE
works.  I was unable to get it to find modules except in
*DEFAULT-PATHNAME-DEFAULTS*.

KCL looks for modules only in *DEFAULT-PATHNAME-DEFAULTS*.


Adoption Cost:

The change is minor and isolated to a single function.  Here is a suggested
implementation of REQUIRE:

(defvar *require-pathname-list* nil
    "Where REQUIRE looks for modules if you don't give an explicit pathname.")

(defun require (module &optional pathname)
    (cond ((member (string module) *modules* :test #'equal))
          ((consp pathname)
	   (dolist (p pathname)
	       (load p)))
	  (pathname
	   (load pathname))
	  ((progn
	       (setq pathname (pathname module))
	       (some
		   #'(lambda (default)
			 (load (merge-pathnames pathname (pathname default))
			       :if-does-not-exist nil))
		   *require-pathname-list*)))
	  ((load pathname :if-does-not-exist nil))
	  (t
	   (cerror "Nothing will be loaded."
	       "Module ~s could not be found."
	       module)))
    module)



Cost of non-adoption:

Using REQUIRE in portable code is difficult.  In KCL and Lucid, I was forced
to redefine REQUIRE in my startup file to get it to look for modules in
places other than *DEFAULT-PATHNAME-DEFAULTS*.


Benefits:

See above, under "Rationale".


Conversion Cost:

None.  The proposal is entirely compatible with the existing definition.


Esthetics:

I'd ordinarily be the last person to propose extensions to Common Lisp, but
having to learn one feature that works under all implementations is better
than having to learn each implementation's own peculiar way of handling the
same situation.


Discussion:

I mentioned the idea of having a variable to specify where REQUIRE looks
for modules in passing on the CL mailing list.  There were 2 positive
responses and no negative ones.  Cutting.pa@xerox.com proposed a search
list rather than a single pathname, which is actually what I had in mind
anyway.

-------