*load-pathname* and *load-truename* nil on compiled file
Zulu-Inuoe opened this issue · comments
Hello!
It seems that load
is not properly binding *load-pathname*
and *load-truename*
when calling a compiled file.
Create a file:
(print "Printing..")
(print *load-pathname*)
(print *load-truename*)
(print *compile-file-pathname*)
(print *compile-file-truename*)
(print "Done")
(terpri)
At the repl:
;; Corman Lisp 3.1 (Patch level 2)
;; Copyright (c) Corman Technologies Inc. See LICENSE.txt for license information.
;; User: Zulu.
Type :quit to exit.
?(load "test.lisp")
"Printing.."
#P"C:\Users\Zulu\test.lisp"
#P"C:\Users\Zulu\test.lisp"
NIL
NIL
"Done"
7
?(compile-file "test.lisp")
"Printing.."
NIL
NIL
#P"C:\Users\Zulu\test.lisp"
#P"C:\Users\Zulu\test.lisp"
"Done"
#P"C:\Users\Zulu\test.fasl"
NIL
NIL
?(load "test.fasl")
"Printing.."
NIL
NIL
NIL
NIL
"Done"
7
?
Thanks for reporting this.
Could you verify if the attached build works as expected?
Not a problem. And the attached build does work.
Thank you!
There is a somewhat related issue in that according to http://clhs.lisp.se/Body/v_ld_pns.htm:
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)).
Likewise for*compile-file-pathname*
But I'll open up a separate issue for that, and it's less of a priority since I doubt many people make use of *load-pathname*
and *compile-file-pathname*
. Especially since a lot of impls seem to not do the same thing.
Thanks!
@Zulu-Inuoe what values for *load-pathname*
and *compile-file-pathname*
seem reasonable for you?
@arbv The standard calls for them to be (pathname (merge-pathnames filespec))
, filespec
being the original object given to load
or compile-file
On Corman, notice what (pathname (merge-pathnames ..))
gives:
?*default-pathname-defaults*
#P"C:\Users\Zulu\Desktop\Corman Lisp\"
?(pathname (merge-pathnames "../test"))
#P"C:\Users\Zulu\Desktop\Corman Lisp\..\test"
Now with the file C:\Users\Zulu\Desktop\test.lisp
containing the code:
(eval-when (:compile-toplevel :load-toplevel :execute)
(format t "load-pathname: ~A~%" *load-pathname*)
(format t "load-truename: ~A~%" *load-truename*)
(format t "compile-file-pathname: ~A~%" *compile-file-pathname*)
(format t "compile-file-truename: ~A~%" *compile-file-truename*))
on Corman I see this:
?(load "../test")
load-pathname: #P"C:\Users\Zulu\Desktop\test.lisp"
load-truename: #P"C:\Users\Zulu\Desktop\test.lisp"
compile-file-pathname: NIL
compile-file-truename: NIL
I would instead expect *load-pathname*
to be as the previous example:
#P"C:\Users\Zulu\Desktop\Corman Lisp\..\test"
compile-file
yields similar results:
?(compile-file "../test")
load-pathname: NIL
load-truename: NIL
compile-file-pathname: #P"C:\Users\Zulu\Desktop\test.lisp"
compile-file-truename: #P"C:\Users\Zulu\Desktop\test.lisp"
Also, I wanted to note that as of the fixed build you sent me, this is what load
yields on a compiled file:
?(load "../test")
load-pathname: #P"C:\Users\Zulu\Desktop\test.fasl"
load-truename: #P"C:\Users\Zulu\Desktop\test.fasl"
compile-file-pathname: NIL
compile-file-truename: NIL
So *load-truename*
is correct, but *load-pathname*
is not.
@Zulu-Inuoe
So, if I understand you correctly:
*load-pathname*
should contain the same exact path as the argument to load.*load-truename*
contains the expected value.
Is the above written correct?
- No.
*load-pathname*
should contain the exact same value as(pathname (merge-pathnames <arg-to-load>))
- Correct.
According to the hyperspec
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)).
By the way. I noticed that SBCL also has a different behaviour from the spec and wrote up an issue. You may want to read a bit of the responses from Richard Kreuter and myself.
You can find the issue page for that here: https://bugs.launchpad.net/sbcl/+bug/1817320
And I want to reiterate as I did there: I don't think this is a particularly important issue. Just one I noticed and got me curious.
Here's a quick summary of what I've found so far with the value of *load-pathname*
and *compile-file-pathname*
on different impls:
- CLISP: Binds
*load-pathname*
to itstruename
, and*compile-file-pathname*
to the spec value - Clozure CL: Matches spec
- Corman CL: Seems to bind both to their
truename
- LispWorks: Matches spec
- SBCL: -Almost- matches spec: Everything is correct except that when the arg to
load
has no type, it is assigned by SBCL according to their search result
1. No. `*load-pathname*` should contain the exact same value as `(pathname (merge-pathnames <arg-to-load>))`
That is what I meant. Sorry for being too lazy to describe it better.
Thank you for investigating the issue so thoroughly. Can you verify if the attached build works as expected?
I have fixed another, very related bug which would cause the previous build to not work properly (see 67798bf).
The new build seems to work in exactly the same way as SBCL does and it follows the spec (as far as I can tell):
http://www.lispworks.com/documentation/HyperSpec/Body/v_ld_pns.htm#STload-pathnameST
During a call to load, *load-pathname* is bound to the pathname denoted by the the first argument to load, merged against the defaults;
There is a subtle difference between how it works now and how we wanted it to work.
Can you test the attached build? Is it an acceptable behaviour for you?
@arbv Sorry about the delay. I was just able to test it and it works exactly as in the spec.
I don't see what you mean by
There is a subtle difference between how it works now and how we wanted it to work.
It seems to do exactly what the spec asks for. As per SBCL, SBCL actually differs from the spec:
Corman CL (this latest version):
?(pathname (merge-pathnames "test"))
#P"C:\Users\Zulu\Desktop\test"
?(load "test")
load-pathname: #P"C:\Users\Zulu\Desktop\test"
load-truename: #P"C:\Users\Zulu\Desktop\test.lisp"
SBCL:
* (pathname (merge-pathnames "test"))
#P"C:/Users/Zulu/Desktop/test"
* (load "test")
load-pathname: C:/Users/Zulu/Desktop/test.lisp
load-truename: C:/Users/Zulu/Desktop/test.lisp
^ Notice that they append the .lisp :type
to *load-pathname*
. So not technically meeting spec.
CCL:
? (pathname (merge-pathnames "test"))
#P"test"
? (load "test")
load-pathname: test
load-truename: C:/Users/Zulu/Desktop/test.lisp
LispWorks:
CL-USER 1 > (pathname (merge-pathnames "test"))
#P"test"
CL-USER 2 > (load "test")
load-pathname: test
load-truename: C:\Users\Zulu\Desktop\test.lisp
In all of these, except SBCL, *load-pathname*
is identical to (pathname (merge-pathnames "test"))
Note that it doesn't matter whether that results in #P"test"
or #P"C:\Users\Zulu\Desktop\test"
What matters is that they match, which is why SBCL technically doesn't meet spec (since it produces a different value)
I don't see what you mean by
There is a subtle difference between how it works now and how we wanted it to work.
Oh sorry, the confusion comes from my poor understanding of how MERGE-PATHNAMES
works: I thought it ought to convert the string arguments to a pathname without changes and it is the required behaviour. It turned out that a value from *default-pathname-defaults*
might be prepended to it. Nevermind.
I am happy that the issue has been resolved.
Investigating this bug was productive - in the end, the 3 related bugs got revealed and fixed:
- Wrong value in
*load-pathname*
; - Wrong value in
*compile-file-pathname*
; - Wrong value in
*default-pathname-defaults*
.
They seem like not very important, but the fact that you stumbled upon them leads to the conclusion that they might be more important than they seem at first.
Thank you for your help!