I have a question, whether this is intended by the language or whether this is kind of an unexpected/unwanted behavior/ BUG in Common Lisp.
However, I observed it in both: CLISP and SBCL:
I thought,
(make-pathname :directory (pathname-directory my-directory-path))
is/should be complimentary in all OS.
In Linux and MacOS it is.
But in Windows, you loose the information about the drive letter:
(pathname-directory #P"C:/Users/me/test/")
;;=> (:ABSOLUTE "Users" "me" "test") ;;=> Drive letter "c:" is lost!
Whereas, if you use ~
, you can keep it.
(pathname-directory #P"~/test/")
;;=> (:ABSOLUTE :HOME "test")
(make-pathname :directory (pathname-directory #P"~/test/"))
;;=> #P"~/test/" ;; no information loss!
(make-pathname :directory (pathname-directory #P"c:/Users/me/test/"))
;;=> #P"/Users/me/test/" ;;=> information loss - and not only that
;; it became an invalid path now, since the drive letter is lost!
Isn’t this actually a bug in the language specification? (Because Windows was not existent or such?).
2
Unix doesn’t have anything analogous to drive letters, so it doesn’t make sense to say that this is retained on Unix.
I’d expect the driver letter to correspond to the device
field in CL pathnames. So you need to copy that as well:
(MAKE-PATHNAME :directory (pathname-directory my-directory-path)
:device (pathname-device my-directory-path))
5
Just to round out the fine answer by @Barmar, the following quote is from Practical Common Lisp:
On Unix file systems, only the directory, name, and type components are typically used. On Windows, one more component–usually the device or host–holds the drive letter. On these platforms, a namestring is parsed by first splitting it into elements on the path separator–a slash on Unix and a slash or backslash on Windows. The drive letter on Windows will be placed into either the device or the host component. All but the last of the other name elements are placed in a list starting with :absolute or :relative depending on whether the name (ignoring the drive letter, if any) began with a path separator. This list becomes the directory component of the pathname. The last element is then split on the rightmost dot, if any, and the two parts put into the name and type components of the pathname.7
Common Lisp pathnames are not specific to any operating system, but attempt to provide enough general functionality to accommodate any operating system. To accomplish this, the standard allows Lisp implementations to do things differently. Read more here:
https://gigamonkeys.com/book/files-and-file-io