Subject: [clisp-list] Re: proposal: probe-file -- major behavior change

From: Peter Wood <[email-masked]>
Date: Sun Feb 24 10:41:05 2002

On Sun, Feb 24, 2002 at 12:41:09AM -0500, Sam Steingold wrote:

<Lots of sensible things clipped>

Yes, please, Sam.  Thank you for listening.

Regards,
Peter

---

From: Peter Wood <[email-masked]>
Date: Wed Feb 27 00:19:04 2002

Hi,

On Tue, Feb 26, 2002 at 08:49:04PM -0500, Sam Steingold wrote:
> > * In message <[email-masked]>
> > * On the subject of "Re: proposal: probe-file -- major behavior change"
> > * Sent on 26 Feb 2002 17:44:16 -0500
> > * Honorable Raymond Toy <[email-masked]> writes:
> >
> > >>>>> "Sam" == Sam Steingold <[email-masked]> writes:
> > 
> >     Sam> In CL, there is a big difference between a file and a directory.
> > 
> > But a file is 
> > 
> >         a named entry in a file system, having an
> >         implementation-defined nature.
> > 
> > so I'm not sure what the right answer is.  I can't find the glossary
> > entry for directory.
> 
> on unix, there is really no difference between "/etc" and "/etc/".
> in CL, there is difference between #p"/etc" and #p"/etc/" wrt the
> values accessors and other functions return.
> 
> >     >> So maybe someone really wants to know that /etc exists?
> > 
> >     Sam> so how is the user supposed to find out whether /etc is a file or
> >     Sam> directory?
> >     Sam> both CLISP and CMUCL have non-portable ways to do that.
> >     Sam> I propose to make PROBE-FILE useable for that.
> > 
> > I don't know.  If CL doesn't specify a way to tell if /etc is a file
> > or directory, whatever you do is non-portable, so you might as well
> > make it non-portable.
> 

I disagree with this ...

> I prefer the occam's razor - do not multiply entities unnecessarily.
> if PROBE-FILE can be made to differenciate between the two, why invent
> a separate function?
> 

1) Use #'truename for this purpose.
   (truename #"/etc") => error, no file named etc 
   (truename #"/ptc") => error, no file named ptc
   (truename #"/etc/") => #/etc/

2) Occam's razor is good, but a  better principle in this case is
   that no system should require more information than is neccessary
   to make a reasonable decision.  Give the user leeway *unless* that
   will result in unreasonable decisions. No browser known to me
   insists on the trailing slash.

3) Use #'probe-file to see if a file/directory exists and return it's
   truename, if it does, or NIL otherwise.

Then a user can do this:

(defun dir? (name)
  (if (not (or (ignore-errors (truename name)) nil))
      (when (probe-file name) t)
    t))

which is still stupid, but better than what one has to do today to see
if a file/directory exists, allowing fair leeway in the designation of
the name.  (Of course, its easy with the libc6 bindings, and that
should raise an alarm.)

of course, if you kept #'probe-directory then the user could do:

(defun dir? (name)
  (let ((ford (probe-file name)))
    (when ford (probe-directory ford))))

Which is prettier, but unportable.

IMHO, my suggestion conforms to the spec, and allows a reasonable
degree of laxity in the naming of files/directories.

According to the spec: 

(probe-file pathspec) returns the actual name of PATHSPEC otherwise
NIL.
(truename filespec) returns the actual name of FILESPEC otherwise
ERROR.

A pathspec or filespec can be (amongst others) a namestring, which can
use the standardized notation for logical pathnames (!?!) OR (thank
God) an implementation-defined notation for naming a physical
pathname.  

So Clisp can say "common usage of pathnames on Unix is vague, and
allows for the ommission or inclusion of a trailing slash, however
#'truename implements a stricter interpretation of names, and returns
an error if a directory name does not have a trailing slash.  Use
#'truename if you need to use the strict interpretation to distinguish
between directories and files, and use #'probe-file if the vague
interpretation is sufficient."

Voila :-/

Regards,
Peter

---

From: Peter Wood <[email-masked]>
Date: Wed Feb 27 02:37:03 2002

On Wed, Feb 27, 2002 at 09:06:35AM +0100, I wrote:

> which is still stupid, 

Very, very stupid, as it won't work.  Silly me. Sorry.

I have tested the following, where #'exists? does the work which I
propose #'probe-file should do...

If #'probe-file accepts directories and files, with or without the
trailing slash and returns the actual pathname of the file/directory,
then one could test for a directory like this:

(defun dir? (n)
  (when (not (pathname-name (probe-file n))) t))

Tested:

[50]> (defun dir? (n)                                                                   (when (not (pathname-name (exists? n))) t))
dir?
[51]> (exists? ".inputrc")
#P"/home/prw/.inputrc"
[52]> (exists? ".dillo")
#P".dillo/"
[53]> (exists? "/etc")
#P"/etc/"
[54]> (exists? "/etc/")
#P"/etc/"
[55]> (exists? "/")
#P"/"
[56]> (exists? "no")
nil
[57]> (dir? ".inputrc")
nil
[58]> (dir? ".dillo")
t
[59]> (dir? "/etc")
t
[60]> (dir? "/")
t

Regards,
Peter