I wonder if any of you can lend me a clue. I'm trying to use the
function DIRECTORY to get a listing of files. In CMUCL, it behaves
like this:
* (lisp-implementation-version)
"18d-pre, level-1 built 2002-04-04 on sydney"
* (directory "/home/tim/wonka/")
(#p"/home/tim/wonka/CVS/" #p"/home/tim/wonka/ddl/" #p"/home/tim/wonka/docs/"
#p"/home/tim/wonka/htdig/" #p"/home/tim/wonka/lib/"
#p"/home/tim/wonka/manual/" #p"/home/tim/wonka/src/"
#p"/home/tim/wonka/webapp/")
* (directory "/home/tim/wonka/*")
(#p"/home/tim/wonka/CVS/" #p"/home/tim/wonka/ddl/" #p"/home/tim/wonka/docs/"
#p"/home/tim/wonka/htdig/" #p"/home/tim/wonka/lib/"
#p"/home/tim/wonka/manual/" #p"/home/tim/wonka/src/"
#p"/home/tim/wonka/webapp/")
*
And in CLISP, like this:
[43]> (lisp-implementation-version)
"2.26 (released 2001-05-23) (built on ragsdale.suse.de [127.0.0.2])"
[44]> (directory #p"/home/tim/wonka/")
(#P"/home/tim/wonka/")
[45]> (directory #p"/home/tim/wonka/*")
NIL
[46]>
The CLISP behavior seems dain bramaged to me. It would actually be
handy if the function gave back a little more information than I put
in. Is there a good reason for it? (I.e. Is it a feature, or a bug?)
Thanks,
Tim
--
Turing Stable: (adj) The property of continuing to be Turing complete,
after running for an hour.
This issue is one where lisp implementors on Unix are slightly doomed
to lose, no matter what they do.
"/home/tim/wonka/" is a designator for the pathname (loosely, ignoring
hosts and other confusions):
#s(pathname :directory (:absolute "home" "tim" "wonka")
:name nil :type nil :version nil)
As such, it isn't (necessarily) a wild pathname, and so (arguably)
the call to directory should return a list of one value. Here I
agree with clisp's behaviour; otherwise there is a great potential for
confusion over the difference between (directory "/home/tim/wonka")
and (directory "/home/tim/wonka/").
"/home/tim/wonka/*" is a designator for the pathname:
#s(pathname :directory (:absolute "home" "tim" "wonka")
:name :wild :type nil :version nil)
As such, directories in the "/home/tim/wonka/" directory do not
necessarily match the above wild pathname, and so need not show up in
the return value of directory; since you have no regular files in
"/home/tim/wonka", you get a NIL return value. Here, I think clisp is
being slightly unhelpful, though certainly within the standard; the
problem with clisp's behaviour is that it is impossible to get a list
of directories.[*]
Oh, and don't forget that the value of *default-pathname-defaults* has
a bearing on all this, too; better make sure that it doesn't contain a
pathname with a type. :-)
Cheers,
Christophe
[*] This may not be the same in the current released version of clisp.
--
Jesus College, Cambridge, CB5 8BL +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/ (defun pling-dollar
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)
> "/home/tim/wonka/*" is a designator for the pathname:
> #s(pathname :directory (:absolute "home" "tim" "wonka")
> :name :wild :type nil :version nil)
>
> As such, directories in the "/home/tim/wonka/" directory do not
> necessarily match the above wild pathname, and so need not show up in
> the return value of directory; since you have no regular files in
> "/home/tim/wonka", you get a NIL return value. Here, I think clisp is
> being slightly unhelpful, though certainly within the standard; the
> problem with clisp's behaviour is that it is impossible to get a list
> of directories.[*]
[...]
> [*] This may not be the same in the current released version of clisp.
Playing a bit with an older clisp (the one that
comes default with Debian). Take a look at prompts
[6] & [7]
[1]> (lisp-implementation-version)
"1999-07-22 (July 1999)"
[2]> (setf p1 (make-pathname :directory '(:absolute "home" "emf" "lisp")))
#P"/home/emf/lisp/"
[3]> (directory p1)
(#P"/home/emf/lisp/")
[4]> (setf p2 (make-pathname :directory '(:absolute "home" "emf" "lisp") :name :wild))
#P"/home/emf/lisp/*"
[5]> (directory p2)
(#P"/home/emf/lisp/fast-test.pgm" #P"/home/emf/lisp/ACL-Exercises-Ray.x86f"
#P"/home/emf/lisp/test.pgm" #P"/home/emf/lisp/ACL-Code-Ray.x86f"
#P"/home/emf/lisp/ACL-Exercises-Ray.lisp"
#P"/home/emf/lisp/ACL-Code-Ray.lisp" #P"/home/emf/lisp/play-array.x86f"
#P"/home/emf/lisp/play-array.lisp" #P"/home/emf/lisp/cl_shell.tgz"
#P"/home/emf/lisp/testing.lisp"
)
[6]> (setf p3 (make-pathname :directory '(:absolute "home" "emf" "lisp" "*")))
#P"/home/emf/lisp/*/"
[7]> (directory p3)
(#P"/home/emf/lisp/cl-http/")
The results look very consistent to me.
The same is true in my W2K machine with clisp 2.27
--
Eduardo Muñoz
That's the ticket! Thanks!
It's unfortunate that CMUCL and CLISP differ on this behavior. It's
also a little strange (to me) that, if the filename is "*", it becomes
:wild, but if the last directory is "*", it does not.
It's a shame, but it seems as though there is no trivial, idiomatic
way to recurse over a filesystem within the CL standard. Something to
note for CLTL3, perhaps. :)
-Tim
> "Eduardo Muñoz" <e...@jet.es> writes:
>
> > [6]> (setf p3 (make-pathname :directory '(:absolute "home" "emf" "lisp" "*")))
> > #P"/home/emf/lisp/*/"
> > [7]> (directory p3)
> > (#P"/home/emf/lisp/cl-http/")
> >
> > The results look very consistent to me.
> >
> > The same is true in my W2K machine with clisp 2.27
>
> That's the ticket! Thanks!
>
> It's unfortunate that CMUCL and CLISP differ on this behavior. It's
> also a little strange (to me) that, if the filename is "*", it becomes
> :wild, but if the last directory is "*", it does not.
I think clisp is being a bit forgiving here. Nothing wrong with that,
but for "portable" behaviour, in as much as that is possible when
dealing with something as inherently unportable as filesystem access,
your [6] above should look like
(... :directory '(:absolute "home" "emf" "lisp" :wild))
as implementations would be perfectly justified in treating that "*"
as naming a directory. (Don't forget that Unix directories _can_ have
ostensibly wild-looking names).
That is, implementations would be perfectly justified in doing:
* (make-pathname :directory '(:absolute "*"))
#P"/\\*/"
* (directory *)
NIL
[ if you disagree, let me know, because that's what SBCL does :-) ]
Christophe
> I think clisp is being a bit forgiving here. Nothing wrong with that,
> but for "portable" behaviour, in as much as that is possible when
> dealing with something as inherently unportable as filesystem access,
> your [6] above should look like
> (... :directory '(:absolute "home" "emf" "lisp" :wild))
> as implementations would be perfectly justified in treating that "*"
> as naming a directory. (Don't forget that Unix directories _can_ have
> ostensibly wild-looking names).
>
> That is, implementations would be perfectly justified in doing:
>
> * (make-pathname :directory '(:absolute "*"))
> #P"/\\*/"
> * (directory *)
> NIL
>
> [ if you disagree, let me know, because that's what SBCL does :-) ]
I don't disagree. It seems portable and intuitive
(I even tried it but it's illegal in Clisp).
Along these lines a thougth something similar
yesterday:
(make-pathname :directory '(:absolute "tmp") :name :wild :type :directory)
should be valid and return a list with the
directories within /tmp
But then, what do I know? I'm just a newbie trying
to explaim myself in an extrange language at an
USENET group full of grammar experts ;)
--
Eduardo Muñoz
I don't agree: that's a wild pathname. The definition of wild in the
standard's glossary just says it means it might match multiple
pathnames. In DIRECTORY, it definitely will, since PATHNAME-MATCH-P
must agree with DIRECTORY, and in PATHNAME-MATCH-P, missing components
default to :WILD.
However, "/home/tim/wonka/" doesn't necessarily designate that
pathname, an implementation could decide that it means that directory
only and return
#s(pathname :directory (:absolute "home" "tim" "wonka")
:name :unspecific :type :unspecific :version :unspecific)
(I don't actually recommend this.)
It's better to work with pathnames than namestrings, whenever
possible, since the mapping cannot be 1-to-1. Only use namestrings to
communicate with the user.
> Oh, and don't forget that the value of *default-pathname-defaults* has
> a bearing on all this, too; better make sure that it doesn't contain a
> pathname with a type. :-)
That's a good way to confuse any program that uses pathnames :-).
--
Pekka P. Pirinen
Don't pay for junk email. It's your private mailbox, and they're abusing
it. If you don't complain, they'll do it again. Don't hit delete, get
*them* deleted. See <http://www.uk.spam.abuse.net/spam/> for info.