Prev: C++/CLI limitations?
Next: SHA1
From: Andrei Alexandrescu (See Website for Email) on 3 Oct 2005 09:21 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 3 Oct 2005 16:58 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 3 Oct 2005 17:14 "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 4 Oct 2005 09:47 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 4 Oct 2005 10:12
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! ] |