[comp.lang.lisp] 'provide' and 'require' and compiled files

uda@mina.liu.se (Ulf Dahlen) (01/27/89)

How is 'provide' and 'require' implemented in existing CL-implementations?
I would like 'require' to search for the compiled file first, and load it if
it's found. Xerox Lisp has a 'require' that doesn't bother about compiled
files. This makes it almost necessary to use the InterLISP function 'FILESLOAD'
and that will make programs less portable.

Let's say I have a file submodule that does the following:

(provide 'submodule)
;;; rest of file

Then say I compile this file, getting a submodule.fasl (or whatever extension
is used). If I have another file with these statements:

(provide 'mainmodule)
(require 'submodule)
;;; rest of file

I would like this file to load submodule.fasl, not submodule.lisp. The fact
that the extension for compiled files is not stated in CLtL, makes it
impossible to write (require 'submodule 'submodule.fasl) or something like
that.

__________
Ulf Dahlen
Dept of Computer & Info Science, University of Linkoping, Sweden
Troskaregatan 51:23       |     uda@ida.liu.se
S-583 30  LINKOPING       |     uda@majestix.liu.se, uda@majestix.UUCP
SWEDEN                    |     {mcvax,munnari,seismo}!enea!liuida!uda
"The beginning is a very delicate time."

jwz@spice.cs.cmu.edu (Jamie Zawinski) (01/30/89)

It has always seemed to me that PROVIDE and REQUIRE are too vaguely
specified to be useful.  The fact that it is not obvious what the
behavior of REQUIRE is in multiple correct implementations of Common
Lisp means that you cannot really expect use of it to be portable.

Why not use some kind of 'make' utility?  There are several public
domain Lisp make-systems around.  Or, you could do something really
minimalist, and just have a file of calls to LOAD.

Jamie
-- 

barmar@think.COM (Barry Margolin) (01/30/89)

In article <4146@pt.cs.cmu.edu> jwz@spice.cs.cmu.edu (Jamie Zawinski) writes:
>It has always seemed to me that PROVIDE and REQUIRE are too vaguely
>specified to be useful.  The fact that it is not obvious what the
>behavior of REQUIRE is in multiple correct implementations of Common
>Lisp means that you cannot really expect use of it to be portable.

For this reason, the ANSI X3J13 committee voted last week not to
include PROVIDE and REQUIRE in ANSI Common Lisp.  (Or we may simply
have removed the second argument to REQUIRE -- I don't have my records
with me here at home.)

Barry Margolin
Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

andy@Gang-of-Four.Stanford.EDU (Andy Freeman) (02/01/89)

In article <1168@mina.liu.se> uda@mina.liu.se (Ulf Dahlen) writes:
>How is 'provide' and 'require' implemented in existing CL-implementations?
>I would like 'require' to search for the compiled file first, and load it if
>it's found. Xerox Lisp has a 'require' that doesn't bother about compiled
>files. This makes it almost necessary to use the InterLISP function 'FILESLOAD'
>and that will make programs less portable.

Given this description, I can't tell where the problem is.  Steele pg
188 says:

"The require function tests whether a module is already present (using
a case-sensitive comparison); if the module is not present, require
proceeds to load the appropriate file or set of files.  The pathname
argument, if present, is a single pathname or a list of pathnames
whose files are to be loaded in order, left to right.  If the pathname
argument is nil or is not provided, the system will attempt to
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."

Note that require's second argument is a pathname, not a string or a
symbol.  The string/symbol "representation" of a pathname on one
implementation may not work on another implementation, but the
pathname construction functions must.

As to getting require to do the right thing if there are both compiled
and text versions of the file, I refer readers to the description of
load, on page 426.  (The description of require implies that it uses
load.)

"If the filename (after the merging in of the defaults does not
explicitly specify a type, and both text and object types of the file
are available in the file system, load should try to select the more
appropriate file by some implementation-dependent means."

This is why it is unnecessary (in this case) for CL to specify the
file type for compiled files.  (It would be nice if CL defined
pathname defaults constants whose implementation dependent values had
the various file types, directories, etc in them, but they're not
needed in this case because load does the right thing.)

In other words, don't do the following:

>(require 'submodule 'submodule.fasl)

as (require 'submodule <expression whose value is a pathname for submodule
that doesn't specify the file type>) does the right thing and is portable.

Did the ANSI people really eliminate require and provide (or require's
second argument) because they couldn't figure this out, or was there
some other reason?  (If ANSI CL doesn't have pathname functions, or
ANSI found a hole in CL's, then that may explain it.  However, it
would be better for ANSI to include pathname functions or fix the
hole.)

-andy
UUCP:  {arpa gateways, decwrl, uunet, rutgers}!polya.stanford.edu!andy
ARPA:  andy@polya.stanford.edu
(415) 329-1718/723-3088 home/cubicle