(make-pathname :directory '(:relative "foo")
:name "bar"
:defaults (user-homedir-pathname))
=> #p"foo/bar"
(merge-pathnames (make-pathname :directory '(:relative "foo")
:name "bar")
(user-homedir-pathname))
=> #p"/home/erik/foo/bar"
but this is not so in Allegro 4.3.1 for Unix or in CMUCL 17f, which agree
on the values.
the specification for `make-pathname' reads (quoted from the HyperSpec):
After the components supplied explicitly by HOST, DEVICE, DIRECTORY,
NAME, TYPE, and VERSION are filled in, the merging rules used by
`merge-pathnames' are used to fill in any _unsupplied_ components from
the defaults supplied by DEFAULTS. [my emphasis]
standing by itself, this could be taken to support the implementation in
ACL 4.3.1 and CMUCL 17f, but the specification for `merge-pathnames' reads:
Constructs a pathname from PATHNAME by filling in any _unsupplied_
components with the corresponding values from DEFAULT-PATHNAME and
DEFAULT-VERSION. [my emphasis]
which might be interpreted to mean that "unsupplied" in `make-pathname' and
`merge-pathnames' are the same, and then defined only in `merge-pathnames',
whose specification goes on to say:
Pathname merging treats a relative directory specially. If
(pathname-directory pathname) is a list whose car is :relative, and
(pathname-directory default-pathname) is a list, then the merged
directory is the value of
(append (pathname-directory default-pathname)
(cdr ;remove :relative from the front
(pathname-directory pathname)))
except [specification of :back processing].
which is clearly intended to _override_ the meaning of "unsupplied" in
entirely intuitive ways.
my question is whether the special treatment of relative directories also
overrides the "unsupplied" in `make-pathname' since it defers the handling
of "unsupplied" arguments to `merge-pathnames'. I would tend to think it
should. comments? (Kent?)
#\Erik
--
The year "98" was new 1900 years ago. | Help fight MULE in GNU Emacs 20!
Be year 2000 compliant, write "1998"! | http://sourcery.naggum.no/emacs/
Erik Naggum <cle...@naggum.no> writes:
> I'm a little confused about the `defaults' arguments to `make-pathname'.
> naďvely, I had imagined that the following two forms would yield the same
> value:
>
> (make-pathname :directory '(:relative "foo")
> :name "bar"
> :defaults (user-homedir-pathname))
> => #p"foo/bar"
>
This asks to take a given pathname and change specific components at
the structure level.
> (merge-pathnames (make-pathname :directory '(:relative "foo")
> :name "bar")
> (user-homedir-pathname))
> => #p"/home/erik/foo/bar"
This asks to semantically merge competing components from two pathnames.
Both kinds of operations need to be possible. One might argue that the
chosen mechanisms are not a perspicuous way to do the two operations
in question, but one definitely needs the ability two do either of two
distinguishable operations to get these two behaviors.
I consider the above examples "correct behavior" (although that doesn't
mean there can't be competing viewpoints :-)
> but this is not so in Allegro 4.3.1 for Unix or in CMUCL 17f, which agree
> on the values.
I assume the "this is not so" means your personal intuitions were not
supported.
>
> the specification for `make-pathname' reads (quoted from the HyperSpec):
>
> After the components supplied explicitly by HOST, DEVICE, DIRECTORY,
> NAME, TYPE, and VERSION are filled in, the merging rules used by
> `merge-pathnames' are used to fill in any _unsupplied_ components from
> the defaults supplied by DEFAULTS. [my emphasis]
This means that in your example above, DIRECTORY and NAME are filled, and
only HOST, DEVICE, TYPE, and VERSION follow the MERGE-PATHNAMES protocol.
> standing by itself, this could be taken to support the implementation in
> ACL 4.3.1 and CMUCL 17f, but the specification for `merge-pathnames' reads:
>
> Constructs a pathname from PATHNAME by filling in any _unsupplied_
> components with the corresponding values from DEFAULT-PATHNAME and
> DEFAULT-VERSION. [my emphasis]
Yeah, unsupplied in this context means those with value NIL.
Note in the above, though you didn't give an example,
(make-pathname :name NIL :defaults #P"X:foo") => #P"X:"
That is, it treats "unsupplied" as referring to explicit args, and :name IS
supplied. Whereas,
;; assumes default host is "X"
(merge-pathnames (make-pathname) #P"X:foo") => #P"X:foo"
(merge-pathnames (make-pathname :name nil) #P"X:foo") => #P"X:foo"
That is, the :name slot is NIL in the component from the first pathname,
and that's treated as unsupplied,
so the compoment for the second pathname is used instead.
> which might be interpreted to mean that "unsupplied" in `make-pathname' and
> `merge-pathnames' are the same, and then defined only in `merge-pathnames',
Well, I said you can create competing viewpoints. It's not the intended
viewpoint, though it's your right to disagree since the wording is what
counts. I just screwed up with the writing here--all the worse since this
issue came up before we froze the spec and I'd tried to repair it. I guess
I missed one. Sigh.
As a rule, if it helps, CLHS does not do what CLTL does of defining a
global term in a local place. It TRIES to migrate all global definitions
to the glossary and use local meanings of "unsupplied" only in a "lexical"
way. But that's nowhere expressed and can't be said to be a formal rule.
It's just something I tried informally to do because I hated that CLTL,
in textbook style, did otherwise.
> whose specification goes on to say:
>
> Pathname merging treats a relative directory specially. If
> (pathname-directory pathname) is a list whose car is :relative, and
> (pathname-directory default-pathname) is a list, then the merged
> directory is the value of
>
> (append (pathname-directory default-pathname)
> (cdr ;remove :relative from the front
> (pathname-directory pathname)))
>
> except [specification of :back processing].
>
> which is clearly intended to _override_ the meaning of "unsupplied" in
> entirely intuitive ways.
Yep. I should have just picked another word, though.
> my question is whether the special treatment of relative directories also
> overrides the "unsupplied" in `make-pathname' since it defers the handling
> of "unsupplied" arguments to `merge-pathnames'. I would tend to think it
> should. comments? (Kent?)
Nope. It is my belief that it is definitely the intention of the
committee that MAKE-PATHNAME do what you observe. I think your real
gripe is with that dummy of an editor (oops, that's me) who screwed up
the wording and made it hard to read.
I'll mark it for further clarification in that distant day where we do such
things.
this view does make sense and I accept that this is how things should be,
but now I wonder: are there any other :defaults arguments in the language
or in moderately wide use? I have not seen any. all I find in the CLHS
is the "defaulted initialization argument list", of which this seems like
a particularly practical form that I would have liked to be able to use
in many other cases, but I don't even see how I can (easily) create my
own :defaults argument that I could effectively copy from like
`make-pathname' does. suggestions?
| I consider the above examples "correct behavior" (although that doesn't
| mean there can't be competing viewpoints :-)
there is the issue of whether the competing viewpoints come from people
like me who are trying very hard to find a reason to believe their
personal intuitions are supported by the standard or from people whose
intuitions were supposed to become the standard... so, was there any
(serious) disagreement on this in X3J13 when the issue came up? if not,
who cares what kind of competing viewpoints outsiders come up with?
| Well, I said you can create competing viewpoints. It's not the intended
| viewpoint, though it's your right to disagree since the wording is what
| counts. I just screwed up with the writing here--all the worse since
| this issue came up before we froze the spec and I'd tried to repair it.
| I guess I missed one. Sigh.
I don't think this is true (about it being the wording that counts). if
I submit a request for clarification to ANSI, you get a second chance.
since the time I wrote that article and solicited comments from all over
the place, _nobody_ has disagreed with my analysis. it might be worth
our while to get this cleaned up formally and to explain the rationale
like you just did in this article through the accredited channels, too.
| Nope. It is my belief that it is definitely the intention of the
| committee that MAKE-PATHNAME do what you observe. I think your real
| gripe is with that dummy of an editor (oops, that's me) who screwed up
| the wording and made it hard to read.
now you're being grossly uncharitable to yourself. don't do that. ANSI
CL is an amazingly high-quality standard, and I have had to work my way
through so many standards that I have earned the right to compliment you
on this. that this is an editorial glitch that left room for a competing
viewpoint is not itself bad: it would have been bad if you couldn't argue
convincingly for your view or people could start to argue for a change of
semantics in contradiction to the committee intentions.
| I'll mark it for further clarification in that distant day where we do
| such things.
well, donning my standards committee hat, I'd have to comment that as per
ANSI rules, X3.226-1994 is due for a reaffirmation vote at the end of
1999. there is nothing to bar you from publishing corrigenda or
amendments at any time between such votes. however, I take it from this
and other comments that there haven't been any requests for clarification
addressed to X3J13 since its publication. that by itself is remarkable.
speaking of corrigenda, I have a couple of bug reports to file for the
application that made use of relative directories and the behavior I have
argued for and which no available Common Lisp implementation agreed with
so they implemented their own hacks. I'm glad I asked about this.
thanks for your clear answer this time around, too, Kent.