* "Must instantiate controlled types at library level." Why? @ 2004-05-11 23:04 Peter C. Chapin 2004-05-12 1:03 ` Jeffrey Carter 0 siblings, 1 reply; 59+ messages in thread From: Peter C. Chapin @ 2004-05-11 23:04 UTC (permalink / raw) Hello! I have a generic package that contains a controlled type. When I attempt to instantiate that package in the declarative part of a procedure, GNAT (v3.15p) tells me that I must instantiate controlled types at "library level" (or something like that). I worked around this by creating a helper package in which I did the instantiation and then used that helper package in my procedure. However, this experience leads me to wonder why there is this restriction on controlled types. I'm relatively new to Ada so I apologize if this seems like a basic question. Thanks in advance! Peter ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-11 23:04 "Must instantiate controlled types at library level." Why? Peter C. Chapin @ 2004-05-12 1:03 ` Jeffrey Carter 2004-05-12 10:47 ` Peter C. Chapin 0 siblings, 1 reply; 59+ messages in thread From: Jeffrey Carter @ 2004-05-12 1:03 UTC (permalink / raw) Peter C. Chapin wrote: > I have a generic package that contains a controlled type. When I attempt to > instantiate that package in the declarative part of a procedure, GNAT > (v3.15p) tells me that I must instantiate controlled types at "library > level" (or something like that). I worked around this by creating a helper > package in which I did the instantiation and then used that helper package in > my procedure. However, this experience leads me to wonder why there is this > restriction on controlled types. That's the correct way to create a controlled type. I know it's difficult to see why this is needed, but it's a feature of all tagged types, not just controlled types. Any tagged type declared at library level must be extended at library level. The declarative part of a subprogram, including a library level subprogram, is never at library level. The problem is that a value of an extended type can be stored in a variable at a higher nesting level. This could result in dispatching to an operation that no longer exists and referencing variables that no longer exist. This is easier to demonstrate than describe: package Library_Level is type Taggy is tagged null record; procedure Op (T : in out Taggy); type Taggy_Ptr is access all Taggy'Class; Ptr : Taggy_Ptr; end Library_Level; with Library_Level; procedure Outer is procedure Inner is type Taggy_Ext is new Library_Level.Taggy with null record; -- Illegal type extension procedure Op (T : in out Taggy_Ext); I : Integer := 7; procedure Op (T : in out Taggy_Ext) is begin -- Op I := I + 1; end Op; V : Taggy_Ext; begin -- Inner Library_Level.Ptr := new Library_Level.Taggy'Class'(V); end Inner; begin -- Outer Inner; Library_Level.Op (T => Library_Level.Ptr.all); end Outer; The call to Library_Level.Op would attempt to dispatch to Outer.Inner.Op, which is out of scope. The references to I in Outer.Inner.Op refer to a variable that no longer exists. -- Jeff Carter "Blessed is just about anyone with a vested interest in the status quo." Monty Python's Life of Brian 73 ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-12 1:03 ` Jeffrey Carter @ 2004-05-12 10:47 ` Peter C. Chapin 2004-05-12 11:25 ` Ludovic Brenta 2004-05-12 11:55 ` Martin Krischik 0 siblings, 2 replies; 59+ messages in thread From: Peter C. Chapin @ 2004-05-12 10:47 UTC (permalink / raw) Jeffrey Carter <spam@spam.com> wrote in news:NJeoc.16758$V97.5496 @newsread1.news.pas.earthlink.net: > The call to Library_Level.Op would attempt to dispatch to > Outer.Inner.Op, which is out of scope. The references to I in > Outer.Inner.Op refer to a variable that no longer exists. Thank you for your detailed post. It was very helpful. I haven't yet gotten around to studying Ada's object oriented features in detail but I can see that the issue is related to the fact that Ada allows procedures to be defined inside other procedures. Just for fun I attached an equivalent C++ program below. Interestingly, it seems to compile and work using three different C++ compilers. I wonder its behavior is technically "undefined". It seems like it probably should be. Perhaps I'll ask on the C++ group. Peter -----> cut <----- #include <iostream> class X { public: virtual void f(); }; void X::f() { std::cout << "I'm in X::f\n"; } X *ptr; void helper() { class Y : public X { public: virtual void f() { std::cout << "I'm in Y::f\n"; } }; ptr = new Y; } int main() { helper(); ptr->f(); return 0; } ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-12 10:47 ` Peter C. Chapin @ 2004-05-12 11:25 ` Ludovic Brenta 2004-05-12 14:41 ` Martin Krischik 2004-05-13 2:20 ` Peter C. Chapin 2004-05-12 11:55 ` Martin Krischik 1 sibling, 2 replies; 59+ messages in thread From: Ludovic Brenta @ 2004-05-12 11:25 UTC (permalink / raw) Peter, what do you mean when you say your C++ program "works"? Does it print "I'm in X::f" or "I'm in Y::f"? And what were you expecting? Personally I have a hard time deciding what I should expect. Perhaps my mind has been tainted by Ada by now :) -- Ludovic Brenta. -- Use our news server 'news.foorum.com' from anywhere. More details at: http://nnrpinfo.go.foorum.com/ ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-12 11:25 ` Ludovic Brenta @ 2004-05-12 14:41 ` Martin Krischik 2004-05-13 2:20 ` Peter C. Chapin 1 sibling, 0 replies; 59+ messages in thread From: Martin Krischik @ 2004-05-12 14:41 UTC (permalink / raw) Ludovic Brenta wrote: > > Peter, what do you mean when you say your C++ program "works"? Does it > print "I'm in X::f" or "I'm in Y::f"? And what were you expecting? > Personally I have a hard time deciding what I should expect. Perhaps > my mind has been tainted by Ada by now :) He did not use any stack memory so it should work. It's of corse C++ thinking since most C++ programmers don't understand the language. In my last assignment I was the only one of about 50 C++ programmers who ever read the ISO standart on C++. One team was using multiple inheritence left right and centre never know about diamont inheritance and its side effect. When the switch from IBM C++ to MS C++ was made there programm crashed - sporadicly - left right and centre. Until I told them about virtual inheritance. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-12 11:25 ` Ludovic Brenta 2004-05-12 14:41 ` Martin Krischik @ 2004-05-13 2:20 ` Peter C. Chapin 1 sibling, 0 replies; 59+ messages in thread From: Peter C. Chapin @ 2004-05-13 2:20 UTC (permalink / raw) Ludovic Brenta <ludovic.brenta@insalien.org> wrote in news:2004512-132548- 992437@foorum.com: > Peter, what do you mean when you say your C++ program "works"? Does it > print "I'm in X::f" or "I'm in Y::f"? It "works" in the sense that Y::f was called despite the fact that conceptually Y::f no longer exists. What it doesn't do is produce a compile time error because I created a local class that was derived from a global class. If I understand the earlier post this is the essence of what GNAT was worried about when it complained that I couldn't instantiate a controlled type except at library level. As I said, my earlier program probably invokes undefined behavior. I would be surprised if Standard C++ mandated any kind of sensible response in a case like this. Peter ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-12 10:47 ` Peter C. Chapin 2004-05-12 11:25 ` Ludovic Brenta @ 2004-05-12 11:55 ` Martin Krischik 2004-05-13 2:59 ` Peter C. Chapin 1 sibling, 1 reply; 59+ messages in thread From: Martin Krischik @ 2004-05-12 11:55 UTC (permalink / raw) Peter C. Chapin wrote: > Jeffrey Carter <spam@spam.com> wrote in news:NJeoc.16758$V97.5496 > @newsread1.news.pas.earthlink.net: > >> The call to Library_Level.Op would attempt to dispatch to >> Outer.Inner.Op, which is out of scope. The references to I in >> Outer.Inner.Op refer to a variable that no longer exists. > > Thank you for your detailed post. It was very helpful. I haven't yet > gotten around to studying Ada's object oriented features in detail but I > can see that the issue is related to the fact that Ada allows procedures > to be defined inside other procedures. > > Just for fun I attached an equivalent C++ program below. Interestingly, it > seems to compile and work using three different C++ compilers. I wonder > its behavior is technically "undefined". It seems like it probably should > be. Perhaps I'll ask on the C++ group. It is not quite complete: > -----> cut <----- > #include <iostream> > > class X { > public: > virtual void f(); > }; > > void X::f() > { > std::cout << "I'm in X::f\n"; > } > > X *ptr; > > void helper() > { auto int Z := 5; > class Y : public X { > public: > virtual void f() { > std::cout << "I'm in Y::f\n"; std::cout << "and Z is " << Z << std:endl; > } > }; > > ptr = new Y; > } > > int main() > { > helper(); > ptr->f(); > return 0; > } But you can reduce the probem to a 5 liner: int& Very_Silly () { auto int Short_Lived = 5; return Short_Lived; } A good compiler will warn you. But it does compile. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-12 11:55 ` Martin Krischik @ 2004-05-13 2:59 ` Peter C. Chapin 2004-05-13 7:10 ` Martin Krischik 0 siblings, 1 reply; 59+ messages in thread From: Peter C. Chapin @ 2004-05-13 2:59 UTC (permalink / raw) Martin Krischik <krischik@users.sourceforge.net> wrote in news:13392802.3gDeTK7ybb@linux1.krischik.com: > It is not quite complete: > >> -----> cut <----- >> #include <iostream> >> >> class X { >> public: >> virtual void f(); >> }; >> >> void X::f() >> { >> std::cout << "I'm in X::f\n"; >> } >> >> X *ptr; >> >> void helper() >> { > > auto int Z := 5; > >> class Y : public X { >> public: >> virtual void f() { >> std::cout << "I'm in Y::f\n"; > > std::cout << "and Z is " << Z << std:endl; > >> } >> }; >> >> ptr = new Y; >> } >> >> int main() >> { >> helper(); >> ptr->f(); >> return 0; >> } Actually I tried this modification. In fact, the three C++ compilers I used *do* produce a compile time error on this code. In particular the use of an auto variable in the member function of a local class is specifically illegal. The relevant language from the C++ standard is in section section 9.8, paragraph 1: "Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope." The standard then goes on to give an example showing that the use of an auto variable is illegal. So it appears that contrary to my earlier assumption, C++ does in fact try to do something sensible with this construction. Peter ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-13 2:59 ` Peter C. Chapin @ 2004-05-13 7:10 ` Martin Krischik 2004-05-13 10:36 ` Peter C. Chapin 0 siblings, 1 reply; 59+ messages in thread From: Martin Krischik @ 2004-05-13 7:10 UTC (permalink / raw) Peter C. Chapin wrote: > Martin Krischik <krischik@users.sourceforge.net> wrote in > news:13392802.3gDeTK7ybb@linux1.krischik.com: > Actually I tried this modification. In fact, the three C++ compilers I > used *do* produce a compile time error on this code. In particular the use > of an auto variable in the member function of a local class is > specifically illegal. The relevant language from the C++ standard is in > section section 9.8, paragraph 1: "Declarations in a local class can use > only type names, static variables, extern variables and functions, and > enumerators from the enclosing scope." The standard then goes on to give > an example showing that the use of an auto variable is illegal. Well, here you have a good example of the difference of Ada and C++. Ada has a complete ban on the construct while C++ goes out and about to ban only the tricky part. Off course the C++ ISO standart is 200 pages longer the Ada Standart. And that's without tasking, without protected types, without indefinite types and with a need for clone() functions. Just in case you did not know: P is tagged .... P_Class is access P; C is new P .... A_C : C := ... A_P : P'Class := P'Class (A_C); A_P_Ptr : P_CLass := new P'CLass'(A_C); A_P and A_P_Ptr will contain a copy of C. With Regards Martin PS: I hope you don't mind my other post to much. You do dig deeper and you do know the ISO standart so my rant about the average C++ programmer does not apply to you. -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-13 7:10 ` Martin Krischik @ 2004-05-13 10:36 ` Peter C. Chapin 2004-05-13 11:18 ` Martin Krischik 2004-05-13 19:33 ` Randy Brukardt 0 siblings, 2 replies; 59+ messages in thread From: Peter C. Chapin @ 2004-05-13 10:36 UTC (permalink / raw) Martin Krischik <krischik@users.sourceforge.net> wrote in news:2780491.NPbR8AFya6@linux1.krischik.com: > Well, here you have a good example of the difference of Ada and C++. Ada > has a complete ban on the construct while C++ goes out and about to ban > only the tricky part. It's interesting to reflect on these different approaches. C++ can get away with imposing such restrictions on nested functions because nested functions are rarely used in C++. In Ada similar restrictions on nested procedures would be entirely unacceptable. Consequently Ada imposes restrictions in a different place in order to avoid the same fundamental problem. > Just in case you did not know: > > P is tagged .... > P_Class is access P; > C is new P .... > > A_C : C := ... > A_P : P'Class := P'Class (A_C); > A_P_Ptr : P_CLass := new P'CLass'(A_C); > > A_P and A_P_Ptr will contain a copy of C. Interesting. I don't completely follow the code above because I haven't gotten to this material yet in my study. In the statement A_P : P'Class := P'Class(A_C); Is A_C "sliced" into a P (to use a bit of C++ terminology)? I'm not certain what declaring A_P as type P'Class is doing for me. > PS: I hope you don't mind my other post to much. You do dig deeper and > you do know the ISO standard so my rant about the average C++ programmer > does not apply to you. No offense taken. Certainly C++ is a rather twisted language, especially syntactically. I'm enjoying Ada because it seems much cleaner while still being very powerful and expressive. Peter ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-13 10:36 ` Peter C. Chapin @ 2004-05-13 11:18 ` Martin Krischik 2004-05-13 22:27 ` Peter C. Chapin 2004-05-13 22:54 ` Freejack 2004-05-13 19:33 ` Randy Brukardt 1 sibling, 2 replies; 59+ messages in thread From: Martin Krischik @ 2004-05-13 11:18 UTC (permalink / raw) Peter C. Chapin wrote: > Martin <krischik@users.sourceforge.net> wrote in > news:2780491.NPbR8AFya6@linux1.krischik.com: > A_P : P'Class := P'Class(A_C); > > Is A_C "sliced" into a P (to use a bit of C++ terminology)? I'm not > certain what declaring A_P as type P'Class is doing for me. If you think of slice as something being cut away then: No! P is an definite type. For any definite type the size is know at compile time. For any tagged type a 'Class type exists. 'Class are indefinite types (like String). For any indefinite type the size is may or may not be known at compile time and if needed is calculated (by compiler magic) at run time. The trick is that a 'Class type can contain any type from the class hirachie it is part of. Thats why they are called class wide. The compiler will calculate the size of C at and make enough space on the stack so that C can be copied into P'Class. I almost never use pointers in Ada since I can pass 'Class types around as I like. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-13 11:18 ` Martin Krischik @ 2004-05-13 22:27 ` Peter C. Chapin 2004-05-13 22:54 ` Freejack 1 sibling, 0 replies; 59+ messages in thread From: Peter C. Chapin @ 2004-05-13 22:27 UTC (permalink / raw) Martin Krischik <krischik@users.sourceforge.net> wrote in news:11924003.IfRfnULeIG@linux1.krischik.com: > I almost never use pointers in Ada since I can pass 'Class types around > as I like. Sounds pretty neat. I'll have to check it out more. Peter ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-13 11:18 ` Martin Krischik 2004-05-13 22:27 ` Peter C. Chapin @ 2004-05-13 22:54 ` Freejack 2004-05-14 7:13 ` Martin Krischik 1 sibling, 1 reply; 59+ messages in thread From: Freejack @ 2004-05-13 22:54 UTC (permalink / raw) On Thu, 13 May 2004 13:18:11 +0200, Martin Krischik wrote: > I almost never use pointers in Ada since I can pass 'Class types around as I > like. > Huh? > Martin Alright. I'm not a guru by any stretch of the imagination. But I do get around Ada code quite proficiently. This idea of substituting Classes for pointers is a bit fuzzy to me. I mean, a pointer is an address. Maybe I don't understand Ada Classes as well as I thought. Classes are addresses too? Could you elaborate? Freejack ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-13 22:54 ` Freejack @ 2004-05-14 7:13 ` Martin Krischik 2004-05-14 13:50 ` Xenos 0 siblings, 1 reply; 59+ messages in thread From: Martin Krischik @ 2004-05-14 7:13 UTC (permalink / raw) Freejack wrote: > On Thu, 13 May 2004 13:18:11 +0200, Martin Krischik wrote: > >> I almost never use pointers in Ada since I can pass 'Class types around >> as I like. >> > Huh? > >> Martin > > Alright. I'm not a guru by any stretch of the imagination. But I do get > around Ada code quite proficiently. This idea of substituting Classes for > pointers is a bit fuzzy to me. I mean, a pointer is an address. Maybe I > don't understand Ada Classes as well as I thought. Simple Mantra: 'Class behaves like String. If you compare with C/C++: You always have to uses char* pointers since C/C++ has no equivalent for String. In C an array is either definite "int X[10]" or you use pointer. "int X[]" is only another syntax for "char*" since there is no 'First and 'Last in C/C++. Ada however has indefinite types - so pointers arn't neede here. Also you use pointers because C/C++ has no "out" or "in out". Ada however decides itself if call by value or call by reference is needed. So no pointers needed here as well. Back to the mantra: You can't say: S : String; C : Tagged_Type'Class; type S_Array is array (Natural range <>) of String; type C_Array is array (Natural range <>) of Tagged_Type'Class; But you can say: S : String := "Hello!"; C2 : Tagged_Type'Class := C1; procedure Do_S (Some_S : in out String); procedure Do_C (Some_C : in out Tagged_Type'Class); > Classes are addresses > too? No, like Strings they use memory. Actualy in the example above C2 might even allocate more memory then C1 since C2 as an indefinite type need to keep track of its size. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 7:13 ` Martin Krischik @ 2004-05-14 13:50 ` Xenos 2004-05-14 17:27 ` Georg Bauhaus ` (2 more replies) 0 siblings, 3 replies; 59+ messages in thread From: Xenos @ 2004-05-14 13:50 UTC (permalink / raw) "Martin Krischik" <krischik@users.sourceforge.net> wrote in message news:1676457.GMYvKY1ieA@linux1.krischik.com... > Freejack wrote: > Simple Mantra: 'Class behaves like String. > > If you compare with C/C++: You always have to uses char* pointers since > C/C++ has no equivalent for String. Wrong. C++ has a string class in its standard library. Its a lot more versitile than Ada's String type. > > In C an array is either definite "int X[10]" or you use pointer. "int X[]" > is only another syntax for "char*" since there is no 'First and 'Last in > C/C++. Ada however has indefinite types - so pointers arn't neede here. > Wrong. In certain situations, an array will "degrade" to a pointer to its element type. As a function parameter int X[] will degrade to a constant pointer to an integer, or int * const. It is NEVER eqvilent to char*. You must be thinking of Classic C (before the standard) were a char* was used at the generic pointer type before void* was introduced. A generic pointer will accept any type of (non-function) pointer, but is still not equivilent to it. It is only during degradation that an array end is unknown to the compiler. C++ has the vector (et. al.) where .begin() and .end() are equivalent to 'First and 'Last. > Also you use pointers because C/C++ has no "out" or "in out". Ada however > decides itself if call by value or call by reference is needed. So no > pointers needed here as well. Wrong. C++ has reference types are equivalent to "in out." Constant reference types may be used for "in." If you don't understand a language, you don't have any grounds to lambaste it. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 13:50 ` Xenos @ 2004-05-14 17:27 ` Georg Bauhaus 2004-05-14 17:58 ` Xenos 2004-05-14 18:49 ` Martin Krischik 2004-05-15 17:20 ` Pascal Obry 2 siblings, 1 reply; 59+ messages in thread From: Georg Bauhaus @ 2004-05-14 17:27 UTC (permalink / raw) Xenos <dont.spam.me@spamhate.com> wrote: : : Wrong. C++ has a string class in its standard library. Its a lot more : versitile than Ada's String type. It would be more fair I think if you compared Standard.Strings.Unbounded to std::string C++ minus the STL, if I may put it this way, has no Ada-like or STL-like arrays after all. (But it does have an STL.) :> Also you use pointers because C/C++ has no "out" or "in out". Ada however :> decides itself if call by value or call by reference is needed. So no :> pointers needed here as well. : Wrong. C++ has reference types are equivalent to "in out." Constant : reference types may be used for "in." My understanding of Martin's comment is that you can have an Ada compiler decide whether it thinks that pass by reference is better, thus you only need to specify the mode, not the passing mechanism. Is there a similar allowance for C++ compilers? -- Georg ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 17:27 ` Georg Bauhaus @ 2004-05-14 17:58 ` Xenos 0 siblings, 0 replies; 59+ messages in thread From: Xenos @ 2004-05-14 17:58 UTC (permalink / raw) "Georg Bauhaus" <sb463ba@l1-hrz.uni-duisburg.de> wrote in message news:c82vhe$ecp$2@a1-hrz.uni-duisburg.de... > Xenos <dont.spam.me@spamhate.com> wrote: > : > : Wrong. C++ has a string class in its standard library. Its a lot more > : versitile than Ada's String type. > > It would be more fair I think if you compared > Standard.Strings.Unbounded > to > std::string > > C++ minus the STL, if I may put it this way, has no Ada-like or STL-like > arrays after all. (But it does have an STL.) I'll give you that one, though I don't think its fair to weigh a language without considering its library. The C++ philosophy (and I won't argue its correctness) is to put anything that can be in the library in there and not in the language. Though admittedly I was probably guilt of the same comparing std::string to String. > > > :> Also you use pointers because C/C++ has no "out" or "in out". Ada however > :> decides itself if call by value or call by reference is needed. So no > :> pointers needed here as well. > : Wrong. C++ has reference types are equivalent to "in out." Constant > : reference types may be used for "in." > > My understanding of Martin's comment is that you can have an Ada > compiler decide whether it thinks that pass by reference is better, > thus you only need to specify the mode, not the passing mechanism. > Is there a similar allowance for C++ compilers? The comment I argued against stated that in C++ you *had* to use pointers because the language *didn't* have anything like "in out" which is simply untrue. In C++, pointers are almost as unnecessary as they are in Ada. I won't argue whether it is better for the compiler to decide when to use pass by reference. > > > -- Georg ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 13:50 ` Xenos 2004-05-14 17:27 ` Georg Bauhaus @ 2004-05-14 18:49 ` Martin Krischik 2004-05-14 19:40 ` Xenos 2004-05-15 17:20 ` Pascal Obry 2 siblings, 1 reply; 59+ messages in thread From: Martin Krischik @ 2004-05-14 18:49 UTC (permalink / raw) Xenos wrote > "Martin Krischik" <krischik@users.sourceforge.net> wrote in message > news:1676457.GMYvKY1ieA@linux1.krischik.com... >> Freejack wrote: >> Simple Mantra: 'Class behaves like String. >> >> If you compare with C/C++: You always have to uses char* pointers since >> C/C++ has no equivalent for String. > Wrong. C++ has a string class in its standard library. Its a lot more > versitile than Ada's String type. We are comparing languages capabilities here not libraries. the C++ string class in not build into the language. >> In C an array is either definite "int X[10]" or you use pointer. "int >> X[]" is only another syntax for "char*" since there is no 'First and >> 'Last in C/C++. Ada however has indefinite types - so pointers arn't >> neede here. > Wrong. In certain situations, an array will "degrade" to a pointer to its > element type. As a function parameter int X[] will degrade to a constant > pointer to an integer, or int * const. It is NEVER eqvilent to char*. > You must be thinking of Classic C (before the standard) were a char* was > used at > the generic pointer type before void* was introduced. A generic pointer > will accept any type of (non-function) pointer, but is still not > equivilent to it. No, You are am mistaken. Try this: class X { f (int *const x); f (int x[]); } Practical value is what counts. > It is only during degradation that an array end is unknown to the > compiler. The array bounds become unknown. Well, you have proven my point. It is even worse: Sometimes "sizeof X" will be the size of the array sometimes it is just the size of an pointer. > C++ has the vector (et. al.) where .begin() and .end() are > equivalent to 'First and 'Last. Again: vector is library not language. >> Also you use pointers because C/C++ has no "out" or "in out". Ada however >> decides itself if call by value or call by reference is needed. So no >> pointers needed here as well. > Wrong. C++ has reference types are equivalent to "in out." Constant > reference types may be used for "in." References are just "*const" with automatic referencing / dereferencing. Syntactic sugar no new semantic. You can even do: Some_Class& X = *new Some_Class; delete &X; Does work. Did it hundreds of times. If you use reference as class members the compiler will stop creating copy constructors and warn you if you forget to assign data inside the constructor. > If you don't understand a language, you don't have any grounds to lambaste > it. Just for the record: I have 10 years+ experience in C/C++ programming. I know which bugs I have hunted. I know when the dam compiler turned my arrays into pointer when I did not want, did not need it. Thank you very much. And this is why I am here in this Ada group: I only program C/C++ when I get paid for it and not one line for my private needs. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 18:49 ` Martin Krischik @ 2004-05-14 19:40 ` Xenos 2004-05-14 22:47 ` Ludovic Brenta 0 siblings, 1 reply; 59+ messages in thread From: Xenos @ 2004-05-14 19:40 UTC (permalink / raw) "Martin Krischik" <krischik@users.sourceforge.net> wrote in message news:1616198.O4tUV8TdF7@linux1.krischik.com... > Xenos wrote > > > "Martin Krischik" <krischik@users.sourceforge.net> wrote in message > > news:1676457.GMYvKY1ieA@linux1.krischik.com... > >> Freejack wrote: > >> Simple Mantra: 'Class behaves like String. > >> > >> If you compare with C/C++: You always have to uses char* pointers since > >> C/C++ has no equivalent for String. > > > Wrong. C++ has a string class in its standard library. Its a lot more > > versitile than Ada's String type. > > We are comparing languages capabilities here not libraries. the C++ string > class in not build into the language. Yes, I conceded that when someone else commented. > > >> In C an array is either definite "int X[10]" or you use pointer. "int > >> X[]" is only another syntax for "char*" since there is no 'First and > >> 'Last in C/C++. Ada however has indefinite types - so pointers arn't > >> neede here. > > > Wrong. In certain situations, an array will "degrade" to a pointer to its > > element type. As a function parameter int X[] will degrade to a constant > > pointer to an integer, or int * const. It is NEVER eqvilent to char*. > > You must be thinking of Classic C (before the standard) were a char* was > > used at > > the generic pointer type before void* was introduced. A generic pointer > > will accept any type of (non-function) pointer, but is still not > > equivilent to it. > > No, You are am mistaken. Try this: > > class X > { > f (int *const x); > f (int x[]); > } > > Practical value is what counts. This just proves what I said above about degrading (or decaying if you prefer) pointers, and does not validate you saying that int X[] is the same as a char*. > > > It is only during degradation that an array end is unknown to the > > compiler. > > The array bounds become unknown. Well, you have proven my point. It is even > worse: Sometimes "sizeof X" will be the size of the array sometimes it is > just the size of an pointer. No, not sometimes. There are explicit rules for when this happen; it is not willy-nilly. If you say sizeof X, and X is an array type, you will ALWAYS get the size of the array. The function example won't get you out of this. Arrays in C/C++ are not first-class citizens and cannot be functions parmeters. Saying foo(int x[]) does not define x as an array type, so of course sizeof x will equal sizeof(int*). > > > C++ has the vector (et. al.) where .begin() and .end() are > > equivalent to 'First and 'Last. > > Again: vector is library not language. Again, I concede. > > >> Also you use pointers because C/C++ has no "out" or "in out". Ada however > >> decides itself if call by value or call by reference is needed. So no > >> pointers needed here as well. > > > Wrong. C++ has reference types are equivalent to "in out." Constant > > reference types may be used for "in." > > References are just "*const" with automatic referencing / dereferencing. > Syntactic sugar no new semantic. You can even do: > > Some_Class& X = *new Some_Class; > > delete &X; > This proves nothing other than you can create a pointer to an object and deference it. It also show that operators attached to a reference type act upon what is referenced, not the reference itself. References are more than just automatic pointers, and even so, when it comes down to it, "pass by reference" in Ada is still no more than a "hidden pointer." > Does work. Did it hundreds of times. If you use reference as class members > the compiler will stop creating copy constructors and warn you if you > forget to assign data inside the constructor. > This is because as I said above references are not just automatic pointers. They cannot be changed, so the compiler does not know how to create a copy constructor for you. You may still create one yourself, but you still cannot change the reference. Its the same as if you have other constant, non-mutable members. > > If you don't understand a language, you don't have any grounds to lambaste > > it. > > Just for the record: I have 10 years+ experience in C/C++ programming. I > know which bugs I have hunted. I know when the dam compiler turned my > arrays into pointer when I did not want, did not need it. Thank you very > much. > > And this is why I am here in this Ada group: I only program C/C++ when I get > paid for it and not one line for my private needs. > > With Regards > > Martin > -- > mailto://krischik@users.sourceforge.net > http://www.ada.krischik.com > ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 19:40 ` Xenos @ 2004-05-14 22:47 ` Ludovic Brenta 2004-05-15 8:34 ` Martin Krischik 2004-05-16 2:55 ` Hyman Rosen 0 siblings, 2 replies; 59+ messages in thread From: Ludovic Brenta @ 2004-05-14 22:47 UTC (permalink / raw) "Xenos" writes: > Arrays in C/C++ are not first-class citizens and cannot be functions > parmeters. Saying foo(int x[]) does not define x as an array type, > so of course sizeof x will equal sizeof(int*). Well, I think that that was the whole point Martin was making. In Ada, arrays *are* first-class citizens. However you want to present things, sooner or later you will have to concede that C++ "arrays" create whole classes of potential problems which simply do not exist in Ada. The std::vector template class is not a first-class citizen, and therefore inherits all the problems; you may very well have a std::vector<T>* which really points to an array of vectors, and you'd be back to square one. -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 22:47 ` Ludovic Brenta @ 2004-05-15 8:34 ` Martin Krischik 2004-05-16 2:55 ` Hyman Rosen 1 sibling, 0 replies; 59+ messages in thread From: Martin Krischik @ 2004-05-15 8:34 UTC (permalink / raw) Ludovic Brenta wrote: > "Xenos" writes: >> Arrays in C/C++ are not first-class citizens and cannot be functions >> parmeters. Saying foo(int x[]) does not define x as an array type, >> so of course sizeof x will equal sizeof(int*). > > Well, I think that that was the whole point Martin was making. In > Ada, arrays *are* first-class citizens. However you want to present > things, sooner or later you will have to concede that C++ "arrays" > create whole classes of potential problems which simply do not exist > in Ada. Precisely. Partly the dicussion involves around the fact I have my developers had on an Xenos has his language lawyer had on. If I put my on language lawyer had on I have to fully agree with him. Nothing wrong with what he said. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 22:47 ` Ludovic Brenta 2004-05-15 8:34 ` Martin Krischik @ 2004-05-16 2:55 ` Hyman Rosen 2004-05-16 13:48 ` Ludovic Brenta 1 sibling, 1 reply; 59+ messages in thread From: Hyman Rosen @ 2004-05-16 2:55 UTC (permalink / raw) Ludovic Brenta wrote: > The std::vector template class is not a first-class citizen, and > therefore inherits all the problems; you may very well have a > std::vector<T>* which really points to an array of vectors, and you'd > be back to square one. If you are to have any hope of convincing C++ programmers to switch to Ada, you had better stop revelling in your ignorance. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-16 2:55 ` Hyman Rosen @ 2004-05-16 13:48 ` Ludovic Brenta 2004-05-17 2:30 ` Hyman Rosen 0 siblings, 1 reply; 59+ messages in thread From: Ludovic Brenta @ 2004-05-16 13:48 UTC (permalink / raw) Hyman Rosen writes: > Ludovic Brenta wrote: >> The std::vector template class is not a first-class citizen, and >> therefore inherits all the problems; you may very well have a >> std::vector<T>* which really points to an array of vectors, and >> you'd be back to square one. > > If you are to have any hope of convincing C++ programmers to switch > to Ada, you had better stop revelling in your ignorance. You are not being helpful to anyone with this comment. If you think I am ignorant, please explain why, or otherwise give me one good reason not to put your name in my kill file. -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-16 13:48 ` Ludovic Brenta @ 2004-05-17 2:30 ` Hyman Rosen 2004-05-17 5:39 ` Martin Dowie ` (2 more replies) 0 siblings, 3 replies; 59+ messages in thread From: Hyman Rosen @ 2004-05-17 2:30 UTC (permalink / raw) Ludovic Brenta wrote: > You are not being helpful to anyone with this comment. If you think I > am ignorant, please explain why, or otherwise give me one good reason > not to put your name in my kill file. Oh, by all means put my name in your kill file! But OK. You state that "The std::vector template class is not a first-class citizen". I haven't a clue as to what that might mean. All a std::vector really is in implementation is a record conatining a length and a couple of pointers. You can pass it and return it by value. It's as "first-class" as anything else in the language. You also say "you may very well have a std::vector<T>* which really points to an array of vectors, and you'd be back to square one". Well, it's certainly true that one could declare an array of std::vector, but it would be an awfully strange application that used one of these. Claiming that the possibility of such a construct puts you "back to square one" is simply ridiculous. With nonsensical claims like these, the only C++ programmers you have a chance of attracting are the ones who are ignorant in the language they are using. You are welcome to them, but I doubt that they'll do much for Ada either. C++ programmers who understand the language will shrug off your comments as ignorant bashing. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 2:30 ` Hyman Rosen @ 2004-05-17 5:39 ` Martin Dowie 2004-05-17 7:48 ` Ludovic Brenta 2004-05-17 6:24 ` Martin Krischik 2004-05-17 12:33 ` Dmitry A. Kazakov 2 siblings, 1 reply; 59+ messages in thread From: Martin Dowie @ 2004-05-17 5:39 UTC (permalink / raw) "Hyman Rosen" <hyrosen@mail.com> wrote in message news:3tVpc.34871$vz5.29965@nwrdny01.gnilink.net... > But OK. You state that "The std::vector template class is not > a first-class citizen". I haven't a clue as to what that might > mean. All a std::vector really is in implementation is a record > conatining a length and a couple of pointers. You can pass it > and return it by value. It's as "first-class" as anything else > in the language. I think by that, Ludovic meant that std::vector is a library as opposed to something built into the language (e.g. int's, float's, pointers, etc).. -- Martin ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 5:39 ` Martin Dowie @ 2004-05-17 7:48 ` Ludovic Brenta 2004-05-17 15:01 ` Hyman Rosen 0 siblings, 1 reply; 59+ messages in thread From: Ludovic Brenta @ 2004-05-17 7:48 UTC (permalink / raw) Martin Dowie wrote: > Hyman Rosen wrote: >> But OK. You state that "The std::vector template class is not a >> first-class citizen". I haven't a clue as to what that might >> mean. All a std::vector really is in implementation is a record >> conatining a length and a couple of pointers. You can pass it and >> return it by value. It's as "first-class" as anything else in the >> language. > > I think by that, Ludovic meant that std::vector is a library as > opposed to something built into the language (e.g. int's, float's, > pointers, etc).. Yes, that is what I meant. Basically, std::vector<> does not eliminate the problems inherent to C++ arrays; it only provides a workaround. Hyman also said that a programmer who would have a std::vector<T>* pointing to an array of vectors would be a stupid programmer. I agree, but this is another form of the oft-heard argument that "any good programmer", etc. which it is not convincing to me. -- Ludovic Brenta. -- Use our news server 'news.foorum.com' from anywhere. More details at: http://nnrpinfo.go.foorum.com/ ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 7:48 ` Ludovic Brenta @ 2004-05-17 15:01 ` Hyman Rosen 2004-05-17 16:31 ` Georg Bauhaus 0 siblings, 1 reply; 59+ messages in thread From: Hyman Rosen @ 2004-05-17 15:01 UTC (permalink / raw) Ludovic Brenta wrote: > Yes, that is what I meant. Basically, std::vector<> does not > eliminate the problems inherent to C++ arrays; it only provides a > workaround. OK, suppose I add these four lines to my code: template <typename T, unsigned N> struct array { T a[N]; T &operator[](unsigned i) { return i < N ? a[i] : throw i; } }; Now I can declare my array, for example, as array<double, 100>, and pass it around by value. I haven't used #include. > Hyman also said that a programmer who would have a std::vector<T>* > pointing to an array of vectors would be a stupid programmer. I > agree, but this is another form of the oft-heard argument that "any > good programmer", etc. which it is not convincing to me. No, that's not at all what I said. I said that no programmer would have a native array of vectors, because it's a completely unnatural thing to do. I also said that because of this, only a stupid programmer would consider this to be a valid argument against C++. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 15:01 ` Hyman Rosen @ 2004-05-17 16:31 ` Georg Bauhaus 2004-05-17 17:40 ` Hyman Rosen 0 siblings, 1 reply; 59+ messages in thread From: Georg Bauhaus @ 2004-05-17 16:31 UTC (permalink / raw) Hyman Rosen <hyrosen@mail.com> wrote: : template <typename T, unsigned N> struct array { : T a[N]; : T &operator[](unsigned i) { return i < N ? a[i] : throw i; } : }; : : Now I can declare my array, for example, as array<double, 100>, : and pass it around by value. I haven't used #include. Right. And now, to the Ada fans, from a practical point of view, how does this compare to Ada arrays? At the C++ source level: you don't see any difference at the point of use because operator[] looks like always. In the compiler: I'm not sure, maybe some C++ compilers have switches for std [] vs .at? But, as Dmitry says, a useful template has been built by hand from the small things. (Lisp even gives you the lools for new syntax (re)definitions...) Is an approach based on discipline and conventinalism on a par with language definitions? Somewhat related to this, you can have template parameter constraints like Can_This or Can_That, as explained in http://www.research.att.com/~bs/bs_faq2.html#constraints But is it the same as saying generic type G is new C with private; ... ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 16:31 ` Georg Bauhaus @ 2004-05-17 17:40 ` Hyman Rosen 2004-05-17 19:17 ` Georg Bauhaus 0 siblings, 1 reply; 59+ messages in thread From: Hyman Rosen @ 2004-05-17 17:40 UTC (permalink / raw) Georg Bauhaus wrote: > Is an approach based on discipline and > conventinalism on a par with language definitions? Shrug. How many students of Ada have fallen down trying to create an array of ragged strings? > Somewhat related to this, you can have template parameter constraints > But is it the same as saying > generic type G is new C with private; Not really, but especially in C++, there are philosophical arguments against constraining template parameters in this way. Because of the many possible ways in which a construct might work (because of automatic conversions, etc.), and because uninstantiated template functions don't need to be correct for types with which they are not used, it's better to let the compiler complain on inapprpriate instantiations instead of trying to capture a priori constraints. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 17:40 ` Hyman Rosen @ 2004-05-17 19:17 ` Georg Bauhaus 0 siblings, 0 replies; 59+ messages in thread From: Georg Bauhaus @ 2004-05-17 19:17 UTC (permalink / raw) Hyman Rosen <hyrosen@mail.com> wrote: : Georg Bauhaus wrote: :> Is an approach based on discipline and :> conventinalism on a par with language definitions? : : Shrug. How many students of Ada have fallen down trying to : create an array of ragged strings? Yes, a frequently asked question. Consider this: A few days ago an Apple speaker (at drupa) warned us that Apple's recent C++ compiler (GCC 3.3.x) is very strict wrt the language definition. some of his programs would no longer compile. (He added that gdb is not fun...) Maybe c.l.ada is a strange place where people think too much about sound language definitions, and good validated compilers? ;-) ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 2:30 ` Hyman Rosen 2004-05-17 5:39 ` Martin Dowie @ 2004-05-17 6:24 ` Martin Krischik 2004-05-17 19:48 ` James Kanze 2004-05-17 12:33 ` Dmitry A. Kazakov 2 siblings, 1 reply; 59+ messages in thread From: Martin Krischik @ 2004-05-17 6:24 UTC (permalink / raw) Hyman Rosen wrote: > Ludovic Brenta wrote: >> You are not being helpful to anyone with this comment. If you think I >> am ignorant, please explain why, or otherwise give me one good reason >> not to put your name in my kill file. > > Oh, by all means put my name in your kill file! > > But OK. You state that "The std::vector template class is not > a first-class citizen". I haven't a clue as to what that might > mean Ruffly: First class is everything you can use without (in C/C++) "#include" or (in Ada) "with" or (in Java) "import". vector <> is not a first class citizen because you need "#include <vector>" And, of corse, to copy the hole content of an other file into your own file is cheating. More precisely: First class are only keywords, predefined operators, predefined types, (in Ada ) attribute and perhaps pragmas. Actually: Even "#include" isn't first class since it is part of a preprocessor. I am unsure if, in Ada, Integer is first class since there is an implicit "with Standart; use Standart;". The argument is that everything inside a language need to be implemented with first class citizen - they are the fondatation of everything else and design errors in this area have profound consequences. Out of my 10 years+ experience with C/C++ I say that the following are my personal top 3 C/C++ design mistakes which lead to most of bugs I had to hunt down insted the compiler just finding them for me. 1) #include instead of an proper import/with. 2) implicit type convertion. 3) arrays are pointers. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 6:24 ` Martin Krischik @ 2004-05-17 19:48 ` James Kanze 2004-05-18 6:27 ` Martin Krischik 0 siblings, 1 reply; 59+ messages in thread From: James Kanze @ 2004-05-17 19:48 UTC (permalink / raw) Martin Krischik <krischik@users.sourceforge.net> writes: |> Hyman Rosen wrote: |> > Ludovic Brenta wrote: |> >> You are not being helpful to anyone with this comment. If you |> >> think I am ignorant, please explain why, or otherwise give me one |> >> good reason not to put your name in my kill file. |> > Oh, by all means put my name in your kill file! |> > But OK. You state that "The std::vector template class is not a |> > first-class citizen". I haven't a clue as to what that might mean |> Ruffly: First class is everything you can use without (in C/C++) |> "#include" or (in Ada) "with" or (in Java) "import". So bool and complex are not first class in C, because you need to "turn them on"? I'm afraid I don't really understand this distinction. (The way most C++ intantiations implement this is extremely primitive. But there's nothing second class about it, in the context of the language.) |> vector <> is not a first class citizen because you need "#include |> <vector>" And on many of the early C implementations I'used, float wasn't first class, because you needed to link in a special library to get it? |> And, of corse, to copy the hole content of an other file into your |> own file is cheating. It's certainly not the most robust or the most elegant way of getting the job done, but I don't quite understand why "cheating"? What makes it less honest than anything else (as opposed to simply being a less efficient way of getting the job done)? |> More precisely: First class are only keywords, predefined operators, |> predefined types, (in Ada ) attribute and perhaps pragmas. More precisely: First class is what you like, and second class is everything else. Not much of an argument, really. |> Actually: Even "#include" isn't first class since it is part of a |> preprocessor. |> I am unsure if, in Ada, Integer is first class since there is an |> implicit "with Standart; use Standart;". |> The argument is that everything inside a language need to be |> implemented with first class citizen - they are the fondatation of |> everything else and design errors in this area have profound |> consequences. And one of the basic premises of Stroustrup is that there should be as little in the language as possible. I don't necessarily agree with this attitude; some things, like closure, can really only be done effectively from within the language. But just saying it is bad, or second class, doesn't prove anything. |> Out of my 10 years+ experience with C/C++ I say that the following |> are my personal top 3 C/C++ design mistakes which lead to most of |> bugs I had to hunt down insted the compiler just finding them for |> me. |> 1) #include instead of an proper import/with. |> 2) implicit type convertion. |> 3) arrays are pointers. Arrays aren't pointers. There's just another implicit type conversion. And you don't mention the declaration syntax, which is enough to drive any sane man up the wall. -- James Kanze 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 ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 19:48 ` James Kanze @ 2004-05-18 6:27 ` Martin Krischik 0 siblings, 0 replies; 59+ messages in thread From: Martin Krischik @ 2004-05-18 6:27 UTC (permalink / raw) James Kanze wrote: > Martin Krischik <krischik@users.sourceforge.net> writes: > > So bool and complex are not first class in C, because you need to "turn > them on"? I'm afraid I don't really understand this distinction. (The > way most C++ intantiations implement this is extremely primitive. But > there's nothing second class about it, in the context of the language.) Well ISO 9899:1999(6.2.5) declares both _Bool and _Complex as keywords and therefore first class. bool and complex on the other hand are macros and do not feature in the language at all. > |> vector <> is not a first class citizen because you need "#include > |> <vector>" > > And on many of the early C implementations I'used, float wasn't first > class, because you needed to link in a special library to get it? float is a keyword. So float is first class. Neither the Ada ISO standart nor the C/C++ ISO standart define how linking is done. So if you compiler vendor thinks that the float library need to be linked separately is not the fault of the language. > More precisely: First class is what you like, and second class is > everything else. OK, you win. Lets try an other definition: First class are the atomic feature of an language. Those which can not be broken down further. > |> The argument is that everything inside a language need to be > |> implemented with first class citizen - they are the fondatation of > |> everything else and design errors in this area have profound > |> consequences. > And one of the basic premises of Stroustrup is that there should be as > little in the language as possible. I don't necessarily agree with this > attitude; some things, like closure, can really only be done effectively > from within the language. But just saying it is bad, or second class, > doesn't prove anything. I do like second class features as well. In fact I also spend a lot of time creating those second class features so I like well defined building blocks to do that. > |> 1) #include instead of an proper import/with. > |> 2) implicit type convertion. > |> 3) arrays are pointers. > Arrays aren't pointers. There's just another implicit type conversion. You are right. But a particular nasty case of implicit type conversion which deserves to be named separately - you loose the size of the object which leads to nice things like Blaster32. Blaster32 was a nice supprice when I came out of holiday last year. Without Linux I would not able to keep the computer running long enough to download the patch. > And you don't mention the declaration syntax, which is enough to drive > any sane man up the wall. Ah, yes good point. Hint: try to use the "auto" keyword for better readability. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 2:30 ` Hyman Rosen 2004-05-17 5:39 ` Martin Dowie 2004-05-17 6:24 ` Martin Krischik @ 2004-05-17 12:33 ` Dmitry A. Kazakov 2004-05-17 13:46 ` Martin Krischik ` (2 more replies) 2 siblings, 3 replies; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-17 12:33 UTC (permalink / raw) On Mon, 17 May 2004 02:30:23 GMT, Hyman Rosen <hyrosen@mail.com> wrote: >Ludovic Brenta wrote: >> You are not being helpful to anyone with this comment. If you think I >> am ignorant, please explain why, or otherwise give me one good reason >> not to put your name in my kill file. > >But OK. You state that "The std::vector template class is not >a first-class citizen". I haven't a clue as to what that might >mean. All a std::vector really is in implementation is a record >conatining a length and a couple of pointers. You can pass it >and return it by value. It's as "first-class" as anything else >in the language. The difference between first-class and second-class things is that the former cannot be expressed in other language things. Clearly it is desirable to have a minimal set of first-class things providing a richest possible set of second-class ones with minimal efforts. Thus comparing two languages one should take into account not what the first-class objects sets contain or not, but how productive and small they are. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 12:33 ` Dmitry A. Kazakov @ 2004-05-17 13:46 ` Martin Krischik 2004-05-17 15:03 ` Dmitry A. Kazakov 2004-05-17 16:02 ` Alexander E. Kopilovich [not found] ` <URJ8Eg0vzF@VB1162.spb.edu> 2 siblings, 1 reply; 59+ messages in thread From: Martin Krischik @ 2004-05-17 13:46 UTC (permalink / raw) Dmitry A. Kazakov wrote: > On Mon, 17 May 2004 02:30:23 GMT, Hyman Rosen <hyrosen@mail.com> > wrote: > >>Ludovic Brenta wrote: >>> You are not being helpful to anyone with this comment. If you think I >>> am ignorant, please explain why, or otherwise give me one good reason >>> not to put your name in my kill file. >> >>But OK. You state that "The std::vector template class is not >>a first-class citizen". I haven't a clue as to what that might >>mean. All a std::vector really is in implementation is a record >>conatining a length and a couple of pointers. You can pass it >>and return it by value. It's as "first-class" as anything else >>in the language. > > The difference between first-class and second-class things is that the > former cannot be expressed in other language things. Clearly it is > desirable to have a minimal set of first-class things providing a > richest possible set of second-class ones with minimal efforts. Thus > comparing two languages one should take into account not what the > first-class objects sets contain or not, but how productive and small > they are. How very true. The problem with C/C++ is that the first-class things are like an Iceberg. Very small and beautyfull to look at. But below the surface, hidden from view they are big and ugly and tear your ship apart. And missing propper arrays, with/import and save type convertion there are still to small. With Regards Martin -- mailto://krischik@users.sourceforge.net http://www.ada.krischik.com ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 13:46 ` Martin Krischik @ 2004-05-17 15:03 ` Dmitry A. Kazakov 0 siblings, 0 replies; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-17 15:03 UTC (permalink / raw) On Mon, 17 May 2004 15:46:52 +0200, Martin Krischik <krischik@users.sourceforge.net> wrote: >Dmitry A. Kazakov wrote: > >> On Mon, 17 May 2004 02:30:23 GMT, Hyman Rosen <hyrosen@mail.com> >> wrote: >> >>>Ludovic Brenta wrote: >>>> You are not being helpful to anyone with this comment. If you think I >>>> am ignorant, please explain why, or otherwise give me one good reason >>>> not to put your name in my kill file. >>> >>>But OK. You state that "The std::vector template class is not >>>a first-class citizen". I haven't a clue as to what that might >>>mean. All a std::vector really is in implementation is a record >>>conatining a length and a couple of pointers. You can pass it >>>and return it by value. It's as "first-class" as anything else >>>in the language. >> >> The difference between first-class and second-class things is that the >> former cannot be expressed in other language things. Clearly it is >> desirable to have a minimal set of first-class things providing a >> richest possible set of second-class ones with minimal efforts. Thus >> comparing two languages one should take into account not what the >> first-class objects sets contain or not, but how productive and small >> they are. > >How very true. The problem with C/C++ is that the first-class things are >like an Iceberg. Very small and beautyfull to look at. BTW, I do not find them beautiful. And to be small is not all. Assembler is even smaller. >But below the >surface, hidden from view they are big and ugly and tear your ship apart. >And missing propper arrays, with/import and save type convertion there are >still to small. It is a question whether proper arrays should be built-in. It is thinkable that a very advanced ADT could allow users to define some sort of generic array interface and have all arrays just implementations. This would probably solve many problems with containers. Of course it is not what C++ templates could handle. Besides that templates are IMO a wrong way. So at this stage it is indeed better to have arrays built-in. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 12:33 ` Dmitry A. Kazakov 2004-05-17 13:46 ` Martin Krischik @ 2004-05-17 16:02 ` Alexander E. Kopilovich 2004-05-18 7:48 ` Dmitry A. Kazakov [not found] ` <URJ8Eg0vzF@VB1162.spb.edu> 2 siblings, 1 reply; 59+ messages in thread From: Alexander E. Kopilovich @ 2004-05-17 16:02 UTC (permalink / raw) To: comp.lang.ada Dmitry A. Kazakov wrote: > > You state that "The std::vector template class is not > >a first-class citizen". I haven't a clue as to what that might > >mean. All a std::vector really is in implementation is a record > >conatining a length and a couple of pointers. You can pass it > >and return it by value. It's as "first-class" as anything else > >in the language. > > The difference between first-class and second-class things is that the > former cannot be expressed in other language things. Although this is a possible definition, it isn't shared by everyone. In C and then C++ worlds the difference between core language and the standard library is traditionally blurred (naturally, more for users than for compiler vendors, but the latter are affected also). I'd propose another definition, by analogy (which seems more suitable for some languages, including C/C++): a first-class citizen has Secret Clearance, while those who aren't first-class - haven't it. > Clearly it is > desirable to have a minimal set of first-class things providing a > richest possible set of second-class ones with minimal efforts. This is a language-oriented view, not an application-oriented view, and it isn't (and can't be) shared by vast majority of C/C++ users. > Thus > comparing two languages one should take into account not what the > first-class objects sets contain or not, but how productive and small > they are. That may be true/useful for pure language analysis, but the usage profile (which includes the standard library as well as the most popular non-standard libraries) is no less important for even theoretical conclusions. Alexander Kopilovich aek@vib.usr.pu.ru Saint-Petersburg Russia ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 16:02 ` Alexander E. Kopilovich @ 2004-05-18 7:48 ` Dmitry A. Kazakov 2004-05-19 1:20 ` Alexander E. Kopilovich 0 siblings, 1 reply; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-18 7:48 UTC (permalink / raw) On Mon, 17 May 2004 20:02:27 +0400 (MSD), "Alexander E. Kopilovich" <aek@VB1162.spb.edu> wrote: >Dmitry A. Kazakov wrote: > >> Clearly it is >> desirable to have a minimal set of first-class things providing a >> richest possible set of second-class ones with minimal efforts. > >This is a language-oriented view, not an application-oriented view, and it >isn't (and can't be) shared by vast majority of C/C++ users. Everything depends on what is language and what is application. A component library is an application that directly use the language. A business application might view both the core language and the container library as the language it deals with. This ladder might be endless, but at any height the principle holds. >> Thus >> comparing two languages one should take into account not what the >> first-class objects sets contain or not, but how productive and small >> they are. > >That may be true/useful for pure language analysis, but the usage profile >(which includes the standard library as well as the most popular non-standard >libraries) is no less important for even theoretical conclusions. Sure. But to have a library you need the language first. And as the story of container libraries shows, the languages (both C++ and Ada) seem to be insufficient for this job. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-18 7:48 ` Dmitry A. Kazakov @ 2004-05-19 1:20 ` Alexander E. Kopilovich 2004-05-19 9:59 ` Dmitry A. Kazakov 0 siblings, 1 reply; 59+ messages in thread From: Alexander E. Kopilovich @ 2004-05-19 1:20 UTC (permalink / raw) To: comp.lang.ada Dmitry A. Kazakov wrote: > >> Clearly it is > >> desirable to have a minimal set of first-class things providing a > >> richest possible set of second-class ones with minimal efforts. > > > >This is a language-oriented view, not an application-oriented view, and it > >isn't (and can't be) shared by vast majority of C/C++ users. > > Everything depends on what is language and what is application. A > component library is an application that directly use the language. A > business application might view both the core language and the > container library as the language it deals with. Typical mathematical (algebraic or topological) relativity - (base, extension) -> larger object ( <- sub-object ) > This ladder might be endless, Again, a resolvent corresponds to that in some of those mathematical domains > but at any height the principle holds. Well, principle may be held locally - at each step - but in perspective of several consequtive steps, the situation easily may become quite complex, so that it can't be described adequately by same principle. Also, even locally the principle may be held in some sense, but not so straightforward - for example, what mean that some set of first-class things *provides* a richest possible set of second-class one with *minimal* *efforts*? We have there 3 notions, which can be treated non-trivially. As a good example of possible non-triviality I'd propose 2-categories, where even the notion of equality gets uncommon (but perfectly rigorous) meaning. which is a generalization of common notion of equality in non-trivial way. > But to have a library you need the language first. You may be surprised, but I don't think so. More precisely, I don't think that we must have a language in advance or restrict ourselves to a single language. A library is not necessary an extension of a particular language - this is just a viewpoint and an approach. Another viewpoint and another approach is to build a library as a programming implementation of some theory. To have a library with the latter viewpoint/approach we need not the language first. We even may postpone decision about the languages that we will use (yes, several different languages - why not?) for various parts of our library until the design of the library will reach some level of refinement. What we need first with this approach is solid theoretical ground and clear and consistent requirements for implementation. > And as the story of > container libraries shows, the languages (both C++ and Ada) seem to be > insufficient for this job. The story of container libraries shows once again already known fact: Ada's weakness for *general-purpose* libraries. I think that many Ada.* packages suffer one way or another from this weakness. I guess that from viewpoint of general-purpose libraries, Ada's packages are somehow overloaded with various features and restrictions. What is good for specific-purpose library may be not so good for general-purpose one. I'm not calling here for reconsidering of the notion of package (and not because it is impossible, but simply because current packages are good enough for specific-purpose libraries), but I think that there can be another (i.e., additional) construct, more flexible and less concerned about effectiveness (and even about readability - one may notice that general-purpose libraries have much more chances to be supplied with additional materials then most of specific-purpose libraries). Alexander Kopilovich aek@vib.usr.pu.ru Saint-Petersburg Russia ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 1:20 ` Alexander E. Kopilovich @ 2004-05-19 9:59 ` Dmitry A. Kazakov 2004-05-19 12:38 ` Hyman Rosen 2004-05-19 13:09 ` Georg Bauhaus 0 siblings, 2 replies; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-19 9:59 UTC (permalink / raw) On Wed, 19 May 2004 05:20:55 +0400 (MSD), "Alexander E. Kopilovich" <aek@VB1162.spb.edu> wrote: >Dmitry A. Kazakov wrote: > >> But to have a library you need the language first. > >You may be surprised, but I don't think so. More precisely, I don't think >that we must have a language in advance or restrict ourselves to a single >language. Of course we have to. Things like availability of class-wide programming, MI, MD, interface inheritance, supertyping etc are essential for, say, container library. This heavily influences the whole design. It is C++'s insufficient ADT which led to STL. >A library is not necessary an extension of a particular language - >this is just a viewpoint and an approach. Another viewpoint and another >approach is to build a library as a programming implementation of some >theory. To have a library with the latter viewpoint/approach we need not >the language first. We even may postpone decision about the languages that >we will use (yes, several different languages - why not?) for various parts >of our library until the design of the library will reach some level of >refinement. What we need first with this approach is solid theoretical ground >and clear and consistent requirements for implementation. In which language those requirements will be written? >> And as the story of >> container libraries shows, the languages (both C++ and Ada) seem to be >> insufficient for this job. > >The story of container libraries shows once again already known fact: Ada's >weakness for *general-purpose* libraries. I think that many Ada.* packages >suffer one way or another from this weakness. > >I guess that from viewpoint of general-purpose libraries, Ada's packages are >somehow overloaded with various features and restrictions. What is good for >specific-purpose library may be not so good for general-purpose one. It is never good. >I'm not >calling here for reconsidering of the notion of package (and not because it >is impossible, but simply because current packages are good enough for >specific-purpose libraries), but I think that there can be another (i.e., >additional) construct, more flexible and less concerned about effectiveness >(and even about readability Note that readability is the paramount concern. The whole goal of a container library to provide a higher level of abstraction. One could sacrifice efficiency, though I do not see why it is necessary, but not easiness of use. > - one may notice that general-purpose libraries >have much more chances to be supplied with additional materials then most of >specific-purpose libraries). The major problem is weakness of Ada's ADT. Unfortunately people keep on looking in wrong direction. Generics won't help. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 9:59 ` Dmitry A. Kazakov @ 2004-05-19 12:38 ` Hyman Rosen 2004-05-19 13:28 ` Dmitry A. Kazakov 2004-05-19 13:09 ` Georg Bauhaus 1 sibling, 1 reply; 59+ messages in thread From: Hyman Rosen @ 2004-05-19 12:38 UTC (permalink / raw) Dmitry A. Kazakov wrote: > It is C++'s insufficient ADT which led to STL. This is completely wrong. In fact, Stepanov wrote the first version of what would become STL in Ada in 1985. He even tried to influence Stroustrup to adopt Ada's explicit instantiation model of generics, and only when he started using implicit instantiations did he come to realize their power. You can read about this in an interview with him from 1995, <http://www.sgi.com/tech/stl/drdobbs-interview.html>. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 12:38 ` Hyman Rosen @ 2004-05-19 13:28 ` Dmitry A. Kazakov 0 siblings, 0 replies; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-19 13:28 UTC (permalink / raw) On Wed, 19 May 2004 08:38:08 -0400, Hyman Rosen <hyrosen@mail.com> wrote: >Dmitry A. Kazakov wrote: > > It is C++'s insufficient ADT which led to STL. > >This is completely wrong. In fact, Stepanov wrote the first >version of what would become STL in Ada in 1985. I know it well. >He even tried >to influence Stroustrup to adopt Ada's explicit instantiation >model of generics, and only when he started using implicit >instantiations did he come to realize their power. You can >read about this in an interview with him from 1995, ><http://www.sgi.com/tech/stl/drdobbs-interview.html>. Stepanov wished generic programming. He chose templates because ADT (either in Ada 83 or in C++) was insufficient to provide that (remember his "max" test.) So he came to a conclusion that the whole OO (technically = ADT) is unsound. This is IMO wrong, because templates are not the only way. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 9:59 ` Dmitry A. Kazakov 2004-05-19 12:38 ` Hyman Rosen @ 2004-05-19 13:09 ` Georg Bauhaus 2004-05-19 13:44 ` Hyman Rosen 2004-05-19 14:15 ` Dmitry A. Kazakov 1 sibling, 2 replies; 59+ messages in thread From: Georg Bauhaus @ 2004-05-19 13:09 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: Hm. First you say, : Things like availability of class-wide : programming, MI, MD, interface inheritance, supertyping etc are : essential for, say, container library. Then, : This heavily influences the : whole design. It is C++'s insufficient ADT which led to STL. So I guess you have definitions of "container library" and ADT that are both novel in some respect? Would you mind telling us? : The major problem is weakness of Ada's ADT. Unfortunately people keep : on looking in wrong direction. Generics won't help. Then what will help an Abstract Datatype? How? -- Georg ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 13:09 ` Georg Bauhaus @ 2004-05-19 13:44 ` Hyman Rosen 2004-05-19 14:17 ` Dmitry A. Kazakov 2004-05-19 14:15 ` Dmitry A. Kazakov 1 sibling, 1 reply; 59+ messages in thread From: Hyman Rosen @ 2004-05-19 13:44 UTC (permalink / raw) Georg Bauhaus wrote: > Then what will help an Abstract Datatype? How? It's Kazakov's post, so you should know the answer by now :-) He wants ADTs to be implemented using an inherited interface but to keep the virtual table pointer (or other implementation) separate from the objects by implementing fat pointers which combine the address of the object and the address of the vtable. In this way, he hopes that the code generative power of knowing the explicit types involved in an operation can combine cleanly with the expressive power of OO polymorphism. He is both encouraged and discouraged by the distinction Ada makes between classwide types and regular types because this comes tantalizingly close to implementing his vision, unlike in C++ where this is intertwined with parameter passing semantics of by-reference or by-value. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 13:44 ` Hyman Rosen @ 2004-05-19 14:17 ` Dmitry A. Kazakov 0 siblings, 0 replies; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-19 14:17 UTC (permalink / raw) On Wed, 19 May 2004 09:44:24 -0400, Hyman Rosen <hyrosen@mail.com> wrote: >Georg Bauhaus wrote: >> Then what will help an Abstract Datatype? How? > >It's Kazakov's post, so you should know the answer by now :-) > >He wants ADTs to be implemented using an inherited interface >but to keep the virtual table pointer (or other implementation) >separate from the objects by implementing fat pointers which >combine the address of the object and the address of the vtable. > >In this way, he hopes that the code generative power of knowing the >explicit types involved in an operation can combine cleanly with the >expressive power of OO polymorphism. He is both encouraged and >discouraged by the distinction Ada makes between classwide types and >regular types because this comes tantalizingly close to implementing >his vision, unlike in C++ where this is intertwined with parameter >passing semantics of by-reference or by-value. Nicely put, Hyman. Thanks. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 13:09 ` Georg Bauhaus 2004-05-19 13:44 ` Hyman Rosen @ 2004-05-19 14:15 ` Dmitry A. Kazakov 2004-05-21 11:39 ` Georg Bauhaus 1 sibling, 1 reply; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-19 14:15 UTC (permalink / raw) On Wed, 19 May 2004 13:09:54 +0000 (UTC), Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> wrote: >Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > >Hm. First you say, > >: Things like availability of class-wide >: programming, MI, MD, interface inheritance, supertyping etc are >: essential for, say, container library. > >Then, > >: This heavily influences the >: whole design. It is C++'s insufficient ADT which led to STL. > >So I guess you have definitions of "container library" and ADT >that are both novel in some respect? Would you mind telling us? It is a bit too late for Ada 2005! (:-)) >: The major problem is weakness of Ada's ADT. Unfortunately people keep >: on looking in wrong direction. Generics won't help. > >Then what will help an Abstract Datatype? How? The discussion started with the question why String should or not be a built-in type. Isn't String a container type? I think that everybody would agree that String is much better than either vector<char> or generic thousand parameters package Instantiate_And_Rename_Everything_To_Avoid_Name_Clashes Probably Hyman Rosen would disagree. (*) Now a very simple question, why other containers cannot be made like String? Technically what is needed is abstract array interfaces, abstract index types, discriminants for all types, an ability to put type tags and disctiminants in a dope separate from the value, pure compile-time subprograms to evaluate does, supertypes. Give me that, then ask (:-)) More generally. Generics provide parametrization. It is parametrization which is needed for a container library, not generics. There are alternative ways of parametrization. Who said that parametrization by a type tag, a discriminant, a type constraint are not enough powerful for building a container library? ---- * To prevent questions about varying containers. One can bring String and Unbounded_String under one roof to make them interchangeable. With supertypes one could do it only when needed. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-19 14:15 ` Dmitry A. Kazakov @ 2004-05-21 11:39 ` Georg Bauhaus 2004-05-21 20:33 ` Dmitry A. Kazakov 0 siblings, 1 reply; 59+ messages in thread From: Georg Bauhaus @ 2004-05-21 11:39 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : Technically what is needed is abstract array interfaces, abstract : index types, discriminants for all types, an ability to put type tags : and disctiminants in a dope separate from the value, pure compile-time : subprograms to evaluate does, supertypes. Give me that, then ask (:-)) function item_at (a: Array'type; pos: Index'type) return Element'type; Like this? Is this efficient? How many checks are needed at run time (in the presence of separate compilation)? How do you get hold of plain basic types? Anyway, there are two articles on "Genericity versus Inheritance" by Meyer (1986) and Seidewitz (1994) that I'll have to study first, I guess. -- Georg ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-21 11:39 ` Georg Bauhaus @ 2004-05-21 20:33 ` Dmitry A. Kazakov [not found] ` <c8mkor$rlq$1@a1-hrz.uni-duisburg.de> 0 siblings, 1 reply; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-21 20:33 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > > : Technically what is needed is abstract array interfaces, abstract > : index types, discriminants for all types, an ability to put type tags > : and disctiminants in a dope separate from the value, pure compile-time > : subprograms to evaluate does, supertypes. Give me that, then ask (:-)) > > function item_at (a: Array'type; pos: Index'type) return Element'type; > > Like this? package Standard is type Universal_Array is abstract; -- The base type of all arrays type Universal_Array'Index is abstract; -- Defines anonymous type and abstract type -- attribute 'Index to override type Universal_Array'Element is abstract; function "()" ( Container : Universal_Array; Index : Universal_Array'Index ) return Universal_Array'Element is abstract; When you inherit from (implement) an abstract array type, you have to implement all abstract operations it has. The most difficult problem, when one wishes to get rid of generics (*), is to bring together three types: array, index, element. One could define abstract array of abstract constrained elements over abstract index. But then when you derive from it, you have also derive from index and element. This is a known problem of handling parallel type hierarchies. It appears quite often and seems need to be solved anyway. (*) Surely one could further pursue the present Ada approach to arrays, which is kind of hard-wired "template", because "type X is array (Y) of Z", is much close to a generic instantiation. The problem with that is, that anything that should work with different array types automatically becomes generic as well, which ends in STL for Ada. If we could lift this limitation, things might become much easier. > Is this efficient? How many checks are needed at run time (in the > presence of separate compilation)? Implementations can be declared inline. It does not differ from templates. Then I'd like to have a mechanism to fore compile-time evaluation of pure functions, when arguments are static. This would solve all problems with efficiency. More difficult problems are: 1. setters 2. anonymous array subtypes and anonymous subarray types needed to all sorts of aggregates and slices 3. user-defined aggregates, of course 4. same with index types, to have ranges > How do you get hold of plain basic types? I see no problem with them. For example, discrete types could be considered derived from some abstract index type. So type I is range 1..40; be treated as an abbreviation of something like: type I is new Ordered_Index with range 1..40; -- function ">" (Left, Right : I) return Boolean implements -- function ">" (Left, Right : Ordered_Index) return Boolean is abstract; etc -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
[parent not found: <c8mkor$rlq$1@a1-hrz.uni-duisburg.de>]
* Re: "Must instantiate controlled types at library level." Why? [not found] ` <c8mkor$rlq$1@a1-hrz.uni-duisburg.de> @ 2004-05-23 1:28 ` Hyman Rosen 2004-05-23 8:55 ` Dmitry A. Kazakov 1 sibling, 0 replies; 59+ messages in thread From: Hyman Rosen @ 2004-05-23 1:28 UTC (permalink / raw) Georg Bauhaus wrote: > All problems? How much is static in an average program? Well, C++ gets along very happily with templated containers, so I would say that the answer is "lots". ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? [not found] ` <c8mkor$rlq$1@a1-hrz.uni-duisburg.de> 2004-05-23 1:28 ` Hyman Rosen @ 2004-05-23 8:55 ` Dmitry A. Kazakov 2004-05-24 11:38 ` Georg Bauhaus 1 sibling, 1 reply; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-23 8:55 UTC (permalink / raw) Georg Bauhaus wrote: > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: > > : (*) Surely one could further pursue the present Ada approach to arrays, > : which is kind of hard-wired "template", because "type X is array (Y) of > : Z", is much close to a generic instantiation. The problem with that is, > : that anything that should work with different array types automatically > : becomes generic as well, which ends in STL for Ada. If we could lift > : this limitation, things might become much easier. > > Easier in which way? It is very easy to write a multimethod in CLOS. > I think it is also very easy to forget a whole bunch of cases, > each part of the parameter profile multiplying the number of cases. Are you talking about MD? If Ada should support it, then there RM should require that when one signature of a primitive operation gets overridden all other signatures of the operation should be explicitly overridden as well. To reduce the number of cases one should also provide language support for commutative operations and ones in parallel type hierarchies. > It also incurs some mechanism that dedices what to call based on > arguments, right? That's no problem. The type tag could be an index in a multidimensional dispatch table. > Likewise, how does it become easier to write all the implementations? Discrete types are predefined. Implementations will be needed in non-trivial cases only. For example, if you want an array indexed by String. > If everything that some construct like abstract array indexing needs > has to be provided by the implmenting types, this might easily lead > to type inflation. How it differs from what we have now: generic type Index is private; with function ">" (Left, Right : Index) return Boolean; with function First return Index; ... You have to implement ">" before you instantiate. > I'm not sure whether or not this is better than to > define operations based on what the type already has, and near where > they are needed. You will have this for free with multiple inheritance. Consider a possible scenario of making Integer an array index. It is made by deriving a new type from Integer (by implementation inheritance) and abstract index type (by interface inheritance). The inherited Integer implementation will implement the index interface. This is what will happen behind the scene when you write "array (Integer range <>) of". > :> Is this efficient? How many checks are needed at run time (in the > :> presence of separate compilation)? > : > : Implementations can be declared inline. > > But won't implementations have to have some overhead, inlined or not? > > Say you make Number a base class for all sorts of numbers. That will be an abstract type with no implementation, just an interface. As such it is just a label you can attach to any type by providing implementations. > How do you manage to write code so the compiler will know > it deals with numbers of the kind required in some algorithm > involving Array or MultiArray without whole program analysis? You cannot have objects of an abstract type (interface). So what you would do to write a program dealing with all kind of numbers? Presently it is impossible, so there is nothing to compare with. I have an idea of ad-hoc supertypes. Instead of making all numbers derived from Number, sharing its implementation, which will be either impossible or inefficient, we could create such supertypes as necessary *afterwards*. So if you want to bring Integer and Float under one roof, you create a common non-abstract supertype MyNumber. This would require an implementation for MyNumber, which can be made more efficient, because you know all the players. Observe that now you have a choice: 1. either you write your numeric library in terms of MyNumber, which would make it possible to have efficient shared bodies. 2. or you write it in terms of Number'Class, which will be less efficient if bodies are not inlined (the compiler does not know ultimate type representation). > : It does not differ from templates. > > If you pass pairs of pointers around, and have separate compilation, > and specs and bodies, and access types with values pointing to some > derivation, I imagine a multimethod like > > function "()"(mine: Basket; i: JumpyIndex) return Goods; > > will still not be that quick, unless everything about it can be > found out at compile time. Is this correct? With multimethod (=MD), "()" will dispatch. That's the only overhead I see, and only if the destination is not statically known. Parameter passing mechanism can be any. > : Then I'd like to have a mechanism to fore compile-time evaluation of > : pure functions, when arguments are static. This would solve all problems > : with efficiency. > > All problems? Many. You will have unbounded strings, statically checkable dimensioned values, all user-defined! to begin with... > How much is static in an average program? This varies depending on the application field. In an embedded system it could be 100%. The goal is to go static as much as possible, but also to have an ability to switch to dynamic (=less efficient) approach when you cannot otherwise. > How long does program analysis take for the compiler to find out? > Or is it the linker? I do not expect any new problems here. I presume that generics/templates impose the most difficult problems for compilers (and programmers too). Dymanic management of dispatching tables could become a problem if we relax restrictions of the contexts where the new types can be derived. > : More difficult problems are: > : > : 1. setters > : 2. anonymous array subtypes and anonymous subarray types needed to all > : sorts of aggregates and slices > : 3. user-defined aggregates, of course > : 4. same with index types, to have ranges > : > :> How do you get hold of plain basic types? > : > : I see no problem with them. For example, discrete types could be > : considered derived from some abstract index type. > > Hmmnn, if the compiler knows about some very special derivations > it might know how to use processor registerers for indexing. > Otherwise.... > > : type I is range 1..40; > : > : be treated as an abbreviation of something like: > : > : type I is new Ordered_Index with range 1..40; > : -- function ">" (Left, Right : I) return Boolean implements > : -- function ">" (Left, Right : Ordered_Index) return Boolean is > : abstract; > > This looks somewhat like Haskell, doesn't it? I cannot judge. -- Regards, Dmitry A. Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-23 8:55 ` Dmitry A. Kazakov @ 2004-05-24 11:38 ` Georg Bauhaus 2004-05-24 13:57 ` Dmitry A. Kazakov 0 siblings, 1 reply; 59+ messages in thread From: Georg Bauhaus @ 2004-05-24 11:38 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : Georg Bauhaus wrote: : That's no problem. The type tag could be an index in a multidimensional : dispatch table. With fallback entries, so you don't have to provide entries for all m x n x k for a function of (Tm, Tn) -> Tk, I guess, where m, n, and k the number of types in the respective type trees? :> If everything that some construct like abstract array indexing needs :> has to be provided by the implmenting types, this might easily lead :> to type inflation. : : How it differs from what we have now: [...] : You have to implement ">" before you instantiate. You won't have to add a type with an implementation of a comparison interface. All that is needed is a comparison function, inheritance/implementation is not involved. :> I'm not sure whether or not this is better than to :> define operations based on what the type already has, and near where :> they are needed. : : You will have this for free with multiple inheritance. Yes, but it restricts the number of locations where you are allowed to implement the needed functionality, if you have to implement it. :> How do you manage to write code so the compiler will know :> it deals with numbers of the kind required in some algorithm :> involving Array or MultiArray without whole program analysis? : : You cannot have objects of an abstract type (interface). So what you would : do to write a program dealing with all kind of numbers? Presently it is : impossible, so there is nothing to compare with. OK I was referring to algorithms that only need a certain kind of number, like somthing that can be done using real numbers or complex numbers. Is it impossible to have a generic function that operates on reals as well as on complex numbers? : I have an idea of ad-hoc supertypes. Instead of making all numbers derived : from Number, sharing its implementation, which will be either impossible or : inefficient, we could create such supertypes as necessary *afterwards*. So : if you want to bring Integer and Float under one roof, you create a common : non-abstract supertype MyNumber. This would require an implementation for : MyNumber, which can be made more efficient, because you know all the : players. What's wrong with generic units that work like this, with either formal tagged types or explicit requirements listing with defaults? ;) (In Ada200Y you can even have multiple interfaces, IIRC.) Maybe you want take Eiffel into account, as it has a lot of what you seem to want, including full multiple inheritance? ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-24 11:38 ` Georg Bauhaus @ 2004-05-24 13:57 ` Dmitry A. Kazakov 2004-05-24 14:40 ` Georg Bauhaus 0 siblings, 1 reply; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-24 13:57 UTC (permalink / raw) On Mon, 24 May 2004 11:38:38 +0000 (UTC), Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> wrote: >Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: >: Georg Bauhaus wrote: > >: That's no problem. The type tag could be an index in a multidimensional >: dispatch table. > >With fallback entries, so you don't have to provide entries for >all m x n x k for a function of (Tm, Tn) -> Tk, I guess, where >m, n, and k the number of types in the respective type trees? No, there is only one more level of indirection needed as compared to single dispatch. Consider a procedure dispatching on three arguments: procedure Foo (First : A; Second : B; Third : A); It has the dispatching table: Foo.Impl (i, j, i) -> Implementation Then for each independent argument there is an index map: Foo.A (A_Tag) -> i Foo.B (B_Tag) -> j So to disptach to Foo the compiler should resolve: Foo.Impl (Foo.A (First'Tag), Foo.B (Second'Tag), Foo.A (Third'Tag)) All arrays here are dense. >:> If everything that some construct like abstract array indexing needs >:> has to be provided by the implmenting types, this might easily lead >:> to type inflation. >: >: How it differs from what we have now: [...] >: You have to implement ">" before you instantiate. > >You won't have to add a type with an implementation of a >comparison interface. All that is needed is a comparison function, >inheritance/implementation is not involved. An index type interface is more than just something ordered. What about 'Pred, 'Succ, 'Range, copy constructor, default constructor etc? [BTW, multi-dimensional indices are unordered, (1,2) > (2,1)?] When you write in a generic interface something like "type X is <>", you in fact specify an interface to be implemented. During instantiation the actual type is checked against the interface. If check is OK the implementation is accepted. One can do same for non-generic interfaces. >:> I'm not sure whether or not this is better than to >:> define operations based on what the type already has, and near where >:> they are needed. >: >: You will have this for free with multiple inheritance. > >Yes, but it restricts the number of locations where you are allowed >to implement the needed functionality, if you have to implement it. I see no technical reason why generic instantiations should be more flexible in that respect. AFAIK ARG is going to relax some restrictions anyway. >:> How do you manage to write code so the compiler will know >:> it deals with numbers of the kind required in some algorithm >:> involving Array or MultiArray without whole program analysis? >: >: You cannot have objects of an abstract type (interface). So what you would >: do to write a program dealing with all kind of numbers? Presently it is >: impossible, so there is nothing to compare with. > >OK I was referring to algorithms that only need a certain kind >of number, like somthing that can be done using real numbers or >complex numbers. >Is it impossible to have a generic function that operates on >reals as well as on complex numbers? for I in A'Range loop A (I) := 0; end loop; Is it impossible to write A(A'First) := 0; A(A'First + 1) := 0; A(A'First + 2) := 0; A(A'First + 3) := 0; ... ? >: I have an idea of ad-hoc supertypes. Instead of making all numbers derived >: from Number, sharing its implementation, which will be either impossible or >: inefficient, we could create such supertypes as necessary *afterwards*. So >: if you want to bring Integer and Float under one roof, you create a common >: non-abstract supertype MyNumber. This would require an implementation for >: MyNumber, which can be made more efficient, because you know all the >: players. > >What's wrong with generic units that work like this, with either formal >tagged types or explicit requirements listing with defaults? ;) I do not see how they could help. Consider a program (say parser) that should work with both String and Unbounded_String. When the type is a generic parameter, then the whole compiler will be generic too. >(In Ada200Y you can even have multiple interfaces, IIRC.) > >Maybe you want take Eiffel into account, as it has a lot of what you >seem to want, including full multiple inheritance? C++ has MI. -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-24 13:57 ` Dmitry A. Kazakov @ 2004-05-24 14:40 ` Georg Bauhaus 2004-05-25 8:32 ` Dmitry A. Kazakov 0 siblings, 1 reply; 59+ messages in thread From: Georg Bauhaus @ 2004-05-24 14:40 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : On Mon, 24 May 2004 11:38:38 +0000 (UTC), Georg Bauhaus : <sb463ba@l1-hrz.uni-duisburg.de> wrote: : :>Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: :>: Georg Bauhaus wrote: :> :>: That's no problem. The type tag could be an index in a multidimensional :>: dispatch table. :> :>With fallback entries, so you don't have to provide entries for :>all m x n x k for a function of (Tm, Tn) -> Tk, I guess, where :>m, n, and k the number of types in the respective type trees? : : No, there is only one more level of indirection needed as compared to : single dispatch. OK but to what do the pointers refer? Say I write a two argument procedure expecing it to be dispatching in both. proc drive (v: in out Vehicle; d: Steering_Device); I get drive.Impl (v'tag) -> i drive.Impl (d'tag) -> j OK. Now what if later during development some programmer adds a module that calls drive(vv, ddd); The program then would have to have entries in the dense dispatching maps for i', j', wouldn't it? So in general you will need n x m implementations, unique or not. And prior to whole program analysis you will need fallback mechanisms. : So to disptach to Foo the compiler should resolve: : : Foo.Impl (Foo.A (First'Tag), Foo.B (Second'Tag), Foo.A (Third'Tag)) : : All arrays here are dense. Still before complete analysis of the linked program you might have to provide for the possibility of an argument that is not yet in A's or B's map. How does this remove the conceptual need for an m x n x k dispatch matrix, independent of how you implement it, along with the need to actually think of m x n x k cases? Is it worth the trouble? :>: How it differs from what we have now: [...] :>: You have to implement ">" before you instantiate. :> :>You won't have to add a type with an implementation of a :>comparison interface. All that is needed is a comparison function, :>inheritance/implementation is not involved. : When you write in a generic interface something like "type X is <>", : you in fact specify an interface to be implemented. During : instantiation the actual type is checked against the interface. If : check is OK the implementation is accepted. One can do same for : non-generic interfaces. Yes certainly, but why? There is a cost. And Ada offers you the two ways to specify the requirements, either explicitly, or using a generic formal tagged type. : I see no technical reason why generic instantiations should be more : flexible in that respect. AFAIK ARG is going to relax some : restrictions anyway. Consider a simple untagged user defined type that by itself is not ordered. For some reasons you want to store objects of the type in sorted containers (yes, there may be reasons to do so.) So you have to provide "<", consistent with "=". But "<" does not belong to the simple user defined type because that by itself is not ordered. Solution 1: Add it to the type no matter what and explain that "<" is there because some remote part of the program has good reasons to store objects in a sorted container. Solution 2: Turn the simple user defined type into a tagged type and derive a new one from it adding "<" to the derived type (possibly implementing a Less_Than interface in Ada 200Y). Solution 3: Add "<" locally in the remote part of the program, implement it using operations of the simple user defined type. Solution 3 leaves the simple unordered user defined type completely as is, untagged. At the same time it hides "<" locally, as does solution 2. But 2 achieves this effect only at the cost of making the simple UDT tagged, and adding the possibility of dispaching, prior to a full investigation by the compiler/linker. :>Is it impossible to have a generic function that operates on :>reals as well as on complex numbers? : : for I in A'Range loop : A (I) := 0; A(I) := neutral_element_of_addition; -- of course : end loop; : Is it impossible to write : : A(A'First) := 0; : A(A'First + 1) := 0; : A(A'First + 2) := 0; : A(A'First + 3) := 0; : ... : ? I don't understand. It is possible... :>What's wrong with generic units that work like this, with either formal :>tagged types or explicit requirements listing with defaults? ;) : : I do not see how they could help. Consider a program (say parser) that : should work with both String and Unbounded_String. When the type is a : generic parameter, then the whole compiler will be generic too. I have a generic in a program for turning Wide_String values into external representations. This requires either String or Wide_STring, so I'm using either String or Wide_String in the respective instantiations... If I had a need to inject string polymorphism in all parts of the program I'd do the usual thing: create a user defined type, as for every other predefined type that isn't polymorphic. :>(In Ada200Y you can even have multiple interfaces, IIRC.) :> :>Maybe you want take Eiffel into account, as it has a lot of what you :>seem to want, including full multiple inheritance? : : C++ has MI. I did say Eiffel not because it has MI. It is no alone there. But a lot of what you have said has reminded me not only of C++ templates and compiling/linking, but also of problems that Eiffel has solved. It might be interesting to look at the solution and the consequences it has. Eiffel libraries use MI a lot to express a component's dependence on the presence of methods specified in interfaces like COMPARABLE, HASHABLE, etc. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-24 14:40 ` Georg Bauhaus @ 2004-05-25 8:32 ` Dmitry A. Kazakov 2004-05-25 15:47 ` Georg Bauhaus 0 siblings, 1 reply; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-25 8:32 UTC (permalink / raw) On Mon, 24 May 2004 14:40:33 +0000 (UTC), Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> wrote: >Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: >: On Mon, 24 May 2004 11:38:38 +0000 (UTC), Georg Bauhaus >: <sb463ba@l1-hrz.uni-duisburg.de> wrote: >: >:>Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: >:>: Georg Bauhaus wrote: >:> >:>: That's no problem. The type tag could be an index in a multidimensional >:>: dispatch table. >:> >:>With fallback entries, so you don't have to provide entries for >:>all m x n x k for a function of (Tm, Tn) -> Tk, I guess, where >:>m, n, and k the number of types in the respective type trees? >: >: No, there is only one more level of indirection needed as compared to >: single dispatch. > >OK but to what do the pointers refer? Say I write >a two argument procedure expecing it to be dispatching in both. > > proc drive (v: in out Vehicle; d: Steering_Device); > >I get > drive.Impl (v'tag) -> i > drive.Impl (d'tag) -> j >OK. Now what if later during development some programmer >adds a module that calls > > drive(vv, ddd); > >The program then would have to have entries in the dense >dispatching maps for i', j', wouldn't it? Yes. If there are I types rooted in Vehicle and J types rooted in Steering_Device, then the size of the dispatching table is I x J. >So in general you will need n x m implementations, unique or >not. And prior to whole program analysis you will need fallback >mechanisms. No, it does not differ from SI case. When a new type is derived from some base(s), all primitive operations of that type are inherited. Technically it means that dispatching tables of all subroutines having the type as an [dispatching] argument receive a column(s). >: So to disptach to Foo the compiler should resolve: >: >: Foo.Impl (Foo.A (First'Tag), Foo.B (Second'Tag), Foo.A (Third'Tag)) >: >: All arrays here are dense. > >Still before complete analysis of the linked program you might >have to provide for the possibility of an argument that is not >yet in A's or B's map. Same with SD. >How does this remove the conceptual need for an m x n x k dispatch >matrix, independent of how you implement it, along with the need to >actually think of m x n x k cases? Is it worth the trouble? If you have MD you have to think about all possible combinations of the parameter types. It does not depend on how MD is implemented. It is what MD is. Note that when you are trying to implement MD using SD, these problems do not disappear. There are still m x n x k cases to think of. The only "advantage" is that you have no language support. And finally, Ada already has MD, though limited: 1. All arguments types are descendants of same base 2. Only diagonal elements of the dispatching table can be overridden 3. Non-diagonal elements raise Constraint_Error >:>: How it differs from what we have now: [...] >:>: You have to implement ">" before you instantiate. >:> >:>You won't have to add a type with an implementation of a >:>comparison interface. All that is needed is a comparison function, >:>inheritance/implementation is not involved. > >: When you write in a generic interface something like "type X is <>", >: you in fact specify an interface to be implemented. During >: instantiation the actual type is checked against the interface. If >: check is OK the implementation is accepted. One can do same for >: non-generic interfaces. > >Yes certainly, but why? To have class-wide instances. This is what generics cannot provide. >: I see no technical reason why generic instantiations should be more >: flexible in that respect. AFAIK ARG is going to relax some >: restrictions anyway. > >Consider a simple untagged user defined type that by itself is not >ordered. For some reasons you want to store objects of the type in sorted >containers (yes, there may be reasons to do so.) So you have to provide >"<", consistent with "=". But "<" does not belong to the simple user >defined type because that by itself is not ordered. > >Solution 1: Add it to the type no matter what and explain that > "<" is there because some remote part of the program has good > reasons to store objects in a sorted container. In many cases you cannot do that. Consider predefined types, like the type Tag. It would be nice to have "<" with the semantics of "<:" (a descendant of), but you can nothing to do about it. >Solution 2: Turn the simple user defined type into a tagged type > and derive a new one from it adding "<" to the derived type > (possibly implementing a Less_Than interface in Ada 200Y). >Solution 3: Add "<" locally in the remote part of the program, > implement it using operations of the simple user defined type. In this case "<" will not be a primitive operation of the type. So it might get lost. Even worse are many concurrent implementations of "<" puzzling you which one will be selected by the compiler. >Solution 3 leaves the simple unordered user defined type completely >as is, untagged. At the same time it hides "<" locally, as does >solution 2. But 2 achieves this effect only at the cost of making >the simple UDT tagged, and adding the possibility of dispaching, >prior to a full investigation by the compiler/linker. All specific types have to be tagged in the sense of existence T'Class. This costs nothing as long as no objects of T'Class exist. So you need not care about dispatch. >:>Is it impossible to have a generic function that operates on >:>reals as well as on complex numbers? >: >: for I in A'Range loop >: A (I) := 0; > > A(I) := neutral_element_of_addition; -- of course > >: end loop; > >: Is it impossible to write >: >: A(A'First) := 0; >: A(A'First + 1) := 0; >: A(A'First + 2) := 0; >: A(A'First + 3) := 0; >: ... >: ? > >I don't understand. It is possible... I shows that there is no need to have loop statements in the language, because everything one might wish to do with a finite set of elements can be done using a plain sequence of statements. So when you ask why one needs class-wide programs instead of generic ones, then answer is - no more than loop statements instead of code above. >:>What's wrong with generic units that work like this, with either formal >:>tagged types or explicit requirements listing with defaults? ;) >: >: I do not see how they could help. Consider a program (say parser) that >: should work with both String and Unbounded_String. When the type is a >: generic parameter, then the whole compiler will be generic too. > >I have a generic in a program for turning Wide_String values into >external representations. This requires either String or Wide_STring, >so I'm using either String or Wide_String in the respective >instantiations... >If I had a need to inject string polymorphism in all parts of the >program I'd do the usual thing: create a user defined type, as >for every other predefined type that isn't polymorphic. It is nothing else than I propose - an ability to *easily* create a user-defined type serving as a supertype for String, Unbounded_String, Wide_String, Wide_Wide_String, Wide_Wide_Unbounded_String etc. Presently, you have to do it manually and then explicitly convert values and literal. It is a mess. >:>(In Ada200Y you can even have multiple interfaces, IIRC.) >:> >:>Maybe you want take Eiffel into account, as it has a lot of what you >:>seem to want, including full multiple inheritance? >: >: C++ has MI. > >I did say Eiffel not because it has MI. It is no alone there. >But a lot of what you have said has reminded me not only of >C++ templates and compiling/linking, but also of problems that >Eiffel has solved. It might be interesting to look at the solution >and the consequences it has. >Eiffel libraries use MI a lot to express a component's dependence >on the presence of methods specified in interfaces like COMPARABLE, >HASHABLE, etc. That we will have in Ada200Y with multiple interface inheritance. But that is far not enough to make array types second-class (user-defined). In fact even more interesting would be second-class access types (for smart pointers, garbage collection, etc) -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-25 8:32 ` Dmitry A. Kazakov @ 2004-05-25 15:47 ` Georg Bauhaus 0 siblings, 0 replies; 59+ messages in thread From: Georg Bauhaus @ 2004-05-25 15:47 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote: : everything one might wish to do with a finite set of elements : can be done using a plain sequence of statements. So when you ask why : one needs class-wide programs instead of generic ones, then answer is : - no more than loop statements instead of code above. : [...] : It is nothing else than I propose - an ability to *easily* create a : user-defined type [...] I'm beginning to undestand ;-) You should really consider one of the offerings on the language market that has what you seem to want: making things easy to write. ;-) But that's not Ada, or the languages in its class, right? : It is a mess. But a well defined one? A slot in CLOS may or may not be type-checked according to some CLOS description... -- Georg ^ permalink raw reply [flat|nested] 59+ messages in thread
[parent not found: <URJ8Eg0vzF@VB1162.spb.edu>]
* Re: "Must instantiate controlled types at library level." Why? [not found] ` <URJ8Eg0vzF@VB1162.spb.edu> @ 2004-05-17 16:50 ` Marius Amado Alves 2004-05-18 8:27 ` Dmitry A. Kazakov 0 siblings, 1 reply; 59+ messages in thread From: Marius Amado Alves @ 2004-05-17 16:50 UTC (permalink / raw) To: comp.lang.ada I associate first-class citizenship with being an object. For example, in most languages (including Ada), types are NOT first-class citizens. In languages with a MOP (Meta-Object Protocol), e.g. Smalltalk, types ARE first-class citizens. In most prototype-based languages (e.g. Io) everything is an object. Being an object meaning loosely that it can be passed around, inspected, changed, copied, read, written, put in a container etc., especially at run time. For example, in Ada, every now and then a you need to print the component names of a record. You cannot extract them programmatically, because they aren't first class. ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-17 16:50 ` Marius Amado Alves @ 2004-05-18 8:27 ` Dmitry A. Kazakov 0 siblings, 0 replies; 59+ messages in thread From: Dmitry A. Kazakov @ 2004-05-18 8:27 UTC (permalink / raw) On Mon, 17 May 2004 17:50:23 +0100, "Marius Amado Alves" <amado.alves@netcabo.pt> wrote: >I associate first-class citizenship with being an object. This is a view on a program, not language. It is a valid view. However what was meant is not the objects one can operate, but built-in vs. derived ones. >For example, in most languages (including Ada), types are NOT first-class >citizens. Yes, if you support my view on generics as foreign substances! (:-)) Otherwise, types become first-class objects when they appear as the parameters of generic instantiations. Also do not forget that some attributes take types as parameters. Because Ada allows to override *some* attributes, one should probably count *all* attributes as subroutines. >In languages with a MOP (Meta-Object Protocol), e.g. Smalltalk, types ARE >first-class citizens. Yes. Though it is a question which approach is better. Presently it is very difficult to get even "object" ADT right. If you want to make types objects, you should evolve type ADT. Of course you might hope that the ADT working with normal values, would also do with type values. But from what we know now, it seems that "type arithmetic" is very different. So I do not believe that one could manage values, type values, type type values etc within the same framework. >In most prototype-based languages (e.g. Io) everything is an object. This is a delusion. In any language there should be things one cannot operate. >Being an object meaning loosely that it can be passed around, inspected, >changed, copied, read, written, put in a container etc., especially at run >time. > >For example, in Ada, every now and then a you need to print the component >names of a record. You cannot extract them programmatically, because they >aren't first class. Probably we should distinguish n-class and non-existent objects. (:-)) -- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-14 13:50 ` Xenos 2004-05-14 17:27 ` Georg Bauhaus 2004-05-14 18:49 ` Martin Krischik @ 2004-05-15 17:20 ` Pascal Obry 2 siblings, 0 replies; 59+ messages in thread From: Pascal Obry @ 2004-05-15 17:20 UTC (permalink / raw) "Xenos" <dont.spam.me@spamhate.com> writes: > "Martin Krischik" <krischik@users.sourceforge.net> wrote in message > news:1676457.GMYvKY1ieA@linux1.krischik.com... > > Freejack wrote: > > Simple Mantra: 'Class behaves like String. > > > > If you compare with C/C++: You always have to uses char* pointers since > > C/C++ has no equivalent for String. > > Wrong. C++ has a string class in its standard library. Its a lot more > versitile than Ada's String type. We are talking of C++ the language not what is in the library. Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://www.obry.org --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: "Must instantiate controlled types at library level." Why? 2004-05-13 10:36 ` Peter C. Chapin 2004-05-13 11:18 ` Martin Krischik @ 2004-05-13 19:33 ` Randy Brukardt 1 sibling, 0 replies; 59+ messages in thread From: Randy Brukardt @ 2004-05-13 19:33 UTC (permalink / raw) "Peter C. Chapin" <pchapin@sover.net> wrote in message news:Xns94E8433AB7894pchapinsovernet@207.106.93.237... > Martin Krischik <krischik@users.sourceforge.net> wrote in > news:2780491.NPbR8AFya6@linux1.krischik.com: > > > Well, here you have a good example of the difference of Ada and C++. Ada > > has a complete ban on the construct while C++ goes out and about to ban > > only the tricky part. > > It's interesting to reflect on these different approaches. C++ can get > away with imposing such restrictions on nested functions because nested > functions are rarely used in C++. In Ada similar restrictions on nested > procedures would be entirely unacceptable. Consequently Ada imposes > restrictions in a different place in order to avoid the same fundamental > problem. For what it's worth, the ARG is studying approaches to eliminate this restriction. It would be replaced by a number of smaller ones (checks on allocators, 'Access, return statements, and certain generic derivations). The main reason is the inability to instantiate the containers packages in nested scopes -- that seems like a nasty restriction. Randy. ^ permalink raw reply [flat|nested] 59+ messages in thread
end of thread, other threads:[~2004-05-25 15:47 UTC | newest] Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-05-11 23:04 "Must instantiate controlled types at library level." Why? Peter C. Chapin 2004-05-12 1:03 ` Jeffrey Carter 2004-05-12 10:47 ` Peter C. Chapin 2004-05-12 11:25 ` Ludovic Brenta 2004-05-12 14:41 ` Martin Krischik 2004-05-13 2:20 ` Peter C. Chapin 2004-05-12 11:55 ` Martin Krischik 2004-05-13 2:59 ` Peter C. Chapin 2004-05-13 7:10 ` Martin Krischik 2004-05-13 10:36 ` Peter C. Chapin 2004-05-13 11:18 ` Martin Krischik 2004-05-13 22:27 ` Peter C. Chapin 2004-05-13 22:54 ` Freejack 2004-05-14 7:13 ` Martin Krischik 2004-05-14 13:50 ` Xenos 2004-05-14 17:27 ` Georg Bauhaus 2004-05-14 17:58 ` Xenos 2004-05-14 18:49 ` Martin Krischik 2004-05-14 19:40 ` Xenos 2004-05-14 22:47 ` Ludovic Brenta 2004-05-15 8:34 ` Martin Krischik 2004-05-16 2:55 ` Hyman Rosen 2004-05-16 13:48 ` Ludovic Brenta 2004-05-17 2:30 ` Hyman Rosen 2004-05-17 5:39 ` Martin Dowie 2004-05-17 7:48 ` Ludovic Brenta 2004-05-17 15:01 ` Hyman Rosen 2004-05-17 16:31 ` Georg Bauhaus 2004-05-17 17:40 ` Hyman Rosen 2004-05-17 19:17 ` Georg Bauhaus 2004-05-17 6:24 ` Martin Krischik 2004-05-17 19:48 ` James Kanze 2004-05-18 6:27 ` Martin Krischik 2004-05-17 12:33 ` Dmitry A. Kazakov 2004-05-17 13:46 ` Martin Krischik 2004-05-17 15:03 ` Dmitry A. Kazakov 2004-05-17 16:02 ` Alexander E. Kopilovich 2004-05-18 7:48 ` Dmitry A. Kazakov 2004-05-19 1:20 ` Alexander E. Kopilovich 2004-05-19 9:59 ` Dmitry A. Kazakov 2004-05-19 12:38 ` Hyman Rosen 2004-05-19 13:28 ` Dmitry A. Kazakov 2004-05-19 13:09 ` Georg Bauhaus 2004-05-19 13:44 ` Hyman Rosen 2004-05-19 14:17 ` Dmitry A. Kazakov 2004-05-19 14:15 ` Dmitry A. Kazakov 2004-05-21 11:39 ` Georg Bauhaus 2004-05-21 20:33 ` Dmitry A. Kazakov [not found] ` <c8mkor$rlq$1@a1-hrz.uni-duisburg.de> 2004-05-23 1:28 ` Hyman Rosen 2004-05-23 8:55 ` Dmitry A. Kazakov 2004-05-24 11:38 ` Georg Bauhaus 2004-05-24 13:57 ` Dmitry A. Kazakov 2004-05-24 14:40 ` Georg Bauhaus 2004-05-25 8:32 ` Dmitry A. Kazakov 2004-05-25 15:47 ` Georg Bauhaus [not found] ` <URJ8Eg0vzF@VB1162.spb.edu> 2004-05-17 16:50 ` Marius Amado Alves 2004-05-18 8:27 ` Dmitry A. Kazakov 2004-05-15 17:20 ` Pascal Obry 2004-05-13 19:33 ` Randy Brukardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox