|
Boost : |
Subject: Re: [boost] TMP error messages [ was Re: New libraries implementing C++11 features in C++03 ]
From: Joel de Guzman (joel_at_[hidden])
Date: 2011-11-28 19:05:12
On 11/26/2011 9:22 PM, Ábel Sinkovics wrote:
> 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.
I've been reading the docs. This is very clever! I wonder how it
applies to expression templates with runtime code or Fusion with
runtime components?
A simple example would be a template plus function:
template <typename A, typename B>
auto plus(A const& a, B const& b) -> decltype(a+b)
{return a+b;}
The typical problem is an error if a+b is not allowed (e.g.
a is an int but b is a std::vector). I don't see how your
solution will help more than static_assert or better yet,
Boost concepts.
Regards,
-- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk