From: Vinnie Falco (vinnie.falco_at_[hidden])
Date: 2020-09-17 20:50:54


On Thu, Sep 17, 2020 at 12:31 PM Vinícius dos Santos Oliveira via
Boost <boost_at_[hidden]> wrote:
> ...
> The idea here is...
> ...
> Appendix A will present how another feature from Boost.JSON can be
> implemented in pull parsers: strings split among different buffers.
> ...

This is all very nice and I appreciate the time that you put into this
thorough and detailed analysis. What is missing from this screed,
however, is an example of a complete working library which implements
these wonderful ideas of yours.

> Boost.JSON -- will prove unfit to build anything higher-level and a
> new core will have to be developed from the ground-up because current bad
> design choices.

On the other hand, we have a couple of examples of libraries in the
style of Boost.JSON: RapidJSON, and JSON For Modern C++ (nlohmann's
JSON). These libraries also offer a DOM and a monolithic parser
(although, in nlohmann's case it cannot be instantiated directly).
They have tens of thousands of users and can be seen as dependencies
in other projects, which provides a stark contradiction to your claim
above.

Based on the popularity of these two libraries alone, it should be
uncontroversial that a JSON library which offers the same
functionality (a DOM, plus parsing, plus serialization) with great
performance and the level of interface quality you expect from a Boost
component, would be immensely popular and quite the opposite of
"current bad design choices." Quite frankly I find your position to be
completely indefensible.

> ## The case for pull parsers
> ...
> The defining trait present in pull parsers that is impossible to replicate
> in push parsers is their ability to compose algorithms.
> ...

This is a feature no one is asking for, and not a goal of the library.
Boost.JSON is about bringing to C++ the same level of ease of use and
flexibility for working with JSON that you find in other languages
like say, Javascript. It is not a competitor to Boost.Serialization,
nor is it meant for the parser and serializer to satisfy every
possible use-case. It is meant for a particular use-case and designed
to do it very well. Besides, I have a theory that there is no single
parser design which will be ideal for every use-case. That is to say
that optimizing for one feature will by necessity disadvantage other
features. I would of course love to be proven wrong, if someone could
show me a complete working example with benchmarks. But nlohmann's
JSON took this route and well, we know what the results are (not
good).

> Composition is
> enabled by temporarily handing over the token stream to a different
> consumer. Not every consumer needs to know how to process every part of the
> stream. That's a trait impossible to find in push parsers.

Practical experience with a 5-year old Boost library and a 2-year old
Not-In-Boost library, plus feedback from actual users, has shown that
these use-cases are not what people want.

> Can the handler pause the parsing loop by returning `false`
> w/o setting any error code (and how'd the stream be resumed)?

No, this is explained in the docs. Upon error, the only valid
operations are destruction and reset.

Regards