maverick@fir.Berkeley.EDU (Vance Maverick) (02/08/91)
It seems that ANSI is just dropping the module feature. Apparently we are all to roll our own. I quote: "XJ13 commented that the file-loading feature of REQUIRE is not portable, and that the remaining functionality is easily implemented by user code." (CLtLII p.277) This is true but a little unfriendly, and invites portability problems. Vance
pierson@encore.com (Dan L. Pierson) (02/13/91)
In article <10901@pasteur.Berkeley.EDU> maverick@fir.Berkeley.EDU (Vance Maverick) writes:
It seems that ANSI is just dropping the module feature. Apparently we
are all to roll our own. I quote: "XJ13 commented that the file-loading
feature of REQUIRE is not portable, and that the remaining functionality
is easily implemented by user code." (CLtLII p.277) This is true but a
little unfriendly, and invites portability problems.
The problem is that including REQUIRE *in the standard* enforces
portability problems. The argument goes like this:
1. The file loading feature of REQUIRE is speced to be non-portable,
"If the pathname argument is nil or is not provided, the sytem will
attempt to determine, in some system-dependent manner, which files
to load."
2. Some current implementations such as TI Explorer and Coral Common
Lisp (now Allegro Common Lisp for the Mac or some such), include
and depend heavily on powerful, useful, very system-dependent
implementations of the above. For example:
in Coral (require 'quickdraw) is the standard way to access the
Mac-specific graphics extensions.
3. A proposal to delete the second argument of REQUIRE and restrict it
to just the portable functionality was very strongly resisted by
the implementors who would be hurt by it.
4. (here is where it gets tricky) Standardizing REQUIRE including the
non-portable parts is a portability trap. Let's say you're
developing what you fondly think will be a large portable
application on an Explorer. Since REQUIRE is portable, you use it
in lots of places to ensure that your inter-module dependencies are
satisfied. It works just fine; everything you need is always
correctly loaded. Now you move your finished application to a
major stock-hardware Common Lisp (or worse, give it to someone else
to move). Everything breaks with a complex, undoumented network of
unsatisfied dependencies because REQUIRE on the Explorer not only
check to see if dependencies were satisfied, it fixed them up with
system-dependent magic. This is not a bad feature, but it *is* a
non-portable one. What fooled you was the official lie that
REQUIRE was a portable function that you could safely use in
portable code.
5. (the important part) Removing REQUIRE from the standard does not
mean that implementors must, or even should, remove it from their
implementations. It merely means that it should be described as
what it is: an implementation dependent extension. (The standard
does require that such symbols live in a package other than
COMMON-LISP. However, USER can use system-dependent packages so
authors of non-portable code shouldn't have to notice any change.)
--
dan
In real life: Dan Pierson, Encore Computer Corporation, Research
UUCP: {talcott,linus,necis,decvax}!encore!pierson
Internet: pierson@encore.com
jeff@aiai.ed.ac.uk (Jeff Dalton) (02/15/91)
In article <PIERSON.91Feb13104336@xenna.encore.com> pierson@encore.com (Dan L. Pierson) writes: >In article <10901@pasteur.Berkeley.EDU> maverick@fir.Berkeley.EDU (Vance Maverick) writes: > It seems that ANSI is just dropping the module feature. Apparently we > are all to roll our own. I quote: "XJ13 commented that the file-loading > feature of REQUIRE is not portable, and that the remaining functionality > is easily implemented by user code." (CLtLII p.277) This is true but a > little unfriendly, and invites portability problems. > >The problem is that including REQUIRE *in the standard* enforces >portability problems. The argument goes like this: > >1. The file loading feature of REQUIRE is speced to be non-portable, > "If the pathname argument is nil or is not provided, the sytem will > attempt to determine, in some system-dependent manner, which files > to load." [And then: some systems actually do determine which files to load in an interesting way. Some programmers might think that, because REQUIRE is part of standard CL, this interesting behavior is standard too. But it isn't. A proposal to make REQUIRE portable and thus rule out the interesting behavior provided by some systems was resisted. So it was decided to not make anything about REQUIRE standard and let implementations do whatever they wanted (as an extension to std CL).] I think this is the best explanation posted so far (thanks Dan!), and this is not the first time the issue has come up. On the whole, I think it probably _is_ better to take REQUIRE out of standard CL. It was confusing to call what PROVIDE and REQUIRE did "modules" (given what module means in languages that "have modules", such as Modula-II), and it was far from clear that PROVIDE and REQUIRE would fit into any good, portable system defining and building tools that were eventually developed. It used to be possible to write large-ish Franz Lisp programs using something sort of like REQUIRE (called "environment") together with a Makefile (Franz is Unix after all). In Common Lisp I eventually gave up and wrote a simple DEFSYSTEM. Still, I think REQUIRE could be used in that way, and the basic functionality of being able to tell if something has already been loaded is so generally useful that I think it's a shame not to have some standard way to do it. Moreover, it _is_ possible to use REQUIRE portable, or at least that's my interpretation of CLtL (and that of some other people who have posted in the past). In CLtL II, page 278, we find: The _pathname_ argument, if present, is a pathname or a list of pathnames whose files are to be loaded in order, left to right. If the _pathname_ argument is NIL or not provided, the system will attempt to determine, in some system-dependent manner, which files to load. I take it that this implies that if the _pathname_ argument is provided and is not NIL, then the system will load the specified file(s) and NOT attempt to determine, in some system-dependent manner, which files to load. I realize that it's possible to argue that when something says "If X then Y. If not X then Z" that this doesn't strictly imply that if X, then Z won't be done; but I think such a reading would be a little perverse. We could go on to say that _pathnames_ aren't portable, but I don't think that's very convincing. So, I think it's understandable that some people would think X3J13's decision to de-standardize REQUIRE was a bit arbitrary and against the interests of users. I think it's understandable but, as I said, on balance I think the decision was correct. All that's lacking is a complete explanation, which I think we now almost have. -- Jeff