Mike Mintz wrote: > Hi Gord, Mark, and the team, > > I am getting confused as to what the proposals are. Gord, can I trouble > you to summarize the proposals, going as complex as templated external > member functions ? I'd also love to see the instantiating and calling > syntax. I may have missed it, but did we consider the derivation from a > templated base class? > > I realize this is a lot to ask, but maybe the latest two or three > proposals? No problem. I have a summary of the options below after which I address your derivation question (very interesting here!) and have added a summary of some of the main arguments. I've spent way too much time on this already so I'm going to try to stay out of any further rehash of the same issues. Syntax Summary: =============== Since most of the proposals haven't been boiled down to rules yet, I'll do this by example with my original toy example. class C #(type T = int); extern function T get(); endclass I think that the set of suggestions is now: 1) C::function T get(); 2) function::C T get(); 3) function #(type T = int) T C::get(); 4) function #(type T) T C::get(); (these were the 4 I originally raised) 5) function #(T) T C::get(); Arturo asked whether "type" is required in (4) and suggested that (5) might be Ok. 6) function C::T C::get(); Mark's suggestion. Derivation and externs ====================== Mike, your question about derivation is very insightful. I think there were some assumptions in what I've stated that aren't quite correct in such scenarios. Using the smallest modification of my earlier example: class C #(type T = int); endclass class D extends C#(); extern function T get(); endclass For (6), I'm not sure whether I'd need to have: function C::T D::get(); or function D::T D::get(); Perhaps either would be Ok. Certainly the name relationship could end up being a bit less obvious. For (3)-(5), I think that you would need to list all the parameter names in use: function #(type T) T D::get(); So my assumption that you would just copy/paste the parameters from the class in which the method is defined is clearly incorrect. I suspect that the rule would have to be that for each parameter listed in the #(...) list, that name would have to match the "kind" (i.e. type or value) of a parameter in the derivation hierarchy. That is a more general rule than what I had in mind. I don't think there are any issues there, just a bit more complexity in the rule set. For (1) and (2) there is no issue at all. For (1) you would simply have: D::function T get(); since the entire parse would be treated as occurring in the context of D and would have implicit visibility of the inherited parameters. <grin> Obviously I like that result!! Pro/Con summary: ================ I hope that all of my characterizations of the arguments are fair; I certainly apologize if not. I've not included any comments about the derivation case Mike raised since others haven't had time to respond on that. Most of the discussion has revolved around three questions -- a) stylistic preference b) regularity of semantics/syntax c) possibly ambiguities Here are my comments on each question (in reverse order). In the general case, one needs to know whether a name denotes a type or not in order to parse SV. I am not sure whether the function return type context is sufficiently bounded to be able to relax that requirement. If it is contextually bounded so that you can parse without that knowledge, then we can just discard consideration (c). (5) obviously requires there to be no ambiguity. (6) is a bit troubling since I am not sure whether one would in all cases be able to express general types (including "type" operators, etc) while unambiguously retaining all knowledge and without incorrect interactions with the surrounding context. Since you have to parse the return type without knowledge of whether the type is for the extern case, I am just a bit uncomfortable with whether we're leaving anything open. We might not be in which case (c) would not be of concern for (6). I am sure that (c) is not of concern for (1)-(4) since you have full knowledge of what kind of handling you need to follow for each special name. For question (b), the only form that I really don't like is (6). The problem is that with (6) C::T implies a type in a default specialization in all type contexts *except* this one. People are already surprised by default specializations enough that I am pretty opposed to any special cases in this area. Mark's objection to (3), (4), and (5) is that those forms look too much like a parameterized function. I agree that they do and raised the weird (future concern) case of parameterized functions within parameterized classes to make sure that everyone was aware of how obscure the syntax can get. However, in deference to the C++ symmetries, I'm willing to accept such a form. I still think that (1) is the cleanest since, as Jonathan noted, it is clear that you are simply shifting your parse context to be in the parameterized class context and then proceeding to deal with the function. Opposing (1), Mike raised the "distance" issue with respect to where the parameter names were declared versus used, i.e. that it is more obvious in forms (3)-(5) that the names are type/value parameters since they appear with the function declaration. On (a), I'm not going to attempt to even summarize. That gets too close to a religious war.... For myself, I generally do not like required redundancy. So I am quite biased against (3)-(5). Since I've voiced objections to (6) above, that leaves me essentially where I started: I prefer (1) or (2), would accept (4) or (3), am concerned enough about (5) that I would likely object, and would oppose (6). Gord. -- -------------------------------------------------------------------- Gordon Vreugdenhil 503-685-0808 Model Technology (Mentor Graphics) gordonv@model.com -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.Received on Thu Jun 21 08:04:13 2007
This archive was generated by hypermail 2.1.8 : Thu Jun 21 2007 - 08:04:46 PDT