$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] TMP error messages [ was Re: New libraries implementing C++11 features in C++03 ]
From: Ábel Sinkovics (abel_at_[hidden])
Date: 2011-11-26 08:22:32
Hi,
> The problem is that errors point to code that is deep within the library's
> implementation, or worse, the implementations of helper libraries used
> by the library. To understand the error, the user has to look at the
> library's implementation. The user shouldn't have to do that -
> understanding the implementation of a library should not be a
> prerequisite for using it.
>
> If you have any specific suggestions about what compilers could do to turn
> these errors from deep within the library implementation, into errors
> that do not require knowing anything about the library implementation,
> I would like to hear it, and I'm sure so would compiler writers.
>
> Otherwise, you have to accept that library writers face a trade-off
> between the user-friendliness of error messages, and the expressiveness,
> terseness, and power obtained by extensive use of advanced techniques
> such as template metaprogramming. There is no one right answer to
> this tradeoff, and it is good for users to have different alternatives
> available to them.
We've been experimenting with returning error messages from TMP 
libraries that make sense in the domain of the library. Our approach is 
returning a class describing the error when a metafunction is called 
with invalid arguments (a pretty-printer can display that information 
later in a human-readable way). The assumption is that this error 
information is returned by a metafunction deeply inside the TMP library 
and need to be propagated out (maybe changed a bit along the way to make 
more sense to the user). For this we've used monads, using which we 
could simulate exceptions being thrown at compile-time. Using monads 
increases the complexity of the TMP library, however, most of it can be 
hidden by another library. We've been working on such a library (not in 
Boost).
What TMP library authors can do is wrapping the body of every 
metafunction with a template that "adds" error propagation to it. For 
example instead of:
template <class A, class B, class C>
struct some_metafunction_in_the_library :
   f<g<A, C>, h<B>, A>
{};
one can write
template <class A, class B, class C>
struct some_metafunction_in_the_library :
   try_<f<g<A, C>, h<B>, A> >
{};
in which case if f, g or h returns an error, the same error is returned 
by some_metafunction_in_the_library instead of breaking the compilation 
with a cryptic error message. At the top level it can be pretty-printed 
by a test harness (eg. simple binary built to pretty-print it or by a 
TMP unit testing framework). A downside of using it is that it makes 
compilation slower (see 
http://plcportal.inf.elte.hu/en/publications/TechnicalReports/monad-tr.pdf 
for measurements).
So far we've only been using it for improving error messages coming from 
template metafunctions. Cases where they can't be easily and clearly 
separated from runtime code haven't been addressed yet.
This solution is part of a library implementing monads in C++ template 
metaprogramming.
Documentation: http://abel.web.elte.hu/mpllibs/metamonad/index.html
Source code: https://github.com/sabel83/mpllibs/tree/master/libs/metamonad
Note that there are only a few examples so far.
Regards,
   Abel