Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easier debugging of misuse of the library #55

Open
Quincunx271 opened this issue Jul 12, 2018 · 4 comments
Open

Easier debugging of misuse of the library #55

Quincunx271 opened this issue Jul 12, 2018 · 4 comments

Comments

@Quincunx271
Copy link
Contributor

Quincunx271 commented Jul 12, 2018

As it is now, it can be really difficult to debug misuse of the library. A misunderstanding of the various algorithms or improperly tracking the form of the data being operated on leads to inscrutable template errors. Meticulously examining the compilation error can sometimes help in resolving the issue, but it can also lead to further confusion. For example, Clang does not show the value of the parameter pack at each alias template call.

I get that fast evaluation is important to this library. However, use of this library frequently leads to near-impossible to debug metaprograms.

A proposal for easier debugging: a KVASIR_MPL_DEBUG preprocessor define which unlocks static asserts, the goal being easier to understand compilation errors.

For example, front<> could do something like this when #ifdef KVASIR_MPL_DEBUG:

template <typename... Ts>
struct checked_front {
    static_assert(sizeof...(Ts) > 0, "a nice error message about needing at least one argument");
};
template <typename T, typename... Ts>
struct checked_front<T, Ts...> {
    using type = T;
};

template <...>
struct front {
    template <typename... Ts>
    using f = typename checked_front<Ts...>::type;
};

While I don't like having two forms for every algorithm, I think that these asserts can be designed to be transparently inserted into the calls in some form of continuation. Maybe some kind of peek<...> continuation which calls the appropriate static asserts. peek<check_front, ...>

@odinthenerd
Copy link
Member

I agree this is a source of pain. I'm currently doing a full rewrite of this library as boost.tmp where I use a strategy I call 'arity tracking' to speed up low arity calls (like complex predicates) which also has the nice side effect of being able to provide better static asserts on underflow etc.

@odinthenerd
Copy link
Member

one technique I use when trying to figure out how I broke the world is to start with a small piece of the algorithm and add complexity until it blows up, not the most ergonomic error handling but has worked for me so far.

@jonathanpoelen
Copy link
Contributor

Should we understand that it is better to use boost.tmp rather than kvasir.mpl?

I looked at the sources a bit, from what I understand, the implementations are moved into a dispatch specialization. What would prevent it from doing it for kvasi.mpl? Is it really faster?

In any case, clang errors are no more readable (they are even worse :/). To have a trace, it would be necessary for dcall to go through a eager meta-function, as below (with a few exceptions, everything goes through dcall/dcallf).

template<class T> struct identity { using type = T; };

template<class C, class... Ts> struct trace_call
  : identity<typename C::template f<Ts...>> {};

template<class C> struct dtrace_call
{
  template<class... Ts> using f = typename trace_call<C, Ts...>;
};

template <typename C>
struct dependant_impl<true, C> : dtrace_call<C> {};
// before: struct dependant_impl<true, C> : C {};

@odinthenerd
Copy link
Member

the dispatch approach allows for more optimizations with low arity operations and allows for better workarounds on some broken compilers, it is not necessarily faster in all cases.

I have kind of been ignoring the problem of errors thus far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants