unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Null filename ("") is considered to correspond to an existing, readable, and writable file?
@ 2006-01-02 22:57 Drew Adams
  2006-01-03  1:22 ` Luc Teirlinck
  0 siblings, 1 reply; 22+ messages in thread
From: Drew Adams @ 2006-01-02 22:57 UTC (permalink / raw)


The following expressions all return true (on Windows, at least). I imagine
that this is by design (it is an old policy), but I don't understand the
reason for this.

 (file-exists-p "")
 (file-readable-p "")
 (file-writable-p "")

How often would someone want a null filename to be considered to correspond
to an existing, readable, or writable file?

This means that code that tests a filename needs to do something like this:

 (and (not (string= "" name)) (file-readable-p name))

For example, when prompting a user for the name of a readable file, I guess
you need to do something like this:

(while (or (string= "" name) (not (file-readable-p name)))
  (setq name (read-file-name prompt...)))

Why?

This behavior also seems to contradict the doc strings. They say clearly
that the file with the given name really exists, is really readable, or is
really writable.

Also, the doc strings and the manual say nothing about using a default
directory (yes, apparently) or whether the FILENAME argument must include a
directory (it need not, apparently).

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-02 22:57 Null filename ("") is considered to correspond to an existing, readable, and writable file? Drew Adams
@ 2006-01-03  1:22 ` Luc Teirlinck
  2006-01-03  3:27   ` Drew Adams
  0 siblings, 1 reply; 22+ messages in thread
From: Luc Teirlinck @ 2006-01-03  1:22 UTC (permalink / raw)
  Cc: emacs-devel

Drew Adams wrote:

   The following expressions all return true (on Windows, at least). I imagine
   that this is by design (it is an old policy), but I don't understand the
   reason for this.

    (file-exists-p "")
    (file-readable-p "")
    (file-writable-p "")

   How often would someone want a null filename to be considered to correspond
   to an existing, readable, or writable file?

The empty string is a relative file name.  It is the current
directory, given be the buffer-local variable default-directory.  Just
do `M-: (find-file "").  There can not be any file with a "null" file
name other than the current directory.

   Also, the doc strings and the manual say nothing about using a default
   directory (yes, apparently) or whether the FILENAME argument must include a
   directory (it need not, apparently).

It would get rather tedious if every single docstring of any function
handling files had to explain the difference between relative and
absolute file names and if all these docstrings had to document the
variable default-directory.

The Elisp manual talks about relative and absolute file names and
documents default-directory.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03  1:22 ` Luc Teirlinck
@ 2006-01-03  3:27   ` Drew Adams
  2006-01-03  4:41     ` Luc Teirlinck
                       ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03  3:27 UTC (permalink / raw)


       The following expressions all return true (on Windows, at
       least). I imagine that this is by design (it is an old policy),
       but I don't understand the reason for this.

        (file-exists-p "")
        (file-readable-p "")
        (file-writable-p "")

       How often would someone want a null filename to be
       considered to correspond to an existing, readable,
       or writable file?

    The empty string is a relative file name.  It is the current
    directory, given be the buffer-local variable default-directory.  Just
    do `M-: (find-file ""). There can not be any file with a "null" file
    name other than the current directory.

Fine. It should be documented. There are plenty of functions that take an
absolute file-name argument, and others that take a relative file-name
argument. The doc for these particular functions should say that the
argument must be a relative file name.

And they should explicitly point out the case of "". All the more so because
their names can easily mislead you into thinking that an argument of "" will
return a nil result.

`file-writable-p' is not `find-file'.

       Also, the doc strings and the manual say nothing about using
       a default directory (yes, apparently) or whether the FILENAME
       argument must include a directory (it need not, apparently).

    It would get rather tedious if every single docstring of any function
    handling files had to explain the difference between relative and
    absolute file names and if all these docstrings had to document the
    variable default-directory.

Tedious, perhaps, but it is, first of all, a reference manual. Many people
will not read it in a linear fashion, front to back. When I want to know
what a function does and how to use it, I look up that function.

Besides, where is the section of the manual that says that, unless stated
otherwise, all file-name arguments to functions are relative, and they are
all relative to the `default-directory'?

    The Elisp manual talks about relative and absolute file names and
    documents default-directory.

Yes, of course it does. So what? It talks about lists and faces too, but
that doesn't mean that the doc for a function shouldn't specify what its
arguments are.

Beyond the doc, wouldn't you expect functions with these names to return nil
for a "" argument? What's the purpose of not checking this case, correctly
applying the meaning of the function's name and returning nil?

Is it so that you can use (file-exists-p "") to test the existence of
directory `default-directory'? What's the advantage of such a "feature"?
There are other, more readable ways to test that: (file-exists-p
default-directory), for instance.

Sorry, I still don't get it. Why is the design like this?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03  3:27   ` Drew Adams
@ 2006-01-03  4:41     ` Luc Teirlinck
  2006-01-03  8:24       ` Drew Adams
  2006-01-03 18:13       ` Eli Zaretskii
  2006-01-03  4:56     ` Luc Teirlinck
  2006-01-03  5:32     ` Eli Zaretskii
  2 siblings, 2 replies; 22+ messages in thread
From: Luc Teirlinck @ 2006-01-03  4:41 UTC (permalink / raw)
  Cc: emacs-devel

Drew Adams wrote:

   Fine. It should be documented. There are plenty of functions that take an
   absolute file-name argument, and others that take a relative file-name
   argument. The doc for these particular functions should say that the
   argument must be a relative file name.

No, it does _not_ have to be a relative file name.  It is _allowed_ to
be.  If you do not want a relative file name, then why do you specify
one?  Just start your filename with ~ or /.  The _normal_ situation is
that both are accepted.  It are the exceptions that should be documented.

   And they should explicitly point out the case of "". All the more so because
   their names can easily mislead you into thinking that an argument of "" will
   return a nil result.

Why do you absolutely want to create files with the empty string as
name?  It does not work, at least not on POSIX systems.  Does it work
on MS Windows?

   Besides, where is the section of the manual that says that, unless stated
   otherwise, all file-name arguments to functions are relative, and they are
   all relative to the `default-directory'?

They are _not_ relative unless the docstring states otherwise.  They
are relative unless the file name specifies otherwise, that is, if the
file name starts with / or ~.  "" does not start with / or ~, hence it
is relative.  Read `(elisp)Relative File Names'.

   Yes, of course it does. So what? It talks about lists and faces too, but
   that doesn't mean that the doc for a function shouldn't specify what its
   arguments are.

But a function taking lists or faces as arguments should not explain
what lists and faces are.

   Beyond the doc, wouldn't you expect functions with these names to return nil
   for a "" argument?

Of course not.  If default-directory is "/mydir/", then "a" is the
file "/mydir/a", the concatenation of /mydir/" and "a".  Why would
you expect "" to be anything else but "/mydir/", the concatenation of
"/mydir/ and "" ?.

   Is it so that you can use (file-exists-p "") to test the existence of
   directory `default-directory'?

Of course.

   What's the advantage of such a "feature"?

That it makes sense and is consistent.

   Why is the design like this?

Because it is logical and consistent.  And it is POSIX's design, not Emacs'.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03  3:27   ` Drew Adams
  2006-01-03  4:41     ` Luc Teirlinck
@ 2006-01-03  4:56     ` Luc Teirlinck
  2006-01-03  5:32     ` Eli Zaretskii
  2 siblings, 0 replies; 22+ messages in thread
From: Luc Teirlinck @ 2006-01-03  4:56 UTC (permalink / raw)
  Cc: emacs-devel

Drew Adams wrote:

   Tedious, perhaps, but it is, first of all, a reference manual. Many people
   will not read it in a linear fashion, front to back. When I want to know
   what a function does and how to use it, I look up that function.

But if you do not know the basics about how file name arguments are
normally treated, you probably should more or less read the chapter on
files front to back.  It would look very silly to explain in each
function docstring that takes a file name as an argument, and in each
description of such a function in the Elisp manual, the difference
between absolute and relative file names, the difference between hard
and soft links, the meaning of ~ in a file name, what shell
environment variables are, how remote files are handled and
recognized, the meaning of `.' and `..', what wildcards are, what makes
a file name magic and so on and so on...

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03  3:27   ` Drew Adams
  2006-01-03  4:41     ` Luc Teirlinck
  2006-01-03  4:56     ` Luc Teirlinck
@ 2006-01-03  5:32     ` Eli Zaretskii
  2006-01-03  8:25       ` Drew Adams
  2 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2006-01-03  5:32 UTC (permalink / raw)
  Cc: emacs-devel

> From: "Drew Adams" <drew.adams@oracle.com>
> Date: Mon, 2 Jan 2006 19:27:56 -0800
> 
> Besides, where is the section of the manual that says that, unless stated
> otherwise, all file-name arguments to functions are relative

This is a basic notion of every filesystem: every file is relative to
the current directory, unless it begins with the root directory
string.  I don't thing the Emacs manual should teach such basics.

> and they are all relative to the `default-directory'?

In Emacs, `default-directory' is the variable that stores the current
directory that is in effect when you are in that file's buffer.  The
Emacs manual says in the node "File Names":

       Each buffer has a default directory which is normally the same as the
    directory of the file visited in that buffer.  When you enter a file
    name without a directory, the default directory is used.  If you specify
    a directory in a relative fashion, with a name that does not start with
    a slash, it is interpreted with respect to the default directory.  The
    default directory is kept in the variable `default-directory', which
    has a separate value in every buffer.

Clear enough?

> Beyond the doc, wouldn't you expect functions with these names to return nil
> for a "" argument? What's the purpose of not checking this case, correctly
> applying the meaning of the function's name and returning nil?
> 
> Is it so that you can use (file-exists-p "") to test the existence of
> directory `default-directory'? What's the advantage of such a "feature"?
> There are other, more readable ways to test that: (file-exists-p
> default-directory), for instance.
> 
> Sorry, I still don't get it. Why is the design like this?

This was discussed here some months ago, although I couldn't find that
thread in the few minutes I had to look for it.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03  4:41     ` Luc Teirlinck
@ 2006-01-03  8:24       ` Drew Adams
  2006-01-03 18:13       ` Eli Zaretskii
  1 sibling, 0 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03  8:24 UTC (permalink / raw)


    No, it does _not_ have to be a relative file name.  It is _allowed_ to
    be.  If you do not want a relative file name, then why do you specify
    one?  Just start your filename with ~ or /.  The _normal_ situation is
    that both are accepted.  It are the exceptions that should be
    documented.

