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

Issue: REQUIRE-PATHNAME-DEFAULTS (version 2)



Issue:         REQUIRE-PATHNAME-DEFAULTS
References:    *MODULES*, PROVIDE, REQUIRE, pp 188-191
               LOAD, pp 426-427
Category:      CHANGE
Edit history:  Version 1 by Pierson 9/13/88
               Version 2 by Pierson 9/19/88, change PROVIDE stuff per comments
Status:        For Internal Discussion

Problem description:

PROVIDE and REQUIRE are a dual-purpose pair of functions that attempt
to provide multi-file Common Lisp programs with a single mechanism to
detect and correct incorrect load sequences.  These functions were
also designed to be used for general file inclusion in Common Lisp.
Unfortunately, the file loading feature of REQUIRE is specified such
that it is inherently non-portable and environment dependent.

The instructions on CLtL pp. 189-191 on the placement of PROVIDE and
REQUIRE don't work because they ignore interactions with LOAD.  If
PROVIDE is placed at the head of a file which fails to load correctly,
the module will be incorrectly recorded as loaded.  If PROVIDE is
placed at the end of the file, as is the unofficial current practice
in some groups, it is not possible to REQUIRE a file that REQUIREs the
current file; thus mutually dependent modules cannot be correctly
defined. 


Proposal (REQUIRE-PATHNAME-DEFAULTS:DECLARATIVE):

Remove the second argument from REQUIRE.  Change the description of
REQUIRE to:

    The REQUIRE function tests whether a module is already present
    (using a case-sensitive comparison); if the module is not present,
    REQUIRE signals a correctable error of type REQUIRE-ERROR.  The
    error can be corrected by loading the appropriate file(s).

Note that there is no requirement that a module consist of exactly one
file. 

Change the description of PROVIDE to:

   "The PROVIDE function adds a new module name to the list of
    modules maintained in the variable *MODULES* and possibly performs
    other implementation-dependant actions to indicate that the module
    in question has been loaded."

(There is no need to make a corresponding change to the definition of
REQUIRE, because it doesn't mention *MODULES*.)

Add a new second paragraph to the section on LOAD (CLtL 23.4):

    "Top level PROVIDE functions in files being loaded are handled
     specially.  The PROVIDE is executed in a temporary environment
     such that the module will appear to have been loaded during the
     remainder of the load of the current file and any files loaded,
     whether directly or by REQUIRE, during the loading of the current
     file.  If an error occurs during the loading of the current file,
     all modules PROVIDEd during the load of the current file will be
     forgotten.  Otherwise, all these modules will be "confirmed" at
     this level of nested loading.  (Note that an implementation which
     uses *MODULES* as the only loaded module database can support all
     of this by simply rebinding *MODULES* appropriately internally
     and pushing the new modules onto the old binding at the end.)"

Test Cases/Examples:

(REQUIRE 'fft)

Would still be legal.

(REQUIRE 'fft "fft")

Would no longer be Common Lisp.

Rationale:

The file loading feature of REQUIRE is non-portable.  Since we can't
figure out an acceptable portable solution, the feature should be
flushed.  Making REQUIRE signal a correctable error gives the user an
easy out in interactive situations.

Current practice:

All implementations that I know of currently support a second argument
to REQUIRE.  Lucid and KCL use the second argment at the pathname to
load relative to the current working directory.

Cost to Implementors:

All currently conforming implementations will have to make a small
change.

Cost to Users:

Any (non-portable) user programs that rely on the current behaviour of
REQUIRE will have to change.  On the other hand, porting Common Lisp
programs from one system to another may well be simplified because
REQUIRE errors will always correctable.

Cost of non-Adoption:

Part of the documented functionality of REQUIRE will continue to
unavailable to portable (and many non-portable) programs.

Benefits:

PROVIDE and REQUIRE will be clearly restricted to a portable,
checking role.

Aesthetics:

This simplifies the language by removing an environment-dependent
feature. 

Discussion:

Pierson supports this proposal.

This proposal creates an asymmetry in the handling of *MODULES* that
may bother some people.

Several people would like to simply eliminate PROVIDE and REQUIRE from
the language and either leave this language space empty or provide a
portable DEFSYSTEM standard.  Others believe that PROVIDE and REQUIRE
are useful as a safety-net even in the presence of DEFSYSTEM.  This
proposal attempts to reduce PROVIDE and REQUIRE to a well-defined
safety-net and leaves the question of DEFSYSTEM to a separate
proposal (which I don't intend to write).