Re: [boost] Boost.Filesystem: naming, canonical path

2003-08-14 Thread Thomas Witt
Dave,

Beman Dawes wrote:
At 08:06 PM 8/9/2003, David Abrahams wrote:

 
 I'm sorry if this sounds harsh, but I think the cure for someone being
 confused about the term absolute on multi-root OSes is to pick the
 definition that allows the term to be meaningful (an absolute path
 identifies a specific location, and so must include the root) and *add
 a clarifying note or definition for the corner case*, not to pick some
 new term which nobody knows about and makes the library hard to
 approach.
The problem is not someone who is confused. The problem are a 
potentionally significant number of users who are sure they know what 
they are doing, but don't. A clarifying note won't be much use to them, 
cause for them there seems to be nothing that needs clarification. Just 
to make this clear, I don't blame them for this. I think we are all 
prone to this behaviour. We mostly fail due to things we believe we know 
not due to those we think we don't know.

The library isn't all that large that people can't just read about each 
function.

There were lengthy discussions on the list of this and other naming 
issues during development, during review, and during the resolution of 
review issues. Many people had fairly strong views. IIRC, the idea that 
is_absolute( /foo ) was false on some operating systems was impeded by 
long-held beliefs. By giving the function an unfamiliar name, people are 
forced to actually read the specs instead of just assuming what it does, 
and that ends up being a good thing, IMO.
I second this.

Thomas



___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Boost.Filesystem: naming, canonical path

2003-08-14 Thread David Abrahams

As a user of the filesystem library, I am having the experience that
obvious things are hard to find, and the docs are much harder to
understand than they ought to be.  The use of creative naming really
gets in the way.  For example, the term complete is never defined
anywhere.  The closest we come is in the following naming rationale.

is_complete

bool is_complete() const;

Returns: For single-root operating systems,
has_root_directory(). For multi-root operating systems,
has_root_directory()  has_root_name().

Naming rationale: The alternate name, is_absolute(), causes
confusion and controversy because on multi-root operating systems
some people believe root_name() should participate in
is_absolute(), and some don't.

I'm sorry if this sounds harsh, but I think the cure for someone being
confused about the term absolute on multi-root OSes is to pick the
definition that allows the term to be meaningful (an absolute path
identifies a specific location, and so must include the root) and *add
a clarifying note or definition for the corner case*, not to pick some
new term which nobody knows about and makes the library hard to
approach.

--- aside ---
Regarding complete paths, is there any guarantee that they are
canonical?  Is foo/bar/../baz reduced to foo/baz?  See
http://java.sun.com/j2se/1.3/docs/api/java/io/File.html#getCanonicalPath()
for an example of the possible semantics.  We could learn a lot about
what's useful and broadly implementable by studying the libraries of
Java and/or Python (yes, I realize that the portability of Java ain't
quite what it's cracked up to be).
--- aside ---

The formal description of some of the function semantics leaves
something to be desired.  For example, the docs for remove_all say:

unsigned long remove_all( const path  ph );

Precondition: !ph.empty()
Postcondition: !exists( ph )
Returns: The number of files and directories removed.
Throws: if ph.empty(). See empty path rationale.

So, what does this do?  At first I thought it removed all the
directories along the branch described by ph.  I think I'm now
inferring that if ph is a file, it is the same as remove( ph ) and
otherwise it removes all of the files and subdirectories in ph and
then removes ph.  A plain English description would help a lot here.
This applies to many other functions in the library also.

I also have some doubts about the validity of the postcondition, since
another process can come along and create ph again before remove_all
returns.  This applies to many other functions in the library also.

The difference between is_empty(ph) and ph.empty() is too slight, IMO,
for their differing semantics.  IMO it's not useful to have one
function which reports both empty files and empty directories - the
implications of the two are much too different.


-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Boost.Filesystem: naming, canonical path

2003-08-10 Thread Beman Dawes
At 08:06 PM 8/9/2003, David Abrahams wrote:

As a user of the filesystem library, I am having the experience that
obvious things are hard to find, and the docs are much harder to
understand than they ought to be.  The use of creative naming really
gets in the way.  For example, the term complete is never defined
anywhere.
It is defined by the is_compler() returns clause.

  The closest we come is in the following naming rationale.

is_complete

bool is_complete() const;

Returns: For single-root operating systems,
has_root_directory(). For multi-root operating systems,
has_root_directory()  has_root_name().

Naming rationale: The alternate name, is_absolute(), causes
confusion and controversy because on multi-root operating systems
some people believe root_name() should participate in
is_absolute(), and some don't.

I'm sorry if this sounds harsh, but I think the cure for someone being
confused about the term absolute on multi-root OSes is to pick the
definition that allows the term to be meaningful (an absolute path
identifies a specific location, and so must include the root) and *add
a clarifying note or definition for the corner case*, not to pick some
new term which nobody knows about and makes the library hard to
approach.
The library isn't all that large that people can't just read about each 
function.

There were lengthy discussions on the list of this and other naming issues 
during development, during review, and during the resolution of review 
issues. Many people had fairly strong views. IIRC, the idea that 
is_absolute( /foo ) was false on some operating systems was impeded by 
long-held beliefs. By giving the function an unfamiliar name, people are 
forced to actually read the specs instead of just assuming what it does, 
and that ends up being a good thing, IMO.

I suppose if we were to discuss the names all over again we would come up 
with a different set of names. But unless the new names are markedly 
superior to the old names, it would just be churn to change them, and might 
be a real step backwards.

--- aside ---
Regarding complete paths, is there any guarantee that they are
canonical?  Is foo/bar/../baz reduced to foo/baz?
Yes. That is documented as a postcondition specifying canonical form for 
all the functions that modify a path. I've just double checked, and it 
doesn't look like any were missed, but let me know if you spot any way to 
alter path state that doesn't supply that postcondition.

  See
http://java.sun.com/j2se/1.3/docs/api/java/io/File.html#getCanonicalPath()
for an example of the possible semantics.  We could learn a lot about
what's useful and broadly implementable by studying the libraries of
Java and/or Python (yes, I realize that the portability of Java ain't
quite what it's cracked up to be).
Yes, I often found other libraries helpful, although many of them offer 
syntactic portability rather than semantic portability.

The legacy operating system API's interesting because they sometimes take 
different approaches. Sometimes what we think of as a path is just a key 
used to find the actual path via some external mapping mechanism.

--- aside ---

The formal description of some of the function semantics leaves
something to be desired.  For example, the docs for remove_all say:

unsigned long remove_all( const path  ph );

Precondition: !ph.empty()
Postcondition: !exists( ph )
Returns: The number of files and directories removed.
Throws: if ph.empty(). See empty path rationale.

So, what does this do?  At first I thought it removed all the
directories along the branch described by ph.  I think I'm now
inferring that if ph is a file, it is the same as remove( ph ) and
otherwise it removes all of the files and subdirectories in ph and
then removes ph.  A plain English description would help a lot here.
This applies to many other functions in the library also.
Yes, a general prose description for each library would help.

I also have some doubts about the validity of the postcondition, since
another process can come along and create ph again before remove_all
returns.  This applies to many other functions in the library also.
The docs really weren't clear enough about postcondition/race-condition 
interactions. I've just added a paragraph to 
boost-root/libs/filesystem/doc/index.htm#Common_Specifications to make it 
clear that postcoditions don't hold if race-conditions exist.

Because of the race-condition problem, the original docs did not specify 
postconditions. Someone pointed out how much clearer they because if 
postconditions were used, and the docs got converted at that point.

The difference between is_empty(ph) and ph.empty() is too slight, IMO,
for their differing semantics.  IMO it's not useful to have one
function which reports both empty files and empty directories - the
implications of the two are much too different.
Early versions of the library did provide the finer granularity of