Fine. That's exactly what I said, BTW: "The doc strings and the manual say
nothing about using a default directory (yes, apparently) or whether the
FILENAME argument must include a directory (it need not, apparently."

What should be documented is that an empty file name to these functions
tests for the existence, readability, and writability of the directory
(`default-directory').

Here's one of the doc strings (they're all similar):

 "Return t if file FILENAME exists (whether or not you can read it.)"

Substitute "" for FILENAME and re-read the doc: Return t if file "" exists.
Well, file "" does not exist, so the doc string suggests that nil is
returned. At the very least, that's a plausible way to read it. I'd say even
that it is the only reasonable interpretation of what is written.

Coming back to relative file names - what is the status of ""? It's true
that the manual says that any file name that doesn't start with / or ~ is
considered a relative file name. I'm not sure people will naturally think of
an empty file name that way, although, yes, an empty name does not start
with / (or anything else). And, yes, `file-name-absolute-p' returns nil for
"". I realize that that is the design. I'm not wild about that design, but
my real point is that this interpretation of "" might not be obvious to
everyone who uses these functions.

The Elisp manual says this, in fact:

  "An absolute file name starts with a slash or a tilde (`~'), and a
  relative one does not."

Fair enough. A relative name does not start with a / or ~. What _does_ it
start with? Trick question. Does this statement really, clearly say that a
name that does not start with anything at all is a relative name? Maybe, but
not very clearly, not explicitly.

Don't you agree that there is a legitimate reading of this - or at least an
illegitimate but natural reading of this - as saying that a relative file
name _starts with a character_ different from / and ~? Nothing is said about
the null case _explicitly_, so a reader must carefully read that any "name"
that does not start with / or ~ is a relative name - and that includes the
file "name" that is not a name: an empty string of characters. If someone
reads that definition with the (natural) idea that a name is a non-null
string, then he will not have made the right interpretation.

The rule (definition) might be a good one or it might be a bad one. It might
be arbitrary or well-designed. But it is not _obvious_ (meaning the only
reasonable, natural rule). And it is not expressed clearly enough.

Alternative reasonable definitions are conceivable. Here's one: file names
are non-null strings; an absolute file name is one that starts with
character blah; a relative file name is one that starts with any character
other than blah. The empty string by this definition names _no_ file; it is
_not_ a file name, just like many other strings that don't have proper
file-name syntax in some OSs.

My point is that we could be _clearer_ on this:

1) In the general presentation of absolute and relative file names, we
should explicitly point out that "" is considered to be a file name, and
that, because it does not start with / or ~, by the rule given it is a
relative file name.

2) Even if we point that out in the general definition, we should also point
it out in particular cases where there might naturally be confusion. And
this is one such case. When I see a function named `file-exists-p' that
takes a file name, I expect it to look for a file with that name in the
given directory. No file exists with an empty name in that directory (or in
any other), so I would expect it to return nil. Yes, I would need to be
reminded of the rule.

You can say that my expectation is incorrect, and you'll be correct. My
point is that I might not be the only one to interpret the description thus.
Don't you agree that some programmers will, even after reading this doc,
expect that (file-exists-p foo) will only return non-nil if there is in fact
a file named foo, regardless of foo's value? And there is no file named <no
name> (""), and that is a valid value for foo.

This is reference doc, but it's about communication. It's not a formal spec.
If we want to give just a formal definition (e.g. a grammar) and let people
figure it out, then fine, let's do that. The definition as given is not
formal, however, and it is open to interpretation (more than one
interpretation). So, let's help readers by interpreting it a little more
clearly: explicitly point out the null-name case.

The empty name is a legitimate relative file name in Emacs, so the file to
be tested is in fact this name tacked onto the directory name. We should
mention that explicitly, that's all. You can't use an empty file name that
way on the command line or in other common contexts - a file name there is
always non-empty, so not everyone will naturally make the right
interpretation of the empty "name" here.

       And they should explicitly point out the case of "". All the
       more so because their names can easily mislead you into
       thinking that an argument of "" will return a nil result.

    Why do you absolutely want to create files with the empty string as
    name?  It does not work, at least not on POSIX systems.  Does it work
    on MS Windows?

I don't want that. What gave you that idea? My point is precisely that there
is _no_ such file, as you confirm. It doesn't exist. It isn't readable. It
isn't writable. But our test functions say, by their _names_, that a file
named <no name> exists, it is readable, and it is writable. Yes, I know that
that is not what they really mean, but that is what their names say - at
least to some people.

I repeat my original example:

 (while (or (string= "" name) (not (file-readable-p name)))
   (setq name (read-file-name prompt...)))

This is the kind of thing you must write, because `file-readable-p' returns
non-nil for name="". I think it's regrettable - I still haven't heard any
advantage to this design - but so be it. My point is that this needs to be
pointed out.

       Besides, where is the section of the manual that says that,
       unless stated otherwise, all file-name arguments to functions
       are relative, and they are all relative to the
       `default-directory'?

    They are _not_ relative unless the docstring states otherwise.

Precisely. We depend on the doc string to let us know what an argument is. A
file-name argument could take any form - it depends on what the particular
_function_ expects. These particular functions, as you point out, accept
both relative and absolute names. I would expect a reference manual to say
that, and to point out (again) that as a result of the general rule that
says `"" is taken as a relative file name', the file tested is, in fact the
directory.

    They are relative unless the file name specifies otherwise, that is, if
the
    file name starts with / or ~.  "" does not start with / or ~,

Or / or \ or a drive specification (X:/ or X:\) or VMS's ...

    hence it is relative.  Read `(elisp)Relative File Names'.

See above.

       Beyond the doc, wouldn't you expect functions with these
       names to return nil for a "" argument?

    Of course not.  If default-directory is "/mydir/", then "a" is the
    file "/mydir/a", the concatenation of /mydir/" and "a".  Why would
    you expect "" to be anything else but "/mydir/", the concatenation of
    "/mydir/ and "" ?.

See above. You're just parroting the existing design (faithfully). I know
how it works. I'm talking about the expectation that someone might have when
he sees the _name_ `file-exists-p'. You are so familiar with the Emacs
interpretation of "relative file name" that you can't see that someone might
read the function name differently, given that there is nothing in the doc
string to teach him otherwise.  "" is _not_ a relative file name on Unix or
GNU/Linux or Windows or ... It is not so bizarre to think that a function
that tests for the existence of a file named <no name> would return nil, and
there is nothing in the doc string to dissuade such an interpretation.

       Is it so that you can use (file-exists-p "") to test the existence of
       directory `default-directory'?

    Of course.

       What's the advantage of such a "feature"?

    That it makes sense and is consistent.

Baloney. As I said, (file-exists-p default-directory) provides the same
functionality. There are lots of designs that make sense and are consistent.
What's the _advantage_ of this one?

       Why is the design like this?

    Because it is logical and consistent.  And it is POSIX's
    design, not Emacs'.

Hmm. I'm no expert on any of this. I just think the doc could be clearer.

However, googling for POSIX and "relative file name", I do see this, in "The
GNU C Library Reference Manual", section "Input/Output Overview"
(http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_6.html#SEC70):

  A file name that names a directory may optionally end in a `/'.
  You can specify a file name of `/' to refer to the root directory,
  but the empty string is not a meaningful file name. If you want to
  refer to the current working directory, use a file name of `.' or
  `./'.

The empty string is not only not a relative file name, it is not any file
name at all. The context here is specifically about POSIX (IIUC).

Reading other paragraphs in the same "File Names" section teaches me that 1)
a "file-name component" cannot be empty (multiple successive / are treated
as a single /), and 2) a "relative file name" starts with a file-name
component (a component which doesn't start with a /). To me, that implies 3)
that a relative file name in POSIX cannot be an empty string.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03  5:32     ` Eli Zaretskii
@ 2006-01-03  8:25       ` Drew Adams
  2006-01-03 15:50         ` Stefan Monnier
  2006-01-03 18:11         ` Eli Zaretskii
  0 siblings, 2 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03  8:25 UTC (permalink / raw)


    > Besides, where is the section of the manual that says that,
    > unless stated otherwise, all file-name arguments to functions
    > are relative

    This is a basic notion of every filesystem: every file is relative to
    the current directory, unless it begins with the root directory
    string.  I don't thing the Emacs manual should teach such basics.

That every file is relative to its directory is not the question. You guys
are adamant, but in contradictory ways.

To support the "obviousness" that all file-name arguments to all functions
are relative file names (which cannot be true, BTW), you provide the
platitude that all files are relative to their directory. Luc is adamant
that this file-name argument need _not_ be a relative file name.

Experiment shows that Luc is right on this one. But you make my point: the
doc for this function says nothing about its file-name argument, so it's
anyone's guess - try it and see...

    > and they are all relative to the `default-directory'?

    In Emacs, `default-directory' is the variable that stores the current
    directory that is in effect when you are in that file's buffer.  The
    Emacs manual says in the node "File Names":

Of course a file is relative to its directory. I know what
`default-directory' is.

           Each buffer has a default directory which is normally
        the same as the directory of the file visited in that buffer.
        When you enter a file name without a directory, the default
        directory is used. If you specify a directory in a relative
        fashion, with a name that does not start with a slash, it is
        interpreted with respect to the default directory.  The
        default directory is kept in the variable `default-directory', which
        has a separate value in every buffer.

    Clear enough?

Perfect. That paragraph, as you point out, is from the Emacs manual, not the
Elisp manual. It is about _entering_ file names in response to prompts. What
you enter is not necessarily what the function uses as an argument. The
paragraph is not about file-name arguments to Emacs-Lisp functions. And it
says only that relative file names are taken relative to the default
directory. It does not speak at all to the question at hand.

    > Beyond the doc, wouldn't you expect functions with these
    > names to return nil for a "" argument? What's the purpose
    > of not checking this case, correctly
    > applying the meaning of the function's name and returning nil?
    >
    > Is it so that you can use (file-exists-p "") to test the existence of
    > directory `default-directory'? What's the advantage of such a
    > "feature"?
    > There are other, more readable ways to test that: (file-exists-p
    > default-directory), for instance.
    >
    > Sorry, I still don't get it. Why is the design like this?

    This was discussed here some months ago, although I couldn't find that
    thread in the few minutes I had to look for it.

I already said that I assumed this was "by design". I asked what the design
_advantage_ is. No answer, so far.

Anyway, the design is as it is. My point was that the arguments to these
functions should be documented more clearly - in particular, the case of a
"filename" of "" should be mentioned - especially given the names of these
functions.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03  8:25       ` Drew Adams
@ 2006-01-03 15:50         ` Stefan Monnier
  2006-01-03 18:51           ` Drew Adams
  2006-01-03 18:11         ` Eli Zaretskii
  1 sibling, 1 reply; 22+ messages in thread
From: Stefan Monnier @ 2006-01-03 15:50 UTC (permalink / raw)
  Cc: emacs-devel

> I already said that I assumed this was "by design".  I asked what the design
> _advantage_ is. No answer, so far.

If you could give us some background as to why you care so much about the
way Emacs handles a file named "", maybe you'd be taken more seriously.

A file name "" is extrememly rare, so how we behave when facing such
a situation should be driven by the two following goals:
1 - avoid risks (e.g. try not to introduce security holes).
2 - try not to spend too much code&time on it.
I.e. the behavior should mostly be determined by the way the code makes it
work, as long as it makes sense and is not dangerous.


        Stefan

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03  8:25       ` Drew Adams
  2006-01-03 15:50         ` Stefan Monnier
@ 2006-01-03 18:11         ` Eli Zaretskii
  2006-01-03 18:51           ` Drew Adams
  2006-01-03 18:51           ` Drew Adams
  1 sibling, 2 replies; 22+ messages in thread
From: Eli Zaretskii @ 2006-01-03 18:11 UTC (permalink / raw)
  Cc: emacs-devel

> From: "Drew Adams" <drew.adams@oracle.com>
> Date: Tue, 3 Jan 2006 00:25:03 -0800
> 
>     > Besides, where is the section of the manual that says that,
>     > unless stated otherwise, all file-name arguments to functions
>     > are relative
> 
>     This is a basic notion of every filesystem: every file is relative to
>     the current directory, unless it begins with the root directory
>     string.  I don't thing the Emacs manual should teach such basics.
> 
> That every file is relative to its directory is not the question.

Perhaps it isn't, but your wording (above) suggested it was.  I'm
sure, if you re-read it, you will agree that it could be interpreted
like that.  Which is why I replied as I did.

> You guys are adamant, but in contradictory ways.

Could we please keep the attitude out of this?  You could imagine, I
think, that reading your complaints might be sometimes annoying no
less than reading my responses.  Let's try to stay focused on the
technical issues, and stay away of ad hominem, okay?

More to the point, Luc and myself don't coordinate our replies, and
respond to different parts of your messages, so there's no reason to
assume that we will offer similar arguments.

> But you make my point: the doc for this function says nothing about
> its file-name argument

You may wish to re-read my message, and then you will see that I did
not say anything about the function's doc string.  I responded to your
assertions and suggestions about the manual.

>            Each buffer has a default directory which is normally
>         the same as the directory of the file visited in that buffer.
>         When you enter a file name without a directory, the default
>         directory is used. If you specify a directory in a relative
>         fashion, with a name that does not start with a slash, it is
>         interpreted with respect to the default directory.  The
>         default directory is kept in the variable `default-directory', which
>         has a separate value in every buffer.
> 
>     Clear enough?
> 
> Perfect. That paragraph, as you point out, is from the Emacs manual, not the
> Elisp manual. It is about _entering_ file names in response to prompts. What
> you enter is not necessarily what the function uses as an argument. The
> paragraph is not about file-name arguments to Emacs-Lisp functions.

For the record, you said ``the manual'', and never hinted on a
specific one.

But okay, let's turn to the ELisp manual:

