Incorrect values for *load-pathname* and *compile-file-pathname*
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Won't Fix
|
Undecided
|
Unassigned |
Bug Description
Hello!
Given a file 'C:/test-
(eval-when (:compile-toplevel :load-toplevel :execute)
(format t "load-pathname: ~A~%" *load-pathname*)
(format t "load-truename: ~A~%" *load-truename*)
(format t "compile-
(format t "compile-
and *default-
#P"C:/test-
I am seeing this at the repl:
* (load "../test")
load-pathname: C:/test-
load-truename: C:/test-
compile-
compile-
* (compile-file "../test")
load-pathname: NIL
load-truename: NIL
compile-
compile-
* (load "../test")
load-pathname: C:/test-
load-truename: C:/test-
compile-
compile-
(chopped off uninteresting bits)
According to http://
During a call to load, *load-pathname* is bound to the pathname denoted by the the first argument to load, merged against the defaults; that is, it is bound to (pathname (merge-pathnames filespec)).
And Similarly for *compile-
I'd expect then for *load-pathname* and *compile-
* (pathname (merge-pathnames "../test"))
#P"C:/test-
rather than
#p"C:/test-
#p"C:/test-
#p"C:/test-
as above.
Thanks!
2. SBCL 1.4.16
3. Windows 10 x64
4.
(:X86-64 :64-BIT :64-BIT-REGISTERS :ALIEN-CALLBACKS :ANSI-CL :AVX2
:C-STACK-
:CYCLE-COUNTER :FP-AND-
:INTEGER-EQL-VOP :LINKAGE-TABLE :LITTLE-ENDIAN :OS-PROVIDES-DLOPEN
:OS-PROVIDES-PUTWC :PACKAGE-
:SB-DYNAMIC-CORE :SB-EVAL :SB-FUTEX :SB-LDB :SB-PACKAGE-LOCKS :SB-QSHOW
:SB-SAFEPOINT :SB-SAFEPOINT-
:SB-SOURCE-
:SB-XREF-
:STACK-
:STACK-
:UNDEFINED-
Changed in sbcl: | |
status: | New → Won't Fix |
You're correct that the current behavior doesn't conform, but is there any practical benefit to having #P"C:/test- dir/test- subdir/ test" in the -PATHNAME* variables?
Here's why I ask: the result of (pathname (merge-pathnames pathspec)) is merely an intermediate value that's used as input to logic that selects what file to address inside COMPILE-FILE and LOAD. The pathname that SBCL uses is computed by implementation- dependent means, and not accessible by any other interface. On SBCL, the computation goes like this, I believe:
1. For (let ((*default- pathname- defaults* #P"/tmp/")) (compile-file "test")), SBCL will
1a. try compiling a file addressible with a pathname that has NIL for the type,
1b. if no such file exists, try compiling a file addressible by a pathname whose type is "lisp".
2. For (let ((*default- pathname- defaults* #P"/tmp/")) (load "test")), SBCL will
2a. try loading a file addressible by a pathname that has NIL for the type,
2b. if there are files addressible by pathnames whose types are "lisp" and "fasl", then if the file addressible with the "fasl" type is newer than the one with the "lisp" type, load the "fasl" file, otherwise error (which error has associated restarts, so either file might get loaded);
2c. if there's only one file addressible by a pathname whose type is either "lisp" or "fasl", load that file.
The current SBCL behavior binds the respective -PATHNAME* variables to the result of the above logic, and so within COMPILE-FILE and LOAD, the appropriate variable's value is the pathname that SBCL truly used to open a file for input.
So I think the question is when is the CLHS-specified value ever useful? The CLHS-specified pathname can't be used to determine what file is currently being compiled or loaded: while the user could reimplement the above logic, user code run during LOAD can't determine whether a restart was selected at the beginning of LOAD; and anyway for both COMPILE-FILE and LOAD the SBCL picks a pathname based on the contents of the file system at the start of the function, so repeating the logic isn't guaranteed to yield the same result later on. By, contrast if the user wants a pathname that has the defaulted device, directory, and name components of the file being used, but an unfilled type and version, that's available conformingly with MAKE-PATHNAME using the current values of the -PATHNAME* variables as the default.
So those are arguments that the CLHS specified behavior is less than the current behavior. For these reasons, I'd favor documenting SBCL's current behavior as an exception under 1.5.1.5.
(Editorial: Certainly a conforming program shouldn't depend on any implementation doing something useful but non-conforming. However, it looks like some other implementations bind the -PATHNAME* variables the way SBCL does, and others can be said to comply with CLHS. So for a program that aspires to be portable, this is already de facto sharpsign- plus/minus territory. So there are already two options out there, and, I claim, the current SBCL behavior is more useful than the other. Maybe it'd be most fruitful to lobby the implementations that do conform with CLHS in this detail to change their ...