Subject: Re: [boost] [metaparse] Practical usefulness
From: Abel Sinkovics (abel_at_[hidden])
Date: 2015-06-03 00:59:57


Hi Phil,

On 2015-06-03 00:18, Phil Endecott wrote:
> So let me ask a question: how useful is this library in practice,
> beyond "toy examples"?
>
> Was this library developed with a real application, i.e. use in
> a product, as its motivation, or was it written to test the
> limits of what is possible using metaprogramming?
This library was generalised from the original version of a type-safe
printf (after realising that a "real" parser makes things much simpler).

> My first reaction to the library was "cool!". My second reaction
> was "it's a toy to demonstrate metaprogramming". Then I saw the
> printf() example and my third (and for now final!) though is that,
> yes, this could be useful.
I see it as a tool to build library interfaces. Here is a (yet
unfinished) attempt to build an Xpressive frontend for example:

https://github.com/istvans/mpllibs/blob/master/libs/xlxpressive/example/comparison/main.cpp

(the link points to an example comparing the new frontend to the
original interface, the library lives in a fork of Mpllibs and has the
same structure as the rest of the Mpllibs libraries).

you can write MPLLIBS_REGEX("....") and that gets validated at compile-time.

Another usage area (not published and to the best of my knowledge
slightly explored) is writing SQL libraries that are checked at
compile-time but don't change the SQL syntax.

A third usage area (again, I'm not aware of it being explored) is
generating runtime parsers from grammars (something like
metaparse::grammar, but building a runtime parser instead of a
compile-time one).

> In another thread, Peter Dimov asked about getting char packs from
> string literals. It seems to me that if we had that then we
> could implement printf() without needing a "parser library" at
> all:
>
> template <char c1, char... c>
> class formatter
> {
> public:
> template <typename... ARGS>
> void operator()(ARGS... args...) {
> std::cout << c1;
> formatter<c...>()(args...);
> }
> };
>
> template <char... c>
> class formatter<'%','d',c...>
> {
> public:
> template <typename... ARGS>
> void operator()(int i, ARGS... args...) {
> std::cout << i;
> formatter<c...>()(args...);
> }
> };
>
> template <char c1>
> class formatter<c1>
> {
> public:
> void operator()() {
> std::cout << c1;
> }
> };
>
> int main()
> {
> formatter<'h','e','l','l','o','%','d','!'>()(42);
> }
>
> So maybe all that I really want is the preprocessor magic to turn
> string literals into something that's more useful at compile time.
> Or a language feature to do that.
>
> Or maybe somehow constexpr can do it all for me. Anyone have a
> constexpr implementation of printf()?
This approach to write a type-safe printf displays the characters
one-by-one on an output stream. The printf library in Mpllibs does the
validation at compile-time and calls the "unsafe" printf at runtime (and
has therefore no runtime overhead).

This does not necessarily mean that it is not possible to build
validation using a recursive (pattern matching) approach for printf.
However, note that the printf grammar is a bit more complicated than the
most commonly used %d, %f, etc. (see
http://www.cplusplus.com/reference/cstdio/printf/ for example). When you
decide to support the full syntax, then it quickly gets complex (and
that is where grammars and parser generators become helpful).

Regards,
   Ábel