In "Relative File Names" we read:

    All the directories in the file system form a tree starting at the root
    directory.  A file name can specify all the directory names starting
    from the root of the tree; then it is called an "absolute" file name.
    Or it can specify the position of the file in the tree relative to a
    default directory; then it is called a "relative" file name.  On Unix
    and GNU/Linux, an absolute file name starts with a slash or a tilde
    (`~'), and a relative one does not.  On MS-DOS and MS-Windows, an
    absolute file name starts with a slash or a backslash, or with a drive
    specification `X:/', where X is the "drive letter".  The rules on VMS
    are complicated.

In "File Name Expansion" we read:

    "Expansion" of a file name means converting a relative file name to an
    absolute one.  Since this is done relative to a default directory, you
    must specify the default directory name as well as the file name to be
    expanded.  Expansion also simplifies file names by eliminating
    redundancies such as `./' and `NAME/../'.

    [...]

     -- Variable: default-directory
	 The value of this buffer-local variable is the default directory
	 for the current buffer.  It should be an absolute directory name;
	 it may start with `~'.  This variable is buffer-local in every
	 buffer.

Could you please state what is unclear in these fragments?

> And it says only that relative file names are taken relative to the
> default directory. It does not speak at all to the question at hand.

So what _is_ the question at hand, wrt the manual(s)?

>     > Sorry, I still don't get it. Why is the design like this?
> 
>     This was discussed here some months ago, although I couldn't find that
>     thread in the few minutes I had to look for it.
> 
> I already said that I assumed this was "by design". I asked what the design
> _advantage_ is. No answer, so far.

I tried to provide a pointer to the answer: if you find and read those
discussions, you might find it.  I didn't necessarily need a
thank-you, but something less unkind would be nice.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03  4:41     ` Luc Teirlinck
  2006-01-03  8:24       ` Drew Adams
@ 2006-01-03 18:13       ` Eli Zaretskii
  1 sibling, 0 replies; 22+ messages in thread
From: Eli Zaretskii @ 2006-01-03 18:13 UTC (permalink / raw)
  Cc: drew.adams, emacs-devel

> Date: Mon, 2 Jan 2006 22:41:51 -0600 (CST)
> From: Luc Teirlinck <teirllm@dms.auburn.edu>
> Cc: emacs-devel@gnu.org
> 
> Why do you absolutely want to create files with the empty string as
> name?  It does not work, at least not on POSIX systems.  Does it work
> on MS Windows?

Of course, it doesn't.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03 18:11         ` Eli Zaretskii
@ 2006-01-03 18:51           ` Drew Adams
  2006-01-03 19:13             ` Eli Zaretskii
  2006-01-03 18:51           ` Drew Adams
  1 sibling, 1 reply; 22+ messages in thread
From: Drew Adams @ 2006-01-03 18:51 UTC (permalink / raw)


    >     > Besides, where is the section of the manual that says that,
    >     > unless stated otherwise, all file-name arguments to functions
    >     > are relative
    >
    >     This is a basic notion of every filesystem: every file is
    >     relative to the current directory, unless it begins with the
    >     root directory string.  I don't thing the Emacs manual should
    >     teach such basics.
    >
    > That every file is relative to its directory is not the question.

    Perhaps it isn't, but your wording (above) suggested it was.  I'm
    sure, if you re-read it, you will agree that it could be interpreted
    like that.  Which is why I replied as I did.

I think you make my point.

My question was stated carefully in terms of "all file-name arguments to
functions", but you misread it as "all files" or perhaps "all file names".

My question says exactly what it means, but, as you point out, it is
possible to misread it (or to read it differently). That's exactly the point
I tried to make about the manual's definition of "relative file name" - it
is correct, but its implication for a null name ("") might not be clearly
understood by reading it.

If I had emphasized that I was speaking of file-name _arguments_, my
question might have been clearer. If the definition of "relative file name"
emphasizes the implication for "", it will be clearer.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03 18:11         ` Eli Zaretskii
  2006-01-03 18:51           ` Drew Adams
@ 2006-01-03 18:51           ` Drew Adams
  1 sibling, 0 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03 18:51 UTC (permalink / raw)


    In "Relative File Names" we read:
       <Elisp text defining relative and absolute file names>
    In "File Name Expansion" we read:
       <Elisp text on converting relative to absolute names>
    -- Variable: default-directory
       <definition of `default-directory'>

    Could you please state what is unclear in these fragments?

They are clear, as far as they go. As I said, the definition of relative is
essentially "every name that is not absolute". That is fine as a definition,
but it would be clearer to also explicitly point out that a null name ("")
is relative, because it does not start with... It's not needed for the
quasi-formal definition, but it is helpful as documentation. That is all.

    So what _is_ the question at hand, wrt the manual(s)?

1) See above.

2) The doc (both doc strings and manual blurb) for the functions mentioned
should explicitly describe the file-name argument, saying that a) it can be
relative or absolute, and reminding readers that b) "" is a relative name,
so that the function returns non-nil, because it tests the directory. Such a
reminder of the definition of relative might not be needed for each function
in the manual that takes a file-name arg, but these functions, because of
their names, encourage misinterpretation wrt "".

    >     > Sorry, I still don't get it. Why is the design like this?
    >
    >     This was discussed here some months ago, although I
    >     couldn't find that thread in the few minutes I had to
    >     look for it.
    >
    > I already said that I assumed this was "by design". I asked
    > what the design _advantage_ is. No answer, so far.

    I tried to provide a pointer to the answer: if you find and read those
    discussions, you might find it.  I didn't necessarily need a
    thank-you, but something less unkind would be nice.

I don't see anything unkind in my reply (certainly nothing unkind was meant)
or particularly helpful in your pointer. Like you, I don't have the time to
scour the posts of the past "some months" (looking for what keywords?). I
don't expect anyone to do that. If the advantage of this design was
discussed (I must have missed it), someone must be able to summarize the
rationale.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03 15:50         ` Stefan Monnier
@ 2006-01-03 18:51           ` Drew Adams
  2006-01-03 19:16             ` Eli Zaretskii
                               ` (3 more replies)
  0 siblings, 4 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03 18:51 UTC (permalink / raw)


    > I already said that I assumed this was "by design".  I asked
    > what the design _advantage_ is. No answer, so far.

    A file name "" is extrememly rare, so how we behave when facing such
    a situation should be driven by the two following goals:
    1 - avoid risks (e.g. try not to introduce security holes).
    2 - try not to spend too much code&time on it.
    I.e. the behavior should mostly be determined by the way the
    code makes it work, as long as it makes sense and is not dangerous.

See below on "extremely rare". Those general design goals are fine, but they
don't speak specifically to the advantage of _this_ particular design. They
don't, for example, show an advantage over considering "" to not be a file
name (neither relative nor absolute). Is there some security advantage? Does
it take less time or code?

    If you could give us some background as to why you care so much
    about the way Emacs handles a file named "", maybe you'd be taken
    more seriously.

As I said, I am not interested in trying to _change_ the current behavior. I
wanted to _understand_ the rationale for it. I wanted to understand the
advantage it provides - I thought perhaps I was missing something. Based on
the lack of an answer to my query (so far), I guess there is no advantage
and I wasn't missing anything. That's OK; now I know. (If anyone does see an
argument for the design, I'm still interested.)

My main point in writing about this, which I keep repeating is my main
point, is that the _doc_ is not clear enough.

As to why I "care so much" and the "extreme rarity" of an empty file name,
I've already given this simple example (twice):

 (while (or (string= "" name) (not (file-readable-p name)))
   (setq name (read-file-name prompt...)))

The example shows:

 - A program often (not extremely rarely) needs to account for user-input
filenames. Whereas "" as a name might be rarely constructed in a program,
and is impossible as the name of a real file, user input can require a
program to deal with the empty-name case.

 - The confusion that could (and will) arise from the fact that there is no
explanation of the file-name arg for these functions whose names suggest
that they act differently than they do. It shows, too, what you must do to
deal correctly with the problem. Such an example, by itself, would in fact
be enough as doc to dispel possible confusion: it shows that
`file-readable-p' by itself does not guarantee that the name names a
readable file.

I propose:

 1) Documenting the file-name arg in each of these functions,
    mentioning:

    a) that the name can be either relative (to the
       `default-directory') or absolute, and

    b) specifically reminding readers that "" is a relative
       file name, so, provided `default-directory' is an existing
       (or readable, or writable) directory, the function will
       return non-nil for ""

 2) More clearly expressing the general definition of a relative
    file name, specifically pointing out that "" is considered a
    legitimate relative file name, and that the name is relative
    because it does not start with / or ~.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03 18:51           ` Drew Adams
@ 2006-01-03 19:13             ` Eli Zaretskii
  2006-01-03 19:23               ` Drew Adams
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2006-01-03 19:13 UTC (permalink / raw)
  Cc: emacs-devel

> From: "Drew Adams" <drew.adams@oracle.com>
> Date: Tue, 3 Jan 2006 10:51:11 -0800
> 
> My question was stated carefully in terms of "all file-name arguments to
> functions", but you misread it as "all files" or perhaps "all file names".

If that is the misreading, then I'd say it's not a misreading at all:
since file-name arguments _are_supposed_to_be_ file names, it is only
natural to assume it's clear to the reader that what applies to file
names applies also to the file-name arguments of file-related
functions.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03 18:51           ` Drew Adams
@ 2006-01-03 19:16             ` Eli Zaretskii
  2006-01-03 19:25               ` Drew Adams
  2006-01-03 19:40             ` Luc Teirlinck
                               ` (2 subsequent siblings)
  3 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2006-01-03 19:16 UTC (permalink / raw)
  Cc: emacs-devel

> From: "Drew Adams" <drew.adams@oracle.com>
> Date: Tue, 3 Jan 2006 10:51:20 -0800
> 
> Those general design goals are fine, but they
> don't speak specifically to the advantage of _this_ particular design. They
> don't, for example, show an advantage over considering "" to not be a file
> name (neither relative nor absolute).

One advantage, IMO, is that no error is thrown or signaled for "",
which means application code will not need to cope with these
exceptional situations.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03 19:13             ` Eli Zaretskii
@ 2006-01-03 19:23               ` Drew Adams
  0 siblings, 0 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03 19:23 UTC (permalink / raw)


    > My question was stated carefully in terms of "all file-name
    > arguments to functions", but you misread it as "all files"
    > or perhaps "all file names".

    If that is the misreading, then I'd say it's not a misreading at all:
    since file-name arguments _are_supposed_to_be_ file names, it is only
    natural to assume it's clear to the reader that what applies to file
    names applies also to the file-name arguments of file-related
    functions.

A function that takes a file name as an argument could take that argument in
any form whatsoever - it could even expect it to be encrypted. My point was
that the doc of a function should document what the arguments are.

But let's drop it. Sorry for the noise. Happy New Year.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03 19:16             ` Eli Zaretskii
@ 2006-01-03 19:25               ` Drew Adams
  0 siblings, 0 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03 19:25 UTC (permalink / raw)


    > Those general design goals are fine, but they
    > don't speak specifically to the advantage of _this_ 
    > particular design. They don't, for example, show an
    > advantage over considering "" to not be a file
    > name (neither relative nor absolute).
    
    One advantage, IMO, is that no error is thrown or signaled for "",
    which means application code will not need to cope with these
    exceptional situations.

OK. Thanks.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03 18:51           ` Drew Adams
  2006-01-03 19:16             ` Eli Zaretskii
@ 2006-01-03 19:40             ` Luc Teirlinck
  2006-01-03 20:23             ` Luc Teirlinck
  2006-01-07 20:04             ` Thien-Thi Nguyen
  3 siblings, 0 replies; 22+ messages in thread
From: Luc Teirlinck @ 2006-01-03 19:40 UTC (permalink / raw)
  Cc: emacs-devel

Drew Adams wrote:

    - A program often (not extremely rarely) needs to account for user-input
   filenames. Whereas "" as a name might be rarely constructed in a program,
   and is impossible as the name of a real file, user input can require a
   program to deal with the empty-name case.

You mean what happens if a user exits with an empty minibuffer?  In
that case a program is free to specify any default behavior that makes
sense, as long as it clearly tells that to the user.  This is mainly
relevant for commands.  The examples you gave, file-exists-p and
friends are not commands.

So if you define a command my-file-operation, taking a file name as an
argument, you could show a minibuffer prompt:

Operate on file (default ~/.emacs):

Your _interactive declaration_ could then transform empty user input
("") into the string "~/.emacs".  Then a call to file-exists-p in the
code of your command will apply to "~/.emacs", if the user pressed RET
in an empty minibuffer.  When called from Lisp, (my-file-operation "")
would not change the "" to "~/.emacs" (only the interactive
declaration does) and hence would still operate on default-directory.

But you can do all of this much more easily by reading the file name
with `read-file-name', which allows you to specify a default if the
user exits with an empty minibuffer.  `file-exists-p' will then get
that default as argument, not "".

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing,  readable, and writable file?
  2006-01-03 18:51           ` Drew Adams
  2006-01-03 19:16             ` Eli Zaretskii
  2006-01-03 19:40             ` Luc Teirlinck
@ 2006-01-03 20:23             ` Luc Teirlinck
  2006-01-03 21:09               ` Drew Adams
  2006-01-07 20:04             ` Thien-Thi Nguyen
  3 siblings, 1 reply; 22+ messages in thread
From: Luc Teirlinck @ 2006-01-03 20:23 UTC (permalink / raw)
  Cc: emacs-devel

Drew Adams wrote:

   As to why I "care so much" and the "extreme rarity" of an empty file name,
   I've already given this simple example (twice):

    (while (or (string= "" name) (not (file-readable-p name)))
      (setq name (read-file-name prompt...)))

   The example shows:

In my previous reply, I forgot that read-file-name returns "" if the
user exits with empty input (and _not_ the DEFAULT-FILENAME arg).  So
your real question is why read-file-name does that, a rather different
question from the one you asked.

Here is what the Elisp doc of find-file-name says:

     If the user types <RET> in an empty minibuffer, this function
     returns an empty string, regardless of the value of EXISTING.
     This is, for instance, how the user can make the current buffer
     visit no file using `M-x set-visited-file-name'.

This is what the docstring of set-visited-file-name says:

    FILENAME nil or an empty string means mark buffer as not visiting any
    file.  Remember to delete the initial contents of the minibuffer if
    you wish to pass an empty string as the argument.

So you could make your function do something similar if you want to.
read-file-name returns "" on empty input to allow its caller to attach
a special meaning to exiting with an empty minibuffer.

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03 20:23             ` Luc Teirlinck
@ 2006-01-03 21:09               ` Drew Adams
  0 siblings, 0 replies; 22+ messages in thread
From: Drew Adams @ 2006-01-03 21:09 UTC (permalink / raw)


    In my previous reply, I forgot that read-file-name returns "" if the
    user exits with empty input (and _not_ the DEFAULT-FILENAME arg).  So
    your real question is why read-file-name does that, a rather different
    question from the one you asked.

No, my question is not about read-file-name. Please, drop the lessons on how
to code commands that read file names. I can do that; trust me.

My point was that the doc for a function should describe its arguments.
That's all.

This is especially true for functions that have names that can suggest they
return a different result from what they do return in one particular case.

I've made my point. You don't want to hear it. Maybe it's not important to
anyone. Let's move on.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Null filename ("") is considered to correspond to an existing, readable, and writable file?
  2006-01-03 18:51           ` Drew Adams
                               ` (2 preceding siblings ...)
  2006-01-03 20:23             ` Luc Teirlinck
@ 2006-01-07 20:04             ` Thien-Thi Nguyen
  3 siblings, 0 replies; 22+ messages in thread
From: Thien-Thi Nguyen @ 2006-01-07 20:04 UTC (permalink / raw)
  Cc: emacs-devel

"Drew Adams" <drew.adams@oracle.com> writes:

>  - The confusion that could (and will) arise from the fact that there
> is no explanation of the file-name arg for these functions whose names
> suggest that they act differently than they do. It shows, too, what
> you must do to deal correctly with the problem. Such an example, by
> itself, would in fact be enough as doc to dispel possible confusion:
> it shows that `file-readable-p' by itself does not guarantee that the
> name names a readable file.

the directory is a "readable file" in the filesystem, if you lump
directories and files together, as is convenient to do for certain
operations.

instead of worrying whether or not the empty string is a filename,
the better question to ask is how/where (in the manual) to establish the
pervasiveness of `default-directory' and its role in resolving into
filenames those strings that are passed to various functions.

the answer (which i tend to agree with) seems to be that due to its
pervasiveness, explaining the relationship for every leaf in the tree is
a lose compared to explaining the relationship once, in the trunk.

if you read the documentation from the leaves to the trunk, that's your
problem, and that's the source of the potential confusion.

thi

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2006-01-07 20:04 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-02 22:57 Null filename ("") is considered to correspond to an existing, readable, and writable file? Drew Adams
2006-01-03  1:22 ` Luc Teirlinck
2006-01-03  3:27   ` Drew Adams
2006-01-03  4:41     ` Luc Teirlinck
2006-01-03  8:24       ` Drew Adams
2006-01-03 18:13       ` Eli Zaretskii
2006-01-03  4:56     ` Luc Teirlinck
2006-01-03  5:32     ` Eli Zaretskii
2006-01-03  8:25       ` Drew Adams
2006-01-03 15:50         ` Stefan Monnier
2006-01-03 18:51           ` Drew Adams
2006-01-03 19:16             ` Eli Zaretskii
2006-01-03 19:25               ` Drew Adams
2006-01-03 19:40             ` Luc Teirlinck
2006-01-03 20:23             ` Luc Teirlinck
2006-01-03 21:09               ` Drew Adams
2006-01-07 20:04             ` Thien-Thi Nguyen
2006-01-03 18:11         ` Eli Zaretskii
2006-01-03 18:51           ` Drew Adams
2006-01-03 19:13             ` Eli Zaretskii
2006-01-03 19:23               ` Drew Adams
2006-01-03 18:51           ` Drew Adams

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).