comp.lang.ada
 help / color / mirror / Atom feed
* "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 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: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 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 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

* 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 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-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  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  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  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  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 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 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?
       [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: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  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 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-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-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  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 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 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: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 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 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

* 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

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