Boost logo

Boost :

From: Jean-Louis Leroy (jl_at_[hidden])
Date: 2025-05-02 01:50:43


Hi Peter,

Thanks for your review!

I'll think about your remarks on the introduction, and probably blend some of it
in.

> To be clear - does the library implement ALL the features of the N2216
> paper - if not all, then list those implemented.

I'll add a dedicated top-level entry for this. Probably it should not be too
close to the top, because it will speak to more hardcore users, not to people
who are just discovering open-methods and who have no awareness of N2216.

> It is totally OK to provide references, though expect some reference links to
> break as time passes. *Required information should be in the library doc*.

Ok.

> A kinda nit - this is funny "You wanted a banana but what you got was a
> gorilla holding the banana and the entire jungle." - but - is it really true?

Yes it is :-D

Take the Matrix example, where you want to add serialization to the matrix
hierarchy. If you plant a `virtual void to_json(std::ostream&)` in the base
class, and implement it in the subclasses, any consumer of your matrix library
will drag in the iostream library. Matrix is the banana you wanted. The iostream
library is the gorilla. You'll pull iostream's dependencies in as well. Jumping
from hierarchy to hierarchy in that fashion, you'll pull much of the entire
jungle.

People did a lot of this when OOP became mainstream. Later patterns, principles,
etc were designed to mitigate the problem. Visitors, dependency injection,
interfaces, etc. Open-methods are a solution, but less clumsy I believe.

GETTING STARTED

> Following the introduction, there should be a *Getting Started* section which
> goes over 1) Requirements 2) Steps to install 3) Dependencies (Boost libs, std
> libs, other libs, etc.) 4) hello world tutorial.

> Getting up and running should come before Tutorials.

OK, those should not be relegated to the reference.

PERFORMANCE

> Perhaps add a table of performance of some sort that readers can relate to
> - say, comparing an open method to a class method with both doing the same
> thing.

https://jll63.github.io/Boost.OpenMethod/#tutorials_performance does that, but
in terms of instructions, not timings. Working on this project has destroyed my
faith in micro-benchmarks.

> However, they are not really tutorials unless they contain steps for the
> reader to follow. Step 1 - copy and paste this example. Step 2 - run it and
> examine the output, Step 3 - add this feature and run again. Step 4 -
> notice how the output has changed...etc. etc.

> It would be most useful if the tutorials related to the use-cases first
> introduced, showing how the desired results are achieved.

On this subject, what do you think of Andrzej's distaste of the Animals example?
And my motivation for it? I don't want to put my words in Andrzej's mouth,
you'll find that dialogue easily.

I do see his point.

> TERMS and ACRONYMS
>
> Acronyms are introduced that I am unaware of, without an initial
> explanation. For example,
>
> Unlike function declarations, which can occur multiple times in a TU, an
> overrider declaration cannot.
>
> What is a TU? Can this be defined in full on first use? Similar for ADL,
> AST, CRTP etc. And for terms such as "guide function" - add a definition on
> first use.

I *think* I kept the acronyms to the "advanced" parts of the doc. I think that
any moderately advanced C++ programmer knows what ADL is...but I will make sure
that in any given section the first mention of an acronum is: Argument Dependant
Lookup (ADL).

> I would really like to see the Reference further divided into sections
> based on type:
> * Classes
> ** fields
> ** methods
> * Interfaces
> * Structures
> * Constants
> * Macros
> * Functions (if external to any class)

So, I struggled with this. I opted for a "thematic" grouping - putting strongly
related constructs close to one another in the sidebar. But that grouping jumps
across categories. Some facets are templates, some are classes. Should they be
scattered between templates and classes? This approach seems to work well only
for the macros.

> - Currently we have to examine each entry, or guess (I don't like guessing)
> what each entry is.

Yeah I experimented with other schemes, trying to get guidance from other adoc
based documentations. There are many variations.

I tried prefixing every entity with its category - e.g. "class template method",
"class template method::override", but this causes a lot of wrapping in the left
sidebar.

I am considering removing the "Reference" level to gain one level. Instead of:

    Reference
        BOOST_OPENMETHOD
            Synopsis
            Description
        BOOST_OPENMETHOD_OVERRIDE
            Synopsis
            Description

...go straight to :

       BOOST_OPENMETHOD
           Synopsis
           Description
       BOOST_OPENMETHOD_OVERRIDE
           Synopsis
           Description

What do you think?

I like adoc but it can be limiting...

> If references are arranged alphabetically within each section (Classes,
> Macros etc.) - they are easy to locate.

In YOMM2 I have a flat alphabetically ordered index
(https://jll63.github.io/yomm2/#index). Maybe thematic grouping is a bad idea.
After all it's a reference, not a novel.

> ERRORS and EXCEPTIONS
>
> It is not clear to me what errors or exceptions might be thrown by any of
> the entries. All errors/exceptions thrown by the library code should be
> listed under the entry that might fire them. For maximum usefulness,
> include a table of errors and exceptions and* what you should do about it
> if you get such an error* could be described too - say likely causes and
> likely resolutions.

It is hard to document accurately because of the customization points.

> A complete structured Reference, with descriptions, return values, use
> cases and errors would be great to see.

Do you mean this style (from Variant2)?

    Effects:
        Initializes the variant to hold the same alternative and value as w.

    Throws:
        Any exception thrown by the move-initialization of the contained value.

    Remarks:
        This function does not participate in overload resolution unless
        std::is_move_constructible_v<Ti> is true for all i.

I tried it. But it is difficult to squeeze the library's flexibility into this
mold. In case of error, it aborts. But before that it calls error handling
facet. Which can throw, or not - it's a customization point. I guess I could
have a Errors instead of a Throws:

    Errors:
        Call the error handler specified in the policy's error_handler facet,
        then call abort.

More importantly, I felt that this style is robotic.

What are your favorite Boost documentations?

> ACKNOWLEDGEMENTS, REFERENCES
>
> The documentation could end with any acknowledgements (designers, testers,
> motivators) and References such as N2216 and no doubt others.

Yes.

> The documentation as it stands describes what the code does but almost
> entirely from an inward looking perspective and almost never addresses the
> "when I should use this" from a use-case - or more likely a component of a
> use-case - perspective.

> 1. an introduction explaining the "why I should be interested" with some
> compelling use-cases. The more relatable the use-cases, the more interest and
> users you will get.

You seem to agree with Andrzej. By the way (BTW ;-) ) he likes YOMM2's intro
better. Can you take a look and tell me what you think?
https://github.com/jll63/yomm2

> 2. Are there other Boost libraries that play well with OpenMethods - even if
> you have limited experience of this a start would be helpful.

Yes.

* Using a flat_unordered_map in place of a std one. That brings dispatch speed
  closer to my perfect hash solution.

* Interoperability with intrusive smart pointers.

> I hope my 2c is useful.

You are a technical writer, I am a just code writer trying to do a technical
writer's job. That's worth a lot more than 2c ;)

J-L


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk