Topic: Concepts - What is the State of the Art, was:Likely C++0x features


Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 22 Aug 2004 03:44:59 GMT
Raw View
andy@servocomm.freeserve.co.uk (kwikius) writes:

> On the theme of concepts and enable if. enable_if works great on
> functions.
> I am wondering if the same idea could not be used on class templates
> too:

Not sure if this is what you had in mind, but it is already known that
enable_if works to limit the applicability of class template partial
specializations.  See
http://boost-consulting.com/boost/libs/utility/enable_if.html or any
of

[1] Jaakko J=E4rvi, Jeremiah Willcock, Howard Hinnant, and Andrew
    Lumsdaine. Function overloading based on arbitrary properties of
    types. C/C++ Users Journal, 21(6):25--32, June 2003.


[2] Jaakko J=E4rvi, Jeremiah Willcock, and Andrew
    Lumsdaine. Concept-controlled polymorphism. In Frank Pfennig and
    Yannis Smaragdakis, editors, Generative Programming and Component
    Engineering, volume 2830 of LNCS, pages 228--244. Springer Verlag,
    September 2003.


[3] David Vandevoorde and Nicolai M. Josuttis. C++ Templates: The
    Complete Guide. Addison-Wesley, 2002.


--=20
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Sat, 21 Aug 2004 17:08:56 GMT
Raw View
andy@servocomm.freeserve.co.uk (kwikius) wrote in message news:<2873fa46.0408080136.1ec45b6c@posting.google.com>...
> tslettebo@hotmail.com ("Terje Sletteb ") wrote in message news:<4112b5c
> 4$1@news.broadpark.no>...
> > "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
> > news:hinnant-83C9B9.13454103082004@syrcnyrdrs-03-ge0.nyroc.rr.com...
> > > In article <2873fa46.0408030347.54b960ed@posting.google.com>,
> > >  andy@servocomm.freeserve.co.uk (kwikius) wrote:
> > >
> > > I suspect that the original motivation for concepts was to improve er
>  ror
> > > messages.  If I'm recalling correctly, concepts were informally propo
>  sed
> > > for C++0X during a "wishlist" session at the Fall '01 standards meeti
>  ng.
> > > At the time, I voiced an opinion on the subject, and I'll voice it he
>  re
> > > as well:
> > >
> > > At the time I asked for my "compile time bool", compiler writers assu
>  red
> > > me that they can not back out of arbitrarily complex expressions when
>  a
> > > compile time error is met.  And I believe them.
> >
> > Hum, in that case the current concepts proposal (N1522, N1536 and N1510
>  ) may
> > have some serious problems, as it relies on "usage" to specify concepts
> > (similar to BCCL).
>
> Or a pragmatic solution might be to restrict Concepts initially to
> things that can be checked by type computation. Things such as
> DefaultConstructibility would require manual specialisation of a e.g
> is default constructible<T> style traits class.
>
> regards
> Andy Little

On the theme of concepts and enable if. enable_if works great on
functions.
I am wondering if the same idea could not be used on class templates
too:
 Here a simple struct returning a type but could be any class template
Perhaps if keyword could be used, as if is not usually allowed outside
function scope:

inside the if statement any compile time bool exactly like
static_assert

// here the default template definition
template<typename A, typename B>
if( Condition<A,B>::value ) <--- ignore if condition fails for A,B
struct getResult;
{
    typedef Result<A,B> type;
};


template< typename A, typename B>
// if the condition evaluates true
/// allow this specialisataion to be considered
if( Condition<A,B>::value )
struct Result_of<MyUdt<A>, B>
{
    typedef   Result<MyUdt<A>,B> type;
}
//.. etcetera
template< typename A, typename B>
if( ! Condition<A,B>::value )
struct Result_of<MyUdt<A>, B>
{
    typedef   OtherResult<MyUdt<A>,B> type;
}

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Tue, 24 Aug 2004 02:45:36 GMT
Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<upt5k6o2o.fsf@boost-consulting.com>...
> andy@servocomm.freeserve.co.uk (kwikius) writes:
>
> > On the theme of concepts and enable if. enable if works great on
> > functions.
> > I am wondering if the same idea could not be used on class templates
> > too:
>
> Not sure if this is what you had in mind, but it is already known that
> enable if works to limit the applicability of class template partial
> specializations.  See
> http://boost-consulting.com/boost/libs/utility/enable if.html

[other links]

Thanks. I didnt know that. This makes enable_if a very powerful tool.
(It does pretty much Exactly what I need :-)  )
It will come in very handy in my result_type mechanism invoked as
binary_operation<A,Op,B>::result_type
I was slightly concerned that adding an extra parameter to it might
break things as I have around 700+ references to this in my library,
However initial tests suggest that adding the default parameter doesnt
break anything, which is extremely good news and should now result in
a useful decrease in size as well as enabling new specialisations of
binary_operation to be added without causing ambiguities. Up to now
adding any new type (for instance I am currently working on a type
representing a coordinate), together with its binary_operation
specialisations would cause ambiguities requiring yet more
specialisations for combinations of types, especially UDTs. This was a
major weakness in the whole scheme.

One point... When using enable_if in a class-template it is obviously
more intrusive than when used in a function return type, because it
requires the extra parameter, whereas in a function return type it
works 'quietly', whereas the use of if(...) in the previous post would
not. Perhaps in the long term constructs such as if(..) and further
things such as switch...case (working on types :-) ) ... even
functions will replace classes in metaprogramming so I still think the
use of if(...) above is an interesting avenue to explore.

Thanks again for the above information. It has given a major 'boost'
to my library.

And of course in answer to the subject line, it does appear that it is
possible to use Concepts in code right now. Magic!

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Sun, 15 Aug 2004 05:24:01 GMT
Raw View
tslettebo@hotmail.com ("Terje Sletteb=F8") writes:

| "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
| news:hinnant-83C9B9.13454103082004@syrcnyrdrs-03-ge0.nyroc.rr.com...
| > In article <2873fa46.0408030347.54b960ed@posting.google.com>,
| >  andy@servocomm.freeserve.co.uk (kwikius) wrote:
| >
| > I suspect that the original motivation for concepts was to improve er=
ror
| > messages.  If I'm recalling correctly, concepts were informally propo=
sed
| > for C++0X during a "wishlist" session at the Fall '01 standards meeti=
ng.
| > At the time, I voiced an opinion on the subject, and I'll voice it he=
re
| > as well:

Overloading on concepts are key motivations too as listed in the
"design choices" paper.

| > At the time I asked for my "compile time bool", compiler writers assu=
red
| > me that they can not back out of arbitrarily complex expressions when=
 a
| > compile time error is met.  And I believe them.

At the Kona meeting, someone (unfortunately I cannot remember the
name) pointed out that that problem has a solution: just dump the
current state before doing a speculative instantiation!
Yes, you don't want your C++ compiler do that often :-) :-)

I seem to remember that Doug Gregor reported he was able to modify GCC
to do speculative instantiation, without causing any problem in his
testcases.=20
I was a bit skeptical but I did not came with any concrete counter-exampl=
e.

Anyway, not all C++ compilers are implemented using the same model, so
yes care needs exercising.

| Hum, in that case the current concepts proposal (N1522, N1536 and N1510=
) may
| have some serious problems, as it relies on "usage" to specify concepts
| (similar to BCCL).

Designing a concept system that evolves existing compilers -- designed
with the assumption A[1] in mind -- is as not easy as designing a
concept system for a brand new C++ compiler written from scratch :-/

There is a conjecture saying that pattern based approach would be
semantically equivalent to pseudo signature based concept.  If that
conjecture were true, then it would mean that the current difficulties
are essentially syntactic or apparant.

[1] Assumption A:
      A C++ program fragment is either acceptable or unacceptable.
      If unacceptable, there is no point in modifying the compiler
      state reversibly, because the program is going to be rejected
      and nobody cares about the compiler state after rejection.

--=20
                                                        Gabriel Dos Reis
                                                         gdr@cs.tamu.edu
  Texas A&M University -- Computer Science Department
 301, Bright Building -- College Station, TX 77843-3112

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tslettebo@hotmail.com ("Terje Sletteb ")
Date: Sun, 15 Aug 2004 20:30:50 GMT
Raw View
"Gabriel Dos Reis" <gdr@cs.tamu.edu> wrote in message
news:m3657lo0bw.fsf@merlin.cs.tamu.edu...

>| "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
>| news:hinnant-83C9B9.13454103082004@syrcnyrdrs-03-ge0.nyroc.rr.com...
>| > In article <2873fa46.0408030347.54b960ed@posting.google.com>,
>| >  andy@servocomm.freeserve.co.uk (kwikius) wrote:

>| > At the time I asked for my "compile time bool", compiler writers
assured
>| > me that they can not back out of arbitrarily complex expressions when a
>| > compile time error is met.  And I believe them.

>At the Kona meeting, someone (unfortunately I cannot remember the
>name) pointed out that that problem has a solution: just dump the
>current state before doing a speculative instantiation!
>Yes, you don't want your C++ compiler do that often :-) :-)

Hm, interesting. To take one example from N1510:

concept Value_type {
  constraints(Value_type a)
  {
    Value_type b = a; // copy initialization
    a = b; // copy assignment
    Value_type v[] = { a }; // not reference
  }
};

template<Value_type V> void swap(V a, V b)
{
  V tmp = a;
  a = b;
  b = a;
}

class Glob {
private:
  void operator=(Glob&); // prevent copying
  // .
};

void f()
{
  int a;
  int b;
  swap(a,b); // ok: we can copy ints
  Glob x;
  Glob y;
  swap(x,y); // error: we can't copy Globs
}

If the "undo"-approach is taken, then at least the compiler knows when to
dump the current state, or, if it's more efficient, make the operations that
follow undoable using some other means. At the instantiations swap(a,b) and
swap(x,y), then if it hasn't already been done for ints and Globs, it could
then "instantiate" the Value_type concepts with the types (substituting the
types for "Value_type", and see if it compiles), and if that fails, bail out
by either restoring the state prior to the "instantiation", or undoing the
operations some other way.

>There is a conjecture saying that pattern based approach would be
>semantically equivalent to pseudo signature based concept.  If that
>conjecture were true, then it would mean that the current difficulties
>are essentially syntactic or apparant.

Also interesting. Are you saying that:

Result r = a + b; // Usage-based concept specification

could somehow be turned into:

(something convertible to Result) operator+((something convertible from a's
type), (something convertible from b's type)) // Or member function

which may be subsequent looked up using conventional overload resolution? If
so, how to deal with the "something..." parts?

Regards,

Terje


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Mon, 9 Aug 2004 04:21:36 GMT
Raw View
tslettebo@hotmail.com ("Terje Sletteb=F8") wrote in message news:<4112b5c=
4$1@news.broadpark.no>...
> "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
> news:hinnant-83C9B9.13454103082004@syrcnyrdrs-03-ge0.nyroc.rr.com...
> > In article <2873fa46.0408030347.54b960ed@posting.google.com>,
> >  andy@servocomm.freeserve.co.uk (kwikius) wrote:
> >
> > I suspect that the original motivation for concepts was to improve er=
ror
> > messages.  If I'm recalling correctly, concepts were informally propo=
sed
> > for C++0X during a "wishlist" session at the Fall '01 standards meeti=
ng.
> > At the time, I voiced an opinion on the subject, and I'll voice it he=
re
> > as well:
> >
> > At the time I asked for my "compile time bool", compiler writers assu=
red
> > me that they can not back out of arbitrarily complex expressions when=
 a
> > compile time error is met.  And I believe them.
>=20
> Hum, in that case the current concepts proposal (N1522, N1536 and N1510=
) may
> have some serious problems, as it relies on "usage" to specify concepts
> (similar to BCCL).

Or a pragmatic solution might be to restrict Concepts initially to
things that can be checked by type computation. Things such as
DefaultConstructibility would require manual specialisation of a e.g
is_default_constructible<T> style traits class.

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Tue, 10 Aug 2004 05:51:40 GMT
Raw View
tslettebo@hotmail.com ("Terje Sletteb=F8") wrote in message news:<4112b58=
c@news.broadpark.no>...
> "kwikius" <andy@servocomm.freeserve.co.uk> wrote in message
> news:2873fa46.0408030347.54b960ed@posting.google.com...
> > tslettebo@hotmail.com ("Terje Sletteb=F8") wrote in message
>  news:<410ebfb3@news.broadpark.no>...
> > > "kwikius" <andy@servocomm.freeserve.co.uk> wrote in message
> > > news:2873fa46.0407311135.33810bdb@posting.google.com...
> > > >
> > > > Ok we will always need types as primitives, but One use of concep=
ts
> > > > might be to solve some of the current type issues:
> > >
> > > As you know, we may get some effects of concepts in the current lan=
guage
> > > using enable_if and type traits, as well as some creative use of
> > > metaprogramming. :) However, as mentioned in another posting, "conc=
ept
> > > inheritance"
> >
> > I'm wondering if "concept inheritance" might not be better named
> > "concept refinement"
>=20
> Right. I was thinking of it being analoguous to OO subclassing/inherita=
nce
> (and the syntax I mentioned, "concept forward_iterator : input_iterator=
",
> looks like "inheritance"), but it is of course refinement, as you say.
>=20
> > > and "best fit" still has to be "simulated".
> >
> > and needs some rules of course...
>=20
> I think it might use similar rules to template specialisations, when it
> comes to determine what is a "better fit", and what is "more
> specialised/refined".

Except bearing in mind that from the compilers point of view a Concept
represents an arbitrary set of types. Concepts would seem to require
*some combination* of
1) template specialisation rules.( How does one extricate ConceptX<T>*
from ConceptX<T*> and so on)
2) function overloading rules
3) something based on what?  dynamic_cast for derived/refined concepts
Its a formidable list ... to me anyway.

> > I have looked briefly at enable_if. As the examples stand they requir=
e
> > a reasonable amount of work per function to implement(ie not reusable
> > unlike boost:::concept_check)
>=20
> Unless, of course, you have a library like boost:::concept_check for
> this...:
>=20
> template<class Iterator>
> typename enable_if<is_random_access_iterator<Iterator> >::type
> sort(Iterator begin,Iterator end)
> {
>   // ...
> }

Hmm...  Practically "Concepts in use" ... Cool :-)

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Wed, 4 Aug 2004 03:45:11 GMT
Raw View
On Tue, 3 Aug 2004, Howard Hinnant wrote:

| In article <2873fa46.0408030347.54b960ed@posting.google.com>,
|  andy@servocomm.freeserve.co.uk (kwikius) wrote:
|
| > You will get custom error messages with static_assert which makes it
| > supremely attractive.Why bother with concept_checking or enable_if ?
|
| There's a fundamental misunderstanding going on here.  enable_if does
| not exist to produce better error messages.  enable_if exists to
| disqualify a templated function (or member function) from the overload
| set, so that other overloads can be chosen when more appropriate.  If no
| other overload exists, enable_if isn't likely to lead to a good error
| message (perhaps something along the lines of "does not match").
|
| I am not getting a clear message from the proponents of concept checking
| about what problem they intend to solve.

Which part of the messages in the three "concept papers" do you find
unclear?

  * Concepts -- Design choices for template argument checking (N1522)
  * Concepts -- syntax and composition (N1536)
  * Concept checking -- A more abstract complement to type checking (N1510)

(this is a genuine question).

--
                                                        Gabriel Dos Reis
                                                         gdr@cs.tamu.edu
  Texas A&M University -- Computer Science Department
 301, Bright Building -- College Station, TX 77843-3112

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Wed, 4 Aug 2004 15:02:14 GMT
Raw View
In article <Pine.GSO.4.58.0408032154060.22310@unix.cs.tamu.edu>,
 gdr@cs.tamu.edu (Gabriel Dos Reis) wrote:

> On Tue, 3 Aug 2004, Howard Hinnant wrote:
>
> | In article <2873fa46.0408030347.54b960ed@posting.google.com>,
> |  andy@servocomm.freeserve.co.uk (kwikius) wrote:
> |
> | > You will get custom error messages with static_assert which makes it
> | > supremely attractive.Why bother with concept_checking or enable_if ?
> |
> | There's a fundamental misunderstanding going on here.  enable_if does
> | not exist to produce better error messages.  enable_if exists to
> | disqualify a templated function (or member function) from the overload
> | set, so that other overloads can be chosen when more appropriate.  If no
> | other overload exists, enable_if isn't likely to lead to a good error
> | message (perhaps something along the lines of "does not match").
> |
> | I am not getting a clear message from the proponents of concept checking
> | about what problem they intend to solve.
>
> Which part of the messages in the three "concept papers" do you find
> unclear?
>
>   * Concepts -- Design choices for template argument checking (N1522)
>   * Concepts -- syntax and composition (N1536)
>   * Concept checking -- A more abstract complement to type checking (N1510)
>
> (this is a genuine question).

If a concept excludes a template from the overload resolution set in a
particular context, and if there is no best viable overload for the
compiler to bind the call to, how does the compiler generate an
"improved diagnostic"?  Should it go back and explain for each overload
it rejected, exactly why?  I can see how this might be very reasonable
if there was only one candidate to begin with.  But if there are
multiple candidates, I'm much less clear.

My experience to date suggests that enable_if is used in situations
specifically because there are expected to be multiple candidates in the
overload set.  And when none of the candidates work out, the error
messages tend to look a lot like:

List< int& > lst4;    // error: no match

On the other hand, I've been able to generate very high quality error
messages with something along the lines of:

template <class T>
class List
{
    static_assert(!is_reference<T>::value,
        "List's template parameter can not be a reference.");
...
};

That is, in my limited experience, I usually get better diagnostics
after overload resolution has selected the best viable function, and the
compiler is now busy instantiating it.

Imho, I would like to see concepts concentrate more on guiding overload
resolution, than better diagnostics.  If concepts can provide the
functionality of enable_if (or better), but with better syntax, or more
flexibility, I think that would be very good.  I am pleased that the
post Kona papers devoted space to the overload resolution issue.

It would also help if any future concepts paper would relate itself to
the enable_if technique, and if still applicable, to static_assert as
well.  I found it confusing that these existing techniques
(static_assert has existed in macro form for years) which seemingly
cover similar ground, were not mentioned.  A little compare/contrast
would build upon our common knowledge and thus communicate very
succinctly.

Thank you for your efforts in the concepts area.

-Howard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Thu, 5 Aug 2004 18:04:59 GMT
Raw View
hinnant@metrowerks.com (Howard Hinnant) wrote in message news:<hinnant-83C9B9.13454103082004@syrcnyrdrs-03-ge0.nyroc.rr.com>...
> In article <2873fa46.0408030347.54b960ed@posting.google.com>,
>  andy@servocomm.freeserve.co.uk (kwikius) wrote:
>
> > You will get custom error messages with static_assert which makes it
> > supremely attractive.Why bother with concept_checking or enable_if ?
>
> There's a fundamental misunderstanding going on here.  enable_if does
> not exist to produce better error messages.  enable_if exists to
> disqualify a templated function (or member function) from the overload
> set, so that other overloads can be chosen when more appropriate.  If no
> other overload exists, enable_if isn't likely to lead to a good error
> message (perhaps something along the lines of "does not match").

Apologies. I am only now getting up to speed on enable_if. I am happy
to accept that remark was incorrect.

>
> I am not getting a clear message from the proponents of concept checking
> about what problem they intend to solve.
>
> If it is better error messages, then surely static_assert will play a
> role, since this gives you custom error messages.
>
> If it is to guide overload resolution by removing templated functions
> from the overload set when a type does not meet a certain concept, then
> enable_if shows how to do that in today's language.  Perhaps "concepts"
> can help us do that with better syntax?  Perhaps "concepts" can help
> provide compile time checks that aren't possible with today's traits
> classes?

[snip]

> A "concept" is essentially a compile time computation on a type.  If
> that computation is going to end up as a compile time error every time
> the type fails to "meet the concept", then I see very little use for
> concepts.

In the boost::concept_check sense and in D&E a concept is not exactly
equivalent to a compile_time computation. Rather it is a way to
exerise a types "requirements". For example Is a type convertible to
bool? This cannot be checked easily by compile time computation.
(here trying out the new (for me) functionality of enable_if and
ignoring how useful this particular "overload set" is in practise)


// OK.. there are probably some flaws here...
    template< typename T> struct BooleableConcept{
 T*  pt; //avoid default constructibility
        void constraints()
        {
            bool b = *pt;
        }
    };


// for bools
template<typename Bool>
typename boost::enable_if<
   boost::is_same<Bool,bool>
>::type myFunc( Bool  b)
{
    std::cout << "bool\n";
}

//anything else
template<typename Booleable>
typename boost::disable_if<
   boost::is_same<Booleable,bool>
>::type myFunc( Booleable  b)
{
  //trap anything not booleable
   boost::function_requires<BooleableConcept<Booleable> >();

   std::cout << "booleable\n";
}

However contradicting my previous remarks, some concepts such as
"is_reference<T>" are more easily checked by compile_time
computations.

The difference between the two mechanisms is that "excercising the
requirements" is designed to make use of the standard compiler
diagnostics, while compile_time computation obviously requires
programmer input to decipher what is going on, so there does seem to
be a place for static_assert too.

>
> At the time I asked for my "compile time bool", compiler writers assured
> me that they can not back out of arbitrarily complex expressions when a
> compile time error is met.  And I believe them.  So the challenge of
> concepts is to find a way for the programmer to ask the compiler if a
> type has certain qualities, without requiring the compiler to parse
> arbitrarily complex expressions in order to answer the question.

I think one problem with concepts is that they could potentially be
used in many different ways. This looks attractive:

if_c<DefaultConstructibleConcept<X>() == true ,Y<X>, Z<X> >::type;

(Note: this doesnt sit well with the current working papers where e.g
a bool return is used differently )

Perhaps the real challenge however is to narrow down expecations to
something workable.


regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Thu, 5 Aug 2004 20:47:14 GMT
Raw View
In article <2873fa46.0408050310.22fdb2da@posting.google.com>,
 andy@servocomm.freeserve.co.uk (kwikius) wrote:

> For example Is a type convertible to
> bool? This cannot be checked easily by compile time computation.

Check out:

loki::Conversion<T,U>::exists
http://www.moderncppdesign.com/

boost::is_convertible<T,U>::type
http://www.boost.org/libs/type_traits/index.html

std::tr1::is_convertible<T,U>::type
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1424.htm

:-)

but nevertheless you have a valid point:  there exists type queries we
would like to make and do not know how.  E.g.:

> if_c<DefaultConstructibleConcept<X>() == true ,Y<X>, Z<X> >::type;

I hope the concepts work will help us expand our ability to query a type
for its capabilities.

> Perhaps the real challenge however is to narrow down expecations to
> something workable.

<nod>

-Howard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Fri, 6 Aug 2004 15:23:03 GMT
Raw View
hinnant@metrowerks.com (Howard Hinnant) wrote in message news:<hinnant-C67990.15500405082004@syrcnyrdrs-03-ge0.nyroc.rr.com>...
> In article <2873fa46.0408050310.22fdb2da@posting.google.com>,
>  andy@servocomm.freeserve.co.uk (kwikius) wrote:
>
> > For example Is a type convertible to
> > bool? This cannot be checked easily by compile time computation.
>
> Check out:
>
> loki::Conversion<T,U>::exists
> http://www.moderncppdesign.com/
>
> boost::is_convertible<T,U>::type
> http://www.boost.org/libs/type_traits/index.html
>
> std::tr1::is_convertible<T,U>::type
> http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1424.htm
>
> :-)

Thanks for the links.

> but nevertheless you have a valid point:  there exists type queries we
> would like to make and do not know how.  E.g.:
>
> > if_c<DefaultConstructibleConcept<X>() == true ,Y<X>, Z<X> >::type;
>
> I hope the concepts work will help us expand our ability to query a type
> for its capabilities.

It strikes me now from the above discussion that concept_checking as
exemplified by boost::concept_check is a primitive instrument. You are
getting the required true/false result of your interrogation, but only
by the primitive means of either a silent "true", or a "false"
resulting in the possibly undesirable side effects of error messages
and failed compilation. OTOH type_traits can also be seen as a concept
interrogation mechanism, however its much more lightweight. It does
one simple thing well. In this case the error message functionality is
available if you want it, but has been neatly packaged out into
static_assert. Its optional.

It would also seem that enable_if provides some of the functionality
one could expect from concepts, but is notably useable with
type_traits but not with boost:concept_check. If Concepts are to
emerge in the role of overload resolution, they would presumably need
to have something like type_traits/enable_if functionality without the
current baggage of boost::concept_check.

Perhaps the way forward for concepts is to have a good look at
type_traits and emerge as a sort of "super type traits" and with
CFINNAE (Concept Failure is not necessarily an error). IOW type_traits
is a better predecessor for a Concept than boost::concept_check.

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tslettebo@hotmail.com ("Terje Sletteb ")
Date: Fri, 6 Aug 2004 18:23:25 GMT
Raw View
"kwikius" <andy@servocomm.freeserve.co.uk> wrote in message
news:2873fa46.0408030347.54b960ed@posting.google.com...
> tslettebo@hotmail.com ("Terje Sletteb   ") wrote in message
news:<410ebfb3@news.broadpark.no>...
> > "kwikius" <andy@servocomm.freeserve.co.uk> wrote in message
> > news:2873fa46.0407311135.33810bdb@posting.google.com...
> > >
> > > Ok we will always need types as primitives, but One use of concepts
> > > might be to solve some of the current type issues:
> >
> > As you know, we may get some effects of concepts in the current language
> > using enable_if and type traits, as well as some creative use of
> > metaprogramming. :) However, as mentioned in another posting, "concept
> > inheritance"
>
> I'm wondering if "concept inheritance" might not be better named
> "concept refinement"

Right. I was thinking of it being analoguous to OO subclassing/inheritance
(and the syntax I mentioned, "concept forward_iterator : input_iterator",
looks like "inheritance"), but it is of course refinement, as you say.

