Boost logo

Boost :

Subject: Re: [boost] [guidelines] why template errors suck
From: David Abrahams (dave_at_[hidden])
Date: 2010-09-28 14:14:20


At Tue, 28 Sep 2010 17:23:05 +0100,
Mathias Gaunard wrote:
>
> On 28/09/10 13:20, Dave Abrahams wrote:
> > On Sep 28, 2010, at 4:33 AM, Mathias Gaunard<mathias.gaunard_at_[hidden]> wrote:
> >
> >> I've done it and there was no particular problem. I just need to
> >> check the argument are input iterators and an unary function
> >> object taking the same value as the iterator value type and
> >> returning a boolean. (of course, by taking a particular value, I
> >> really mean taking something that can be converted from that
> >> particular value, and by returning a particular value I mean
> >> returning a type convertible to that value, but all of those
> >> implicit conversions are taken care of automatically by
> >> expressions)
> >
> > All of that handwaving is exactly where the problem is.
>
> I think I know where the problem is: you're confusing two distinct
> features that exist within the realm of concepts, and then comparing
> apples and oranges.
>
> The two features are:
> 1) the ability to check that a set of types model a concept,
> 2) the ability to check that the body of a function or class that
> requires certain parameters to be models of a particular concept is
> valid with the least amount of requirements that models of those
> concepts can provide.
>
> The former C++0x proposal provides both features.
> Boost.ConceptCheck provides both features as well, albeit using vastly
> different implementation techniques.

Actually the implementation technique for checking bodies is exactly
the same: the compiler generates archetypes internally.

> For better error messages in libraries written within Boost, feature 1)
> is vastly more important than feature 2), since the only thing 2) does
> is ensuring the library is self-consistent (i.e. there is no need for
> these tests at all once the code has been properly debugged), while 1)
> ensures the user is rightly providing the preconditions required by the
> library.

Ha, everyone underestimates the importance of feature 2). Without it
you are almost guaranteed to ship a buggy library, because the types
you test your library with will not touch the boundaries of what's
possible under the library's constraint specification. The library
issues list is littered with corrections and updates to the STL
specification because of this.

> In Boost.ConceptCheck, 1) is achieved by defining a template function,
> whose body (a statement) contains all the expressions (and may contain
> statements too) that are necessary for the types to model the concept.
> If instantiating this function fails, which means the types do not model
> the concept, then you get a hard error you cannot catch at compile-time.

Just for the record, I wrote the current implementation of
Boost.ConceptCheck, so I do understand how it works.

> What I'm suggesting is simply to replace that fairly dumb system of a
> function body by a set of expressions considered in an SFINAE
> context,

The current system isn't dumb for C++03; it's the best you can do for
many checks. There's no way to check for copy-constructibility, for
example, without causing a compile-time error when the check fails.

> which would allow to actually test whether the concept is being modeled
> or not without causing a hard error, which would be priceless in order
> to hugely improve the error messages.

I'm not convinced it would be a _huge_ improvement. You might be able
to get rid of one level of instantiation stack, but AFAICT that's not
a huge difference.

> ConceptCheck also provides the mechanism of archetypes to implement
> feature 2), but that is quite unrelated, despite your insistence on
> talking about it.

It's not unrelated to the reason this part of the thread started.
People were re-considering the design of Boost.ConceptCheck, and I
noted that valid expressions were not the best way to express
concepts.

> Yes, I agree that 2) helps in finding bugs in library code, such as
> possibly your find_if example, but it doesn't help at providing better
> error messages for the user assuming a bug-free library.

That's a big assumption. As I said, without a way to check template
bodies, you're almost guaranteed to ship a buggy library, and that
chance is *massively* increased by the use of a "valid expressions"
approach.

Unfortunately, without real concepts we may not be able to do better,
because the pseudo-signature approach inserts type conversions that
we'd have to write by hand. Now here's an interesting thought: write
a library using TMP that generates "concept wrappers" that will force
the necessary conversions. Would require heavy use of rvalue
references to avoid needless copies. Hmm...

> It's a feature for the library developer, not its user.

Is a bug-free library a feature for the library developer, or its
user? :-)

> I'm sorry, but I still don't see how your comments are at all relevant.

Depends what you think the question is. IMO if we're going to talk
about a library redesign for BCCL it should consider whether we can
express concepts more effectively.

> > When the computer is checking your work, you don't get that luxury ;-)
>
> Right, but here we're not talking about the computer checking my work,
> but checking that what the user is giving me is what I'm expecting, so
> that I can tell him what he did wrong without throwing too much noise at
> thim.

Maybe that's all you're talking about, but it's never been all I'm
talking about. Personally I'm not interested in a discussion that
doesn't at least attempt to address the other half of the problem.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk