From: Andrei Alexandrescu (See Website for Email) on
James Kanze wrote:
> But I've also used <generic.h>, in pre-template days, and
> I've used the Java Collections (which IMHO are globally better
> designed than the STL).

In case you planted that as a hook to have people ask you details
about that or your experience in the battlefield, feel free to :o).
"James, why are the Java Collections globally better designed than the
STL?" Have at it.

Andrei

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Virtanen Antti on
On 2005-10-02, James Kanze <kanze(a)none.news.free.fr> wrote:

>> Actually there is no 'type checking' involved with
>> templates. If a template instantiation compiles (produces
>> syntactically correct C++) it's ok, otherwise you see the
>> notorious error messages. Templates are untyped. The compiler
>> checks syntax, not types.
>
> Templates are resolved at compile time. And the compiler very
> definitly does type check the resulting instantiations. The
> results are as fully type safe as any normal C++ code.

Yes, but the idea is that "if it compiles, it's ok". I wouldn't say
this is much type checking in itself and the STL nor the C++ language
don't offer anything to enforce any other kind of rules on types.

> Which means that some errors will not be detected until
> instantiation, and that error messages refer to the
> instantiation, and not to the template. But precisely because
> they are a meta-language, they permit (amongst many other
> things) expressing type constraints which could otherwise only
> be expressed by means of extensive copy/paste, often with
> additional editing of the pasted code.

In this regard, "concepts" are a very good addition. The Boost.org
implementation of concepts doesn't even need changes the the actual
C++ language and gives a reasonably easy syntax for writing these
checks. Even very complex rules can be expressed fairly easy and the
ugly stuff is hidden away with the meta-programming. Sounds very good
to me.

In fact, boost.org "concept checking" was pointed out to me when I
asked if it was possible to check for certain rules on template type
parameter using template meta-programming :)

> I'm hardly what one could consider an expert with regards to
> templates, and I'm fairly sceptical concerning the applicability
> of the most advanced meta-programming techniques in commercial
> code, where other programmers have to understand what you've
> done.

This is precisely why there should be a "standard" way of doing these
meta-programming tricks. If I understood correctly some of the
"tricks" are quickly becoming part of the C++ standard so things are
going to a good direction.

> But I've also used <generic.h>, in pre-template days, and
> I've used the Java Collections (which IMHO are globally better
> designed than the STL). And given that experience, I can say
> that templates are a better solution that pure macros or than
> deriving everything from Object and depending on dynamic
> downcasting. A much better solution.

Yep.

--
// Antti Virtanen -//- http://www.students.tut.fi/~virtanea -//- 050-4004278

"Aivan samoin jos kirjastosta jatkuvasti varastettaisiin kirjoja, niin
varmaan jonkinlainen muutos tulisi kirjastolaitokseen. T?ss? tapahtuu nyt
todella niin, ett? varkaiden kautta rehellinen kuluttaja joutuu kiusalliseen
tilanteeseen, kun t?t? lakia on muutettu.
Irina Krohn selitt?? eduskunnassa tekij?noikeuslakia 29.9.2005


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Gabriel Dos Reis on
"kanze" <kanze(a)gabi-soft.fr> writes:

| Gabriel Dos Reis wrote:
| > rpbg123(a)yahoo.com (Roland Pibinger) writes:
|
| > | On 30 Sep 2005 21:59:51 -0400, "kanze" <kanze(a)gabi-soft.fr> wrote:
|
| > | >The whole point of static type checking is that the
| > | >compiler detects errors, rather than the run-time library.
| > | >For run-time genericity, the requirement of a common base
| > | >type (or something similar) is essential for static type
| > | >checking.
|
| > | Actually there is no 'type checking' involved with templates.
|
| > I guess it depends on your definition of "type checking".
|
| Actually, I don't think that there is any definition for which
| one could say that there is NO type checking. If I declare:
|
| template < typename T > class X {} ;
|
| and try to instantiation "X< 3 >", the compiler is going to
| complain that the template parameter is of the wrong type -- it
| is an int, where a typename is required.

Indeed. The point I was indirectly tryin to make is that some people
confusingly think that *late* type checking (as in the case of LISP, for
example) means no type checking, and *early* checking (as in the case of
Pascal, for example) as presence of type checking. There are
quite modern elaborated type systems out there, intersection types to
name a representative, where you basically have to run the codes to
see whether it is typeable or not.

[...]

| The only real problem, of course, is that the compiler error
| messages refer to the code generated by the meta-program, which
| doesn't necessarily make them particularly easy to understand.

Your understanding is correct.

--
Gabriel Dos Reis
gdr(a)integrable-solutions.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: dave_abrahams on

Joel Eidsath wrote:
> Dave Abrahams wrote:
> >Covariant argument types (the kind you need in order
> >to do int + int and complex + complex with the same '+' operation --
> >or swap, for that matter) can't be implemented using traditional OO
> >without compromising static type safety. Among other things.
>
> That surprises me to find out. I haven't really used any fully OO
> languages beyond tinkering. I didn't realize things were quite that
> bad.

It's not that they're bad; static and dynamic polymorphism have
different roles and different strengths.

>
> >> Stroustrup's and Dos Reis' paper for the standard committee is
> >> available here:
> >> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1782.pdf
> >
> >I hope you're aware that there's a competing concepts proposal:
> >http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1849.pdf
>
> I wasn't aware of it. I've been making my way through the proposals,
> but in a fairly haphazard manner.
>
> To be honest, the reason I posted what I thought of the Stroustrup
> paper was because I haven't been able to find much good discussion of
> the details of concepts, despite how important they are.

You're right. And very few people, even among those who know the STL,
seem to understand concepts, despite their fundamental nature. As far
as I can tell, there are no books on the discipline of generic
programming (I have great respect for Austern, but his book is mostly
about the STL and only marginally about GP). Fortunately I think I
know some experts who are working on one :).

> >> Concepts allow two sorts of errors to be picked up by the compiler:
> >> 1) Concept violations in the arguments passed to a template at point
> >> of call.
> >> 2) Concept violations inside the template itself.
> >>
> >> I am somewhat wary about this. Catching 1 should be the main
> >> justification of concepts. In effect, it is the template designer
> >> saying to the user of the template "your types must possess these
> >> properties, or they won't work as template arguments." Catching 2,
> >> however, is saying "so long as your types possess these properties,
> >> they will work as template arguments." The problem with 2 is that it
> >> won't always be true.
> >
> >What do you mean?
>
> You specify Assignable<T, U> to keep the user of a template from doing
> something stupid like passing your template a U that can't be assigned
> to T. This would be a violation of 1.
>
> A violation of 2 would be where you try to write T = U in your template
> code, but can't because you haven't specified Assignable<T,U>.

Yes.

> I think
> that enforcing 2 may fool some people into thinking that all concept
> templates are truly generic.

We're back to square 1. What do you mean? Give some examples, please.

> More importantly, because of 2, I can't
> make existing template code more safe for code users by just adding a
> single concept to stop the user from doing something stupid. I have to
> add every concept that the template code uses.

Why is that bad?

> >> Section 3 describes how to create concepts. I dislike that there are
> >> no provisions for negative concepts. For example, I might like to have
> >> something like "Not_Assignable" for use in creating slow careful
> >> algorithms rather than the fast awesome algorithms I might create with
> >> "Assignable".
> >
> >You don't need that. If you create two overloads, only one of which
> >requires Assignable, it will be chosen in preference to the other
> >one. You can put the slow implementation in the overload that doesn't
> >require Assignable.
>
> I realize that it can be done, it just won't be quite as clear or
> pretty.

I guess that's in the eye of the beholder. To me it seems very clean,
and it mirrors existing ideas in C++. When you overload a function on
a base and a derived class, you don't write "not derived" on the base
class overload, except maybe in a comment.

> And it can get uglier. Say I have a property Is_Inherited_From_ClassX.
> (This is what I was getting at with the dynamic_cast stuff. It looks
> like a useful property to me, I'll be able to specify it somehow,
> right?) I have a couple of other properties R and S. I have
> algorithms for 1) R&&~Is_Inherited_From_ClassX, 2)
> S&&~Is_Inherited_From_ClassX, 3) R&&S&&~Is_Inherited_From_ClassX, 4)
> Is_Inherited_From_ClassX.
>
> But because I can't specify ~Is_Inherited_From_ClassX, I have to write
> 7 algorithms instead:
> 1)R
> 2)S
> 3)Is_Inherited_From_ClassX
> 4)R&&S
> 5)R&&Is_Inherited_From_ClassX
> 6)S&&Is_Inherited_From_ClassX
> 7)R&&S&&Is_Inherited_From_ClassX

For years the Indiana concepts guys have had essentially this exact toy
example as a "pathological bad case" that they might have to deal with,
but in all their very extensive generic programming experience, no real
use case with the same characteristics has come up. So there's little
evidence that it's an important example.

That said, you can always use enable_if to do this
(http://www.boost.org/libs/utility/enable_if.html). Yes, concepts are
supposed to make most uses of enable_if obsolete, but it's nice to know
you have this escape hatch where you need it.

> Yeah, some of those will be copy and pastes, but there are more
> required as more properties get involved. It boosts compilation time,
> and so on and so forth. So not having '~' is less clear, potentially
> requires more work, and may slow compilation. What are the reasons put
> forward against having it?

If I understand correctly, the Stroustrup & Dos Reis (Texas) proposal
does support something like that. Isn't that what static_assert(! ...
) does?

> >> Another feature that is missing is some sort of user concept
> >> specification.
> >
> >I don't know what that means.
>
> Say I want to write some template code for classes with a binary
> function. I'd like to specify a concept
> "this_binary_function_never_returns_zero."
> For any class to be used by
> the template, the class designer would specifically have to associate
> "this_binary_function_never_returns_zero" with the class somehow. The
> class author might subvert it by lying, but I still think that you
> would avoid errors and create more maintainable code with that option.
> To do this now, I'd use traits.

You can do that with concepts. Using the Indiana concepts proposal,
you'd just write an empty set of requirements in your
this_binary_function_never_returns_zero concept. Because concept
conformance is determined by explicit model declarations by default,
that's all you need to do.

In the Texas proposal they match concepts implicitly by default, so you
have to write a blanket negative static assertion that says "nothing
conforms." Then that can be overridden by explicit assertions about
specific function types.

> >What you're referring to sounds a lot more like it should be called
> >"runtime semantic guarantees" than "user concept specification."
>
> Yes, that sounds like a much better term.

There is a proposal to introduce (runtime) contract programming to the
language. Its authors are talking with the authors of the concepts
proposals about how to unify them.

> >> Hopefully everyone learned about induction proofs in high school. For
> >> induction to work, you need to prove that "P true for x" implies "P
> >> true for x + 1" and also a specific instance of P. (Usually P of 1 or
> >> 0.) I see concepts as equivalent to the first general condition of
> >> induction, but not the second. It would be nice to have some
> >> constraints on class T initialized with 0, for instance.
> >
> > Again, these are runtime semantic guarantees.
> >
> >> Sometimes this will be possible to know at compile-time, sometimes
> >> not.
> >
> >How could it ever be known at compile time?
>
> If a class constructor doesn't make any function calls, then the
> compiler could theoretically know a lot about C(0) for some class C.

Generally, the things you can know at compile time are limited to
information in declarations, since, e.g., the constructor could be
implemented in a separate translation unit. I don't think the language
should go to heroic lengths to implement something like this if it's
only going to work in the few cases where it isn't.

cheers,
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: kanze on
Andrei Alexandrescu (See Website for Email) wrote:
> James Kanze wrote:
> > But I've also used <generic.h>, in pre-template days, and
> > I've used the Java Collections (which IMHO are globally
> > better designed than the STL).

> In case you planted that as a hook to have people ask you
> details about that or your experience in the battlefield, feel
> free to :o). "James, why are the Java Collections globally
> better designed than the STL?" Have at it.

Because they don't require two iterators to do the job. So you
can feed the results of one function directly to the next
function. And writing non-mutating filtering iterators is
trivial.

And because iterators iterate, and nothing else -- where in C++
you need a random access iterator, in Java, you use a collection
(which can be a view). Which makes it a lot easier to see what
is going on -- if you pass an iterator to a function which
requires a collection, you get a very clear error message,
whereas when you pass a bidirectional iterator to an algorithm
which requires a random access iterator... well, you do
generally get an error message, but I'm not sure that clear
would be an appropriate word to describe it.

I also have a couple of cases where it has been very useful for
iterators to be dynamically polymorphic -- where I had only a
single function (far too complicated to ever put in a header,
and thus not a candidate for templates with current C++
implementations) which was called at different times with
different types of iterators -- over an std::string, or directly
from input, for example. (As luck would have it, I never needed
this in Java, where it is naturally present, but I've needed it
several times in C++. For a long time, I just used C++'s
"other" iterator: std::basic_streambuf. I've heard rumors,
however, that not everyone is as fond of iostreams as I am:-).)

They do weaken the argument by combining incrementation and
access in a single function; this is a definite mistake, and
makes it very difficult to write mutating filtering iterators.
On the other hand, most of the time I've wanted to mutate, I've
been able to make do with a view of the collection, rather than
iterators. And of course, the lack of type safety could hardly
be called a feature; I did have one or two cases where it was
convenient, but in each case, a collection of a discriminant
union (missing in both languages) would have been an even better
solution.

--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: C++/CLI limitations?
Next: SHA1