Prev: C++/CLI limitations?
Next: SHA1
From: Joel Eidsath on 1 Oct 2005 12:04 Dave Abrahams wrote: >> But there is not much functional difference between templates, as >> implemented now, and functions in more OO languages that work on the >> base object for all types. > >Yes, there is. 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. >> 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. So I thought I'd drum some up. I also hoped to provoke some posters into curing my various points of ignorance. So thanks for the link, I'll be reading it right away. >> 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>. I think that enforcing 2 may fool some people into thinking that all concept templates are truly generic. 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. >I hope you're aware that the competing concepts proposal supports >that, and it has been implemented: >http://www.osl.iu.edu/~dgregor/ConceptGCC/ > >You can download that compiler and use it today. Again, thanks. >> 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. 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 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? >> 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. >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 another thing missing from concepts that limit their utility. >> I don't see how to implement it, however: > >> 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. It may know one or two things about a sufficiently simple empty container. I can't imagine an easy way for compiler writers to implement this sort of thing, but maybe there are smarter people than me on this newsgroup who can. That's why I threw it out. Joel Eidsath [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Roland Pibinger on 1 Oct 2005 21:33 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. 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. Best regards, Roland Pibinger [ 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 2 Oct 2005 12:20 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". -- 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: James Kanze on 2 Oct 2005 16:17 Roland Pibinger wrote: > 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. 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. In this regard, the important point is, of course, that C++ templates are a meta-language; the compiler doesn't "compile" the template itself, it compiles instantiations of the template. 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. 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. 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. -- James Kanze mailto: james.kanze(a)free.fr Conseils en informatique orient?e objet/ Beratung in objektorientierter Datenverarbeitung 9 pl. Pierre 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! ]
From: kanze on 3 Oct 2005 09:23
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. The way I "interpret" templates is that they are a meta-language, with dynamic type checking. The meta-program gets "executed" at compile time, with the results that the "dynamic type checking" of the meta-program occurs at compile time. And of course, the meta-program generates "program" (the instantiations), which is type checked exactly like any other C++ code. 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. (I'm exagerating a little, of course, when I say "the only real problem". The interactions between the meta-program and the rest aren't always that simple either -- implicit instantiation with template type deduction and function overload resolution come to mind.) -- 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! ] |