Boost logo

Boost Users :

Subject: Re: [Boost-users] [range] questions about documentation and usage
From: Robert Ramey (ramey_at_[hidden])
Date: 2012-11-04 03:37:13


Neil Groves wrote:
> On Sat, Nov 3, 2012 at 11:29 PM, Robert Ramey <ramey_at_[hidden]> wrote:

> Please demonstrate what you would consider an improvement. I think
> many of us have tried to obtain something from you to help us. I
> appreciate that negative criticism is to some extent useful, but you
> aren't giving me clear enough suggestions for positive corrective
> action.

I pointed out things that I thought were wrong and asked to what I was
missing. The feedback that I got back was that no one else thinks
anything is wrong and don't see my point. From my stand point,
I'm just pointing out mistakes.I didn't think of it as negative criticism.
The feedback I've gotten has convinced me that I didn't get any
thing wrong and that in fact my observations point to real mistakes
in the documentation and perhaps in the library as well. Here
are a few constructive suggestions.

a) For each concept in your documentation define a concept
checking class. OK you've done this - so far so good.

b) Declare a concept class using the BCCL - you've
done this too - so far so good.

c) Declare concept archtypes from reading your documentation.
This is described in the Boost Concept library documentation.
This archtype class looks like:

template <class T>
SinglePassRangeArchType {
    // examples of "valid expressions" from the documentation go here
};

OK First red flag - the "valid expressions" are members of type T
so it's not at all clear to me how to fill this in.

On might think to add something like:
namespace boost {
template <class T>
boost::range_iterator<X>::type begin(T &t){
    return;
}
} // namespace boost

But that raises a few design questions of it's own.
1) What should go into X?
2) this will match just about anything - which will likely create
other design problems.

Given that we've decided (perhaps too soon) we want to support
boost::range::find(std::vector<int>, 0) we likely want to provide

a.begin() as a valid express
and
X::iterator as associated types.

Of course this will ripple to boost::iterator_range so that we'll need
template<class T>
iterator_range {
    ...
    T begin();
    ...
};

But we already have that. So far so good.

d) Each function template documentation page should describe the
concepts of it's template parameters.

the range find function described here:
http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/algorithms/non_mutating/find.html
refers to a type "range_return_value" which I can't find anywhere.
I'm guessing that the type Value can't be any type but is likely restricted
to
some type related to SinglePassRangeConcept? I don't know what it is.

A function template page should look more like this example:

http://rrsd.com/blincubator.com/function/

Note that this includes a small example which can be compiled.
Note it should contain the header file to be included.

e) A type or class template documentation page should have a little
bit more information. Take your example:

http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/utilities/iterator_range.html

which isn't too bad. But it would be helpful if it included the following:

Template parameter. I can guess that the "ForwardTransversalIterator"
parameter should model the ForwardTransversalIterator concept of
the iterator library. But it should be stated explicitly.

Model of: SinglePassRange concept

Valid Expressions (AKA member functions) should state the
concepts (type requirements on member function template
parameters. For example, if I see:

template< class ForwardRange >
iterator_range& operator=( ForwardRange& r );

It's not clear what type I can plug into ForwardRange. Can
I use any type which models SinglePassRange like this:

std::vector<int> x;
boost::range::iterator_range<std::vector::iterator> v(x);

or do have to use another iterator range as an argument?

I can't tell from reading the documentation.

Here is a model for a class template page

http://rrsd.com/blincubator.com/type/

====
More or less unrelated to my questions regarding the documentation
there are a couple of other observations I came upon while looking
into this.

a) The example from a another post

class my_class {};
namespace boost {
const int * begin(my_class & b);
const int * end(my_class & e);
} // namespace boost
void test3(){
my_class x;
  boost::begin(x);
  boost::end(x);
  BOOST_CONCEPT_ASSERT((boost::SinglePassRangeConcept<my_class>)); // error
  // above ASSERT Traps even thoug my class matches SinglePassRange
according
   // to the documentatino
  boost::range::find(x, 0); // error
  // Even the though the assertion above traps, this code compiles
}

At first I assumed that the second error was due to failing to include the
concept checks in the code for the range::find template. I looked
at the code and saw that they were there so I can't explain why
the find doesn't trap with the same assert as above.

b) I thought that all the stuff was built directly in the boost
namespace which I object to. I see it's really built in boost::range
(much better) but hoisted up to namespace boost via a wrapper
and using declaration. I have to observations about this:
1) I don't think using should every be in any header file.
2) Any user can hoist those things he wants into the some higher
namespace - but he can't go the other way. That is, once he
uses your header, he can't undo the "hoisting". If you really
want to provide this "help" at least make it optional. I think you
could do that by providing an optional header which would
hoist all the names.

>> The documentation could always use more
>> examples. I did put these into a separate area in the documentation
>> because I wanted to make them all have tests. The change of layout
>> might not have been optimal and I'll think about this.

The examples I'm refering to are not full blown tutorial type examples
(which are helpful but a lot of work to make). But rather 5-15 lines
mini-programs written at the time the documentation is written. They
are not hard to write when the code is being developed and very
helpful to users of the documentation.

> I'm suggesting that Boost.Range has this wrong.
>
> Yes you are, but frustratingly again without any positive suggestive
> action which is annoying and unhelpful.

I hope this is helpful.

For what it's worth, I don't mean to pick on anyone personally. I
am sympathetic - I doubt anyone ever received more heat than
I have for making the serialization library. My advice above
is fruit of bitter personal experience - which I'm hoping to help
other people avoid.

To this end, I've been working on my latest project: www.blincubator.com
I would hope anyone who has followed this discussion
will find this interesting. It still has a few loose ends, but then
I haven't received any feedback on it.

Robert Ramey


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net