> > and "best fit" still has to be "simulated".
>
> and needs some rules of course...

I think it might use similar rules to template specialisations, when it
comes to determine what is a "better fit", and what is "more
specialised/refined".

> > The following uses Boost enable_if, type traits, and MPL.
>
> Thanks for the examples. And this basically answers my original
> question as to the state of the art for Concepts in the language now.
> I have looked briefly at enable_if. As the examples stand they require
> a reasonable amount of work per function to implement(ie not reusable
> unlike boost:::concept_check)

Unless, of course, you have a library like boost:::concept_check for
this...:

template<class Iterator>
typename enable_if<is_random_access_iterator<Iterator> >::type
sort(Iterator begin,Iterator end)
{
  // ...
}

The above is a simplified example, but it may check for other requirements
the same way, such as the value_type being StrictWeaklyComparable.

> and the implementation is poking right
> in ones face. This could presumably be improved so that the
> functionality is encapsulated somehow. The error messages are terse
> but only more experimentation will tell if the information helps in
> quickly pinpointing "conceptual" errors the way boost::concept_check
> does. I would argue that boost::concept_check could be used as an
> alternative in the examples too.

Sure.

> > > void myFunc1( Booleable b); // anything convertible
> >
> > void myFunc1( bool b); // ;)
>
> except this dominates the next version...
> >
> > > void myFunc1( Bool b); // only bool allowed
> >
> > template<class T>
> > typename enable_if<
> >   is_same<T,bool>
> > >::type myFunc(T n);
>
> //^^unused if above function defined
>
> These last two examples to some extent reinforce why "proper" Concepts
> might be useful in resolving some type issues and present a more
> coherent, (or at least different) view on function arguments than
> types.

Indeed. Above, we have the "best fit" issue, again (aka ambiguous overload).

> > static_assert (and the Boost Concept Check Library that you mention)
doesn't
> > allow fine-tuning of the overload set like language support for
concepts, or
> > use of enable_if like above.
>
> Well it could be pushed to do so...everything ultimately can be
> resolved to true or false. Interestingly the implementation of
> BOOST_STATIC_ASSERT and enable_if have similarities in this respect.
> You will get custom error messages with static_assert which makes it
> supremely attractive.Why bother with concept_checking or enable_if ?

Because of the mentioned fine-tuning of the overload set. The point is that
you may for example have three overloaded functions, which are selected
between depending on the iterator type passed (like std::advance). With
static_assert or BCCL, you would get ambiguous overloads (because the BCCL
checking is done _after_ overload resolution), whereas with concepts or
enable_if, it would resolve to the correct overloaded function.

> > It's rather difficult to do concept checking like the above, in the
current
> > language, as some things have no known technique for detection.
Constructors
> > is one example, so you can't have a trait that works reliably for
> > DefaultConstructible, for example.
>
> Well I'm not sure that boost::concept_check cant be used here...
> ..actually in boost/concept_check.hpp

Sure it can. BCCL can handle all of this, but then you won't get the
mentioned ability to _overload on concepts_ (fine-tuning the overload set),
which I think is a key advantage of concepts. What I said was: "It's rather
difficult to do concept checking _like the above_" (emphasis added).

I see that Howard Hinnant make this point in a later posting, as well. To
quote from his posting:

Howard Hinnant:

>If it is to guide overload resolution by removing templated functions
>from the overload set when a type does not meet a certain concept, then
>enable_if shows how to do that in today's language.  Perhaps "concepts"
>can help us do that with better syntax?  Perhaps "concepts" can help
>provide compile time checks that aren't possible with today's traits
>classes?

I think these are the key points.

>  template<typename T>
>     struct DefaultConstructibleConcept{
>         void constraints()
>         {
>             T t;
>             ignore_unused_variable_warning(t); //...groan
>         }
>     };
>
> template <typename T>
> void myFunc()
> {
>     function_requires<DefaultConstructibleConcept<T> >();
>  ...
> }
>
> IOW enable_if does not entirely nullify concept_check.

Sure. Especially since, as mentioned, there are several concepts that can
only be partially, if at all, be detected in the current language. With
"detected" I mean being detected as a trait, not getting an error message.

Regards,

Terje


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tslettebo@hotmail.com ("Terje Sletteb ")
Date: Fri, 6 Aug 2004 18:23:39 GMT
Raw View
"Howard Hinnant" <hinnant@metrowerks.com> wrote in message
news:hinnant-83C9B9.13454103082004@syrcnyrdrs-03-ge0.nyroc.rr.com...
> In article <2873fa46.0408030347.54b960ed@posting.google.com>,
>  andy@servocomm.freeserve.co.uk (kwikius) wrote:
>
> I suspect that the original motivation for concepts was to improve error
> messages.  If I'm recalling correctly, concepts were informally proposed
> for C++0X during a "wishlist" session at the Fall '01 standards meeting.
> At the time, I voiced an opinion on the subject, and I'll voice it here
> as well:
>
> At the time I asked for my "compile time bool", compiler writers assured
> me that they can not back out of arbitrarily complex expressions when a
> compile time error is met.  And I believe them.

Hum, in that case the current concepts proposal (N1522, N1536 and N1510) may
have some serious problems, as it relies on "usage" to specify concepts
(similar to BCCL).

> So the challenge of
> concepts is to find a way for the programmer to ask the compiler if a
> type has certain qualities, without requiring the compiler to parse
> arbitrarily complex expressions in order to answer the question.

Better reflection might be a way, such as the XTI et al project.

Regards,

Terje


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Sat, 31 Jul 2004 19:47:16 GMT
Raw View
tslettebo@hotmail.com ("Terje Sletteb   ") wrote in message news:<410aabfa$1@news.broadpark.no>...
> "kwikius" <andy@servocomm.freeserve.co.uk> wrote in message
> news:2873fa46.0407241512.58c3c2e1@posting.google.com...
> > Usenet@aristeia.com (Scott Meyers) wrote in message
>  news:<MPG.1b5e67da917bb68d989775@news.hevanet.com>...
> >
> > Concepts.
> > Basically template parameters that conform to a set of requirements.
> > One day Concepts will replace types as C++ primitives IMO.
>
> They're not really a replacement for types. Rather, they're a way of
> grouping related types together (such as all types that are Assignable, for
> example). As you said, template parameters (instantiated with types) that
> conform to a set of requirements.

Ok we will always need types as primitives, but One use of concepts
might be to solve some of the current type issues:

void myFunc( SignedInteger n); // any Integer ... but must be signed
.no unsigned conv
void myFunc( Signed32BitInteger n); // Signed && Only 32 bits wanted
void myFunc1( Booleable b); // anything convertible
void myFunc1( Bool b); // only bool allowed

Whatever.. I am concerned that Concepts may never happen. Firstly we
will have static_assert which can be pushed into the same job and will
discourage further work on Concepts because it is easy to implement
and available.

I seriously do hope that Concepts happen in C++. For my own small
contribution I am using similar functionality to boost::concept_check
and am trying to think more in terms of Concepts, bothly at the
documentation level and by consistently naming template parameters. I
would like to do more to further the cause of Concepts, so any
information about the current state of the art, (and here I mean stuff
that can be implemented Now in code rather than theory of Concepts and
how they will work) would be appreciated.

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tslettebo@hotmail.com ("Terje Sletteb ")
Date: Mon, 2 Aug 2004 22:53:28 GMT
Raw View
"kwikius" <andy@servocomm.freeserve.co.uk> wrote in message
news:2873fa46.0407311135.33810bdb@posting.google.com...
>
> Ok we will always need types as primitives, but One use of concepts
> might be to solve some of the current type issues:

As you know, we may get some effects of concepts in the current language
using enable_if and type traits, as well as some creative use of
metaprogramming. :) However, as mentioned in another posting, "concept
inheritance" and "best fit" still has to be "simulated".

> void myFunc( SignedInteger n); // any Integer ... but must be signed
> .no unsigned conv

The following uses Boost enable_if, type traits, and MPL.

typedef mpl::vector<signed char,short,int,long> signed_ints; // "char" might
be signed or unsigned (implementation-defined)

template<class T>
typename disable_if<
  is_same<
    mpl::find<signed_ints,T>::type,
    mpl::end<signed_ints>::type
  >
>::type myFunc(T n);

> void myFunc( Signed32BitInteger n); // Signed && Only 32 bits wanted

template<class T>
typename enable_if<
  is_same<T,int32_t>
>::type myFunc(T n);

> void myFunc1( Booleable b); // anything convertible

void myFunc1( bool b); // ;)

> void myFunc1( Bool b); // only bool allowed

template<class T>
typename enable_if<
  is_same<T,bool>
>::type myFunc(T n);

> Whatever.. I am concerned that Concepts may never happen. Firstly we
> will have static_assert which can be pushed into the same job and will
> discourage further work on Concepts because it is easy to implement
> and available.

static_assert (and the Boost Concept Check Library that you mention) doesn't
allow fine-tuning of the overload set like language support for concepts, or
use of enable_if like above.

> I seriously do hope that Concepts happen in C++. For my own small
> contribution I am using similar functionality to boost::concept_check
> and am trying to think more in terms of Concepts, bothly at the
> documentation level and by consistently naming template parameters. I
> would like to do more to further the cause of Concepts, so any
> information about the current state of the art, (and here I mean stuff
> that can be implemented Now in code rather than theory of Concepts and
> how they will work) would be appreciated.

I think the above is some examples of this. :)

It's rather difficult to do concept checking like the above, in the current
language, as some things have no known technique for detection. Constructors
is one example, so you can't have a trait that works reliably for
DefaultConstructible, for example.

Paul Mensonides have suggested that, using an "extended SFINAE", where
errors in any expression at instantiation would simply remove the function
from the overload set, one might detect the presence of a constructor.

Regards,

Terje


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andy@servocomm.freeserve.co.uk (kwikius)
Date: Tue, 3 Aug 2004 17:00:29 GMT
Raw View
tslettebo@hotmail.com ("Terje Sletteb   ") wrote in message news:<410ebfb3@news.broadpark.no>...
> "kwikius" <andy@servocomm.freeserve.co.uk> wrote in message
> news:2873fa46.0407311135.33810bdb@posting.google.com...
> >
> > Ok we will always need types as primitives, but One use of concepts
> > might be to solve some of the current type issues:
>
> As you know, we may get some effects of concepts in the current language
> using enable_if and type traits, as well as some creative use of
> metaprogramming. :) However, as mentioned in another posting, "concept
> inheritance"

I'm wondering if "concept inheritance" might not be better named
"concept refinement"

> and "best fit" still has to be "simulated".

and needs some rules of course...

> The following uses Boost enable_if, type traits, and MPL.

Thanks for the examples. And this basically answers my original
question as to the state of the art for Concepts in the language now.
I have looked briefly at enable_if. As the examples stand they require
a reasonable amount of work per function to implement(ie not reusable
unlike boost:::concept_check) and the implementation is poking right
in ones face. This could presumably be improved so that the
functionality is encapsulated somehow. The error messages are terse
but only more experimentation will tell if the information helps in
quickly pinpointing "conceptual" errors the way boost::concept_check
does. I would argue that boost::concept_check could be used as an
alternative in the examples too.

[snip]

>
> > void myFunc1( Booleable b); // anything convertible
>
> void myFunc1( bool b); // ;)

except this dominates the next version...

>
> > void myFunc1( Bool b); // only bool allowed
>
> template<class T>
> typename enable_if<
>   is_same<T,bool>
> >::type myFunc(T n);

//^^unused if above function defined

These last two examples to some extent reinforce why "proper" Concepts
might be useful in resolving some type issues and present a more
coherent, (or at least different) view on function arguments than
types. Now whether or how a Booleable might be disambiguated from a
SignedInteger is of course another matter...

>
> > Whatever.. I am concerned that Concepts may never happen. Firstly we
> > will have static_assert which can be pushed into the same job and will
> > discourage further work on Concepts because it is easy to implement
> > and available.
>
> static_assert (and the Boost Concept Check Library that you mention) doesn't
> allow fine-tuning of the overload set like language support for concepts, or
> use of enable_if like above.

Well it could be pushed to do so...everything ultimately can be
resolved to true or false. Interestingly the implementation of
BOOST_STATIC_ASSERT and enable_if have similarities in this respect.
You will get custom error messages with static_assert which makes it
supremely attractive.Why bother with concept_checking or enable_if ?

> > so any
> > information about the current state of the art, (and here I mean stuff
> > that can be implemented Now in code rather than theory of Concepts and
> > how they will work) would be appreciated.
>
> I think the above is some examples of this. :)

Absolutely... thanks again !

>
> It's rather difficult to do concept checking like the above, in the current
> language, as some things have no known technique for detection. Constructors
> is one example, so you can't have a trait that works reliably for
> DefaultConstructible, for example.

Well I'm not sure that boost::concept_check cant be used here...
..actually in boost/concept_check.hpp

 template<typename T>
    struct DefaultConstructibleConcept{
        void constraints()
        {
            T t;
            ignore_unused_variable_warning(t); //...groan
        }
    };

template <typename T>
void myFunc()
{
    function_requires<DefaultConstructibleConcept<T> >();
 ...
}

IOW enable_if does not entirely nullify concept_check. Between
enable_if and boost::concept_check there do seem to be some useful
mechanisms to implement concepts in the language now. One concern is
that the functionality provided by enable_if and boost::concept_check
dont mix too well, just from the point of view of consistent framework
for error messages and so on. That would seem to be desirable if true
Concepts are to evolve from the current schemes. Meanwhile I suspect
that static_assert may be used in concept_checking just because it
provides user definable error messages.

regards
Andy Little

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Tue, 3 Aug 2004 18:31:27 GMT
Raw View
In article <2873fa46.0408030347.54b960ed@posting.google.com>,
 andy@servocomm.freeserve.co.uk (kwikius) wrote:

> You will get custom error messages with static_assert which makes it
> supremely attractive.Why bother with concept_checking or enable_if ?

There's a fundamental misunderstanding going on here.  enable_if does
not exist to produce better error messages.  enable_if exists to
disqualify a templated function (or member function) from the overload
set, so that other overloads can be chosen when more appropriate.  If no
other overload exists, enable_if isn't likely to lead to a good error
message (perhaps something along the lines of "does not match").

I am not getting a clear message from the proponents of concept checking
about what problem they intend to solve.

If it is better error messages, then surely static_assert will play a
role, since this gives you custom error messages.

If it is to guide overload resolution by removing templated functions
from the overload set when a type does not meet a certain concept, then
enable_if shows how to do that in today's language.  Perhaps "concepts"
can help us do that with better syntax?  Perhaps "concepts" can help
provide compile time checks that aren't possible with today's traits
classes?

I suspect that the original motivation for concepts was to improve error
messages.  If I'm recalling correctly, concepts were informally proposed
for C++0X during a "wishlist" session at the Fall '01 standards meeting.
At the time, I voiced an opinion on the subject, and I'll voice it here
as well:

Concepts sound great.  But I don't want a compile time error if the
concept isn't met.  I want a compile-time bool.  I can do so much more
with a compile-time bool!  For example I could create a custom error
message by feeding that bool into static_assert.  Or for example I could
enable or disable a templated function (or member function), possibly
allowing another overload to bind to the call.

A "concept" is essentially a compile time computation on a type.  If
that computation is going to end up as a compile time error every time
the type fails to "meet the concept", then I see very little use for
concepts.

At the time I asked for my "compile time bool", compiler writers assured
me that they can not back out of arbitrarily complex expressions when a
compile time error is met.  And I believe them.  So the challenge of
concepts is to find a way for the programmer to ask the compiler if a
type has certain qualities, without requiring the compiler to parse
arbitrarily complex expressions in order to answer the question.

-Howard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]