comp.lang.ada
 help / color / mirror / Atom feed
* orthogonal inheritance and extension aggregates
@ 2013-07-19 17:46 Felix Krause
  2013-07-19 18:00 ` Adam Beneschan
  2013-07-19 19:05 ` Dmitry A. Kazakov
  0 siblings, 2 replies; 11+ messages in thread
From: Felix Krause @ 2013-07-19 17:46 UTC (permalink / raw)


I try to implement some feature via orthogonal inhertance like this:


    generic
       type Parent (<>) is abstract tagged private;
    package Extension is
       type Extended is abstract new Parent with private;

       -- operations of the extended type here
    private
       type Extended is abstract new Parent with record
          -- …
       end record;
    end Extension;


Now for testing, I tried to apply this on a Vector:


    package Int_Vectors is new Ada.Container.Vectors (Natural, Integer);
    package Base is new Extension (Int_Vectors.Vector);

    type Child is new Base.Extended with null record;


At the declaration of Child, GNAT tells me "type must be declared 
abstract or "To_Vector" overridden". Can someone explain why this 
happens? As I understand it, To_Vector should be automatically defined 
for the derived type. Is this because the intermediate type Extended is 
declared abstract? Or because To_Vector dispatches in the return type?

Anyway, I tried to declare the function for the type Child like this:


    function To_Vector (Length : Ada.Containers.Count_Type) return Child is
    begin
       return Child'(Base.Extended'(Int_Vectors.To_Vector (Length) with 
others => <>) with null record);
    end To_Vector;


Firstly, this looks rather awkward. Secondly, it doesn't compile: 
"expected private type Extended […] found a composite type". I guess 
this does not work because the type Extended is hidden in the private 
part of Extension. Is it possible to define To_Vector in this context 
to do exactly what the base function does?


-- 
Felix Krause
http://flyx.org/



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-19 17:46 orthogonal inheritance and extension aggregates Felix Krause
@ 2013-07-19 18:00 ` Adam Beneschan
  2013-07-22 16:02   ` Adam Beneschan
  2013-07-19 19:05 ` Dmitry A. Kazakov
  1 sibling, 1 reply; 11+ messages in thread
From: Adam Beneschan @ 2013-07-19 18:00 UTC (permalink / raw)


On Friday, July 19, 2013 10:46:38 AM UTC-7, Felix Krause wrote:
> I try to implement some feature via orthogonal inhertance like this:

> 
>     generic
>        type Parent (<>) is abstract tagged private;
>     package Extension is
>        type Extended is abstract new Parent with private;
> 
>        -- operations of the extended type here
>     private
>        type Extended is abstract new Parent with record
>           -- …
>        end record;
>     end Extension;
> 
> Now for testing, I tried to apply this on a Vector:
> 
>     package Int_Vectors is new Ada.Container.Vectors (Natural, Integer);
>     package Base is new Extension (Int_Vectors.Vector);
> 
>     type Child is new Base.Extended with null record;
> 
> 
> At the declaration of Child, GNAT tells me "type must be declared 
> abstract or "To_Vector" overridden". Can someone explain why this 
> happens? As I understand it, To_Vector should be automatically defined 
> for the derived type. Is this because the intermediate type Extended is 
> declared abstract? Or because To_Vector dispatches in the return type?

This looks like a GNAT bug to me.

                                 -- Adam

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-19 17:46 orthogonal inheritance and extension aggregates Felix Krause
  2013-07-19 18:00 ` Adam Beneschan
@ 2013-07-19 19:05 ` Dmitry A. Kazakov
  2013-07-20  5:49   ` Randy Brukardt
  1 sibling, 1 reply; 11+ messages in thread
From: Dmitry A. Kazakov @ 2013-07-19 19:05 UTC (permalink / raw)


On Fri, 19 Jul 2013 19:46:38 +0200, Felix Krause wrote:

> I try to implement some feature via orthogonal inhertance like this:
> 
>     generic
>        type Parent (<>) is abstract tagged private;
>     package Extension is
>        type Extended is abstract new Parent with private;
> 
>        -- operations of the extended type here
>     private
>        type Extended is abstract new Parent with record
>           -- …
>        end record;
>     end Extension;
> 
> Now for testing, I tried to apply this on a Vector:
> 
>     package Int_Vectors is new Ada.Container.Vectors (Natural, Integer);
>     package Base is new Extension (Int_Vectors.Vector);
> 
>     type Child is new Base.Extended with null record;
> 
> At the declaration of Child, GNAT tells me "type must be declared 
> abstract or "To_Vector" overridden". Can someone explain why this 
> happens? As I understand it, To_Vector should be automatically defined 
> for the derived type. Is this because the intermediate type Extended is 
> declared abstract? Or because To_Vector dispatches in the return type?
> 
> Anyway, I tried to declare the function for the type Child like this:
> 
> 
>     function To_Vector (Length : Ada.Containers.Count_Type) return Child is
>     begin
>        return Child'(Base.Extended'(Int_Vectors.To_Vector (Length) with 
> others => <>) with null record);
>     end To_Vector;
> 
> Firstly, this looks rather awkward. Secondly, it doesn't compile: 
> "expected private type Extended […] found a composite type". I guess 
> this does not work because the type Extended is hidden in the private 
> part of Extension. Is it possible to define To_Vector in this context 
> to do exactly what the base function does?

OK here are two different issues.

1. There are more than one To_Vector declared in Ada.Containers.Vectors.
And there are other primitive operations there you must override:

with Ada.Containers.Vectors;
with Extension;
package PE is
    package Int_Vectors is new Ada.Containers.Vectors (Natural, Integer);
    package Base is new Extension (Int_Vectors.Vector);

    type Child is new Base.Extended with null record;
    overriding
       function To_Vector (Length : Ada.Containers.Count_Type) return
Child;
    overriding
       function To_Vector
                (  New_Item : Integer;
                   Length   : Ada.Containers.Count_Type
		)  return Child;	   
    overriding
       function "&" (Left : Child; Right : Child) return Child;
    overriding
       function "&" (Left : Integer; Right : Child) return Child;
    overriding
       function "&" (Left : Child; Right : Integer) return Child;
    overriding
       function "&" (Left, Right : Integer) return Child;	   
    overriding
       function Copy
                (  Source : Child;
                   Capacity : Ada.Containers.Count_Type := 0
                )  return Child;
end PE;

2. This is a more serious problem. You use a private extension in
Extension, which means that clients cannot use aggregates in order to
create instances.

Extension aggregates is a horrific thing in Ada. But nothing compared to
the constructing function.

At this point you must consider what are you going to fight. If aggregates,
then make extension public. If functions then provide a constructing
function in the Extension package.

Beware that your case will be a *combination* of aggregates and
constructing functions is totally broken in Ada. It might happen to work to
you or not. Nobody, even a language lawyer could say in advance if and when
it will.

P.S. I don't know if Ada 2012 silently inherits from null extension. I
heard that there was an intention to add the kludge. Though semantically
broken it would save programs like yours.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-19 19:05 ` Dmitry A. Kazakov
@ 2013-07-20  5:49   ` Randy Brukardt
  2013-07-20  6:36     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 11+ messages in thread
From: Randy Brukardt @ 2013-07-20  5:49 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:igo2b70i4ox.t5duix9weguc$.dlg@40tude.net...
...
> P.S. I don't know if Ada 2012 silently inherits from null extension. I
> heard that there was an intention to add the kludge. Though semantically
> broken it would save programs like yours.

That's actually an Ada 2005 feature - see 3.9.3(4/2). One that I was against 
because it introduces a maintenance problem (null extensions tend to turn 
into non-null extensions over time, and once that happens, the feature stops 
working).

It appears that GNAT failed to properly implement this feature in the case 
described by the OP.

OTOH, as soon as the OP starts adding components to the extension, they'll 
have the problem again. (I don't think it is practical to extend the 
predefined containers, particularly because it's impossible to derive a 
cursor type to go with the extended container -- so you either end up with 
broken typing or you have do everything twice. And there are a lot of 
functions that have to be overridden.)

             Randy.




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-20  5:49   ` Randy Brukardt
@ 2013-07-20  6:36     ` Dmitry A. Kazakov
  2013-07-20  7:54       ` Niklas Holsti
  0 siblings, 1 reply; 11+ messages in thread
From: Dmitry A. Kazakov @ 2013-07-20  6:36 UTC (permalink / raw)


On Sat, 20 Jul 2013 00:49:41 -0500, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:igo2b70i4ox.t5duix9weguc$.dlg@40tude.net...
> ...
>> P.S. I don't know if Ada 2012 silently inherits from null extension. I
>> heard that there was an intention to add the kludge. Though semantically
>> broken it would save programs like yours.
> 
> That's actually an Ada 2005 feature - see 3.9.3(4/2). One that I was against 
> because it introduces a maintenance problem (null extensions tend to turn 
> into non-null extensions over time, and once that happens, the feature stops 
> working).

Right.

> It appears that GNAT failed to properly implement this feature in the case 
> described by the OP.

But the extension is null only *privately*. How can a public declaration of
the overriding depend on private declaration? It looks totally crazy to me.

> OTOH, as soon as the OP starts adding components to the extension, they'll 
> have the problem again. (I don't think it is practical to extend the 
> predefined containers, particularly because it's impossible to derive a 
> cursor type to go with the extended container -- so you either end up with 
> broken typing or you have do everything twice. And there are a lot of 
> functions that have to be overridden.)

Maintaining parallel types hierarchies is a big type system problem, which
is unclear how to resolve.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-20  6:36     ` Dmitry A. Kazakov
@ 2013-07-20  7:54       ` Niklas Holsti
  0 siblings, 0 replies; 11+ messages in thread
From: Niklas Holsti @ 2013-07-20  7:54 UTC (permalink / raw)


On 13-07-20 09:36 , Dmitry A. Kazakov wrote:
> On Sat, 20 Jul 2013 00:49:41 -0500, Randy Brukardt wrote:
> 
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
>> news:igo2b70i4ox.t5duix9weguc$.dlg@40tude.net...
>> ...
>>> P.S. I don't know if Ada 2012 silently inherits from null extension. I
>>> heard that there was an intention to add the kludge. Though semantically
>>> broken it would save programs like yours.
>>
>> That's actually an Ada 2005 feature - see 3.9.3(4/2). One that I was against 
>> because it introduces a maintenance problem (null extensions tend to turn 
>> into non-null extensions over time, and once that happens, the feature stops 
>> working).
> 
> Right.
> 
>> It appears that GNAT failed to properly implement this feature in the case 
>> described by the OP.
> 
> But the extension is null only *privately*.

The *private* extension looked non-null to me in the original post,
where an ellipsis marks the extension in the private part of the generic:

On 13-07-19 20:46 , Felix Krause wrote:
> I try to implement some feature via orthogonal inhertance like this:
>
>    generic
>       type Parent (<>) is abstract tagged private;
>    package Extension is
>       type Extended is abstract new Parent with private;
>
>       -- operations of the extended type here
>    private
>       type Extended is abstract new Parent with record
>          -- …
>       end record;
>    end Extension;

The visible extension to a non-abstract type was null:

>    type Child is new Base.Extended with null record;

It seems to me that GNAT is working correctly on this code, assuming
that the private extension is not null.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-19 18:00 ` Adam Beneschan
@ 2013-07-22 16:02   ` Adam Beneschan
  2013-07-22 18:44     ` Dmitry A. Kazakov
  2013-07-22 18:59     ` Adam Beneschan
  0 siblings, 2 replies; 11+ messages in thread
From: Adam Beneschan @ 2013-07-22 16:02 UTC (permalink / raw)


On Friday, July 19, 2013 11:00:34 AM UTC-7, Adam Beneschan wrote:
> On Friday, July 19, 2013 10:46:38 AM UTC-7, Felix Krause wrote:
> 
> > I try to implement some feature via orthogonal inhertance like this:
> 
> 
> >     generic
> >        type Parent (<>) is abstract tagged private;
> >     package Extension is
> >        type Extended is abstract new Parent with private;
> > 
> >        -- operations of the extended type here
> >     private
> >        type Extended is abstract new Parent with record
> >           -- …
> >        end record;
> >     end Extension;
> 
> > 
> 
> > Now for testing, I tried to apply this on a Vector:
> 
> >     package Int_Vectors is new Ada.Container.Vectors (Natural, Integer);
> >     package Base is new Extension (Int_Vectors.Vector);
> 
> >     type Child is new Base.Extended with null record;
> 
> > At the declaration of Child, GNAT tells me "type must be declared 
> > abstract or "To_Vector" overridden". Can someone explain why this 
> > happens? As I understand it, To_Vector should be automatically defined 
> > for the derived type. Is this because the intermediate type Extended is 
> > declared abstract? Or because To_Vector dispatches in the return type?
> 
> This looks like a GNAT bug to me.

OK, I goofed.  I forgot that the rules were different when it comes to inherited functions that return tagged types.  GNAT's error message wasn't really helpful. 

The more I look at it, the more I think this is a missing language feature that is not going to be easy to fix.  Normally, if you have a tagged type T and an operation that is a function F that returns T, and in some other package P2 you defined a tagged type T2 that is derived from T and adds components to it, you *must* provide an overriding function F that operates on T2 and (presumably) sets up those additional fields.  If the language allowed you to simply inherit F, that version of F wouldn't set up the new fields.

If you declare T2 to be abstract, the language will let you get away with not overriding F; the inherited F will then be abstract.  I think this might have been a mistake (that is, I think 3.9.3(5) should have applied only to abstract subprograms, not to functions that return controlling types, at least when the parent type is non-abstract).  The package that declares the new fields in the type (i.e. P2) should be responsible for defining the operations that set up the new fields.  This is especially the case when the extension fields are declared in a private part, since other packages that define concrete derived types from T2 have no way to set up the extension fields defined for T2 (unless they happen to be in child packages of P2).  

Generics with formal derived types just make everything worse, as you've noticed, because now, at the time the generic is declared, the compiler can't tell what functions might be present that return the tagged type.  When the generic is instantiated, the question needs to be asked, "All right, we've just inherited some To_Vector functions that return this new Extended type; who's going to be responsible for making sure the new fields are set up"?  And you have two packages pointing fingers at each other.  Extension says it can't do it, because it doesn't know what functions will get inherited.  And the package that contains the instantiation can't do it, because it can't see the fields that need to be set up.  Even if Extension were a public extension, it still wouldn't work, because the language doesn't provide a way for code to instantiate a generic and then define new overriding primitives *inside* the generic.  But in the present case, where it's a private extension, any solution would have to involve some kind of new and interesting kind of cooperation between the two packages, since neither one has access to all the needed information.  The only solution I can think of is to add some sort of "default extension initializer" feature that Extension could provide, and then the inherited To_Vector functions that call the parent To_Vector and then the "default extension initializer" could be implicitly defined.  But I don't like this, since a single routine that initializes the extension components in the same way for all functions may not be appropriate.

So basically I think what you're trying to do just shouldn't be done in Ada, and frankly I think the generic instantiation should have been illegal, and it's a language hole that it lets you get through.  I'll try to think about it and see if there's some other solution that better reflects the class of problem you're trying to solve, rather than being a hack to work around the rules.  (Plus I'll try to think about how this might be handled in other languages, although no other language has the same kind of generic features as Ada so it might be difficult to find an exact parallel.)

                                 -- Adam  




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-22 16:02   ` Adam Beneschan
@ 2013-07-22 18:44     ` Dmitry A. Kazakov
  2013-07-22 18:59     ` Adam Beneschan
  1 sibling, 0 replies; 11+ messages in thread
From: Dmitry A. Kazakov @ 2013-07-22 18:44 UTC (permalink / raw)


On Mon, 22 Jul 2013 09:02:27 -0700 (PDT), Adam Beneschan wrote:

> The more I look at it, the more I think this is a missing language feature
> that is not going to be easy to fix.

Yes. That feature has a name, it is "constructor".

> The only solution I can think of is to add some sort of "default extension
> initializer" feature that Extension could provide,

The "initializer" needs parameters from which it initializes the extension.
It is merely a constructor of the extension.

> So basically I think what you're trying to do just shouldn't be done in Ada,

That Ada offers no means to design opaque types which instances require
initialization does not mean that this should not be done in Ada. It is a
good and useful pattern, which the language should support and encourage.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-22 16:02   ` Adam Beneschan
  2013-07-22 18:44     ` Dmitry A. Kazakov
@ 2013-07-22 18:59     ` Adam Beneschan
  2013-07-22 19:19       ` Adam Beneschan
  2013-07-22 22:03       ` Felix Krause
  1 sibling, 2 replies; 11+ messages in thread
From: Adam Beneschan @ 2013-07-22 18:59 UTC (permalink / raw)


OK, I've thought about this a little more.  First of all, I think the problem might be unique to Ada.  Ada allows you to write a generic that takes an arbitrary tagged type and defines a new extension of that type.  The one other OOP language I'm most familiar with, Java, just doesn't allow this:

   public class ExtensionOf<T> extends T is ...

is illegal.  (T is a "type variable" which is pretty much the equivalent of a generic formal tagged type, and "extends" is how you write derived types; but "extends" doesn't allow "type variables" in its syntax.)

If it did allow it, the new type wouldn't inherit T's constructors, since constructors just aren't inherited.  Ada does try to inherit the "constructors", i.e. functions that return values of the type; but of course the inherited constructors make no sense because they cannot initialize extension components.   Thus, an inherited constructor (for a concrete type) is illegal and must be overridden.  But, as this example shows, this can't be done when the parent type is a generic formal type, since we don't know what functions might be defined for the actual.  

It doesn't make sense for the Extension generic package to try to provide versions of all the constructors that might be defined for the actual type.  I think that the "right" way to handle this would be for Extension to define a function that takes a Parent object and returns an Extended object:

   function Create_Extended (Obj : Parent) return Extended;

where Create_Extended would initialize fields and whatever other action is necessary, and then the code that uses it would do something like

   E1 : Extended := Create_Extended (To_Vector (...));

assuming that Extended were not declared "abstract".  This doesn't solve the legality problem, though.

So I'm thinking that the rules in 3.9.3 need to be relaxed.  3.9.3(4-6) says that for a derived type, if the parent type has any abstract subprograms or functions with a controlling result, then (1) if the derived type is abstract, the inherited subprogram is abstract; or (2) the subprogram must be overridden, except in null extension cases.  What I'm thinking is that we need a (2a) that says something like: if the parent type is a generic formal tagged type or type extension, and the derived type is not a generic formal, and if the subprogram is not abstract [which means it must be a function with a controlling result], and if no overriding subprogram is explicitly provided, the subprogram is overridden with an implicit subprogram that does nothing but raise Program_Error.  This should solve the problem in a case like this--where the language demands that some subprograms be overridden but does not provide any mechanism for doing so.  I'm assuming that if this were the case, Extended would no longer need to be "abstract".  (If it were, this change wouldn't be sufficient.)

Any thoughts?  Does this seem like a possibly worthwhile proposal?

                              -- Adam 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-22 18:59     ` Adam Beneschan
@ 2013-07-22 19:19       ` Adam Beneschan
  2013-07-22 22:03       ` Felix Krause
  1 sibling, 0 replies; 11+ messages in thread
From: Adam Beneschan @ 2013-07-22 19:19 UTC (permalink / raw)


On Monday, July 22, 2013 11:59:29 AM UTC-7, Adam Beneschan wrote:
> What I'm thinking is that we need a (2a) that says something like: if the parent type is a generic formal tagged type or type extension, and the derived type is not a generic formal, and if the subprogram is not abstract [which means it must be a function with a controlling result], and if no overriding subprogram is explicitly provided, the subprogram is overridden with an implicit subprogram that does nothing but raise Program_Error.  This should solve the problem in a case like this--where the language demands that some subprograms be overridden but does not provide any mechanism for doing so.  I'm assuming that if this were the case, Extended would no longer need to be "abstract".  (If it were, this change wouldn't be sufficient.)
> 

I meant for this to apply only in an instance.  I intended to say that, but it got left out somehow.  (Any actual language wording would probably have to refer to "the actual type for a formal", or something like that.)

                          -- Adam


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: orthogonal inheritance and extension aggregates
  2013-07-22 18:59     ` Adam Beneschan
  2013-07-22 19:19       ` Adam Beneschan
@ 2013-07-22 22:03       ` Felix Krause
  1 sibling, 0 replies; 11+ messages in thread
From: Felix Krause @ 2013-07-22 22:03 UTC (permalink / raw)


On 2013-07-22 18:59:29 +0000, Adam Beneschan said:

> OK, I've thought about this a little more.  First of all, I think the 
> problem might be unique to Ada.  Ada allows you to write a generic that 
> takes an arbitrary tagged type and defines a new extension of that 
> type.  The one other OOP language I'm most familiar with, Java, just 
> doesn't allow this:
> 
>    public class ExtensionOf<T> extends T is ...
> 
> is illegal.  (T is a "type variable" which is pretty much the 
> equivalent of a generic formal tagged type, and "extends" is how you 
> write derived types; but "extends" doesn't allow "type variables" in 
> its syntax.)

Just as an example, this would be how one could do it in C++:

    template<class T>
    class extended : public T {
       int i; // some meaningless extension to the base class
    public:
       extended(const T& other) : T(other), i(42) {}
    };

    class my_class : public extended<std::vector<int> > {
       my_class(size_type n) : extended(std::vector<int>(n)) {}
    };

I think there are some interesting things to note here:

 * C++ has no means of explicitly making the intermediate class 
abstract. However,
   if one would define at least one pure virtual (= abstract) method in 
there, it
   would be abstract, and the example would still work. The important 
thing here is
   that unlike Ada, C++ allows constructors for abstract types. In Ada, 
it is impossible
   to provide a generic Create_Extended function like you suggest if 
the type is abstract.
 * C++ makes heavy use of so-called copy constructors, ie. constructors 
that take another
   value of the same type as parameter and create a copy of that value. 
The compiler
   automatically generates a copy constructor if the class meets 
certain criterias.
   In this case, I use the copy constructor of std::vector to create a 
constructor
   of my_class that is similar to the corresponding constructor of std::vector.

So, Ada's primary problem seems to be that one cannot define a 
constructor-like method for
an abstract type. Now the Ada Style Guide at wikibooks tells us

    Consider splitting the initialization and construction of an object. [1]

Let's try to port the idea of an extended creation method to this pattern:

    procedure Init (Obj : in out Extended; From : Parent'Class);

It's important that Init is not a primitive operation of Extended, 
because child
initialization methods may need additional arguments. So it should be 
defined in a nested
package or something:

    package Initialization is
       procedure From_Parent (Obj : in out Extended; From : Parent'Class);
    end Initialization;

By the way, the Style Guide advices the same for constructors (putting 
them in a nested
or child package). While this seems to be a bit bloat, it does solve 
the inheritance problem.

An important issue with this solution is that one should somehow keep 
track of the
initialization status of the object (because if initialization does not 
happen at allocation
automatically, the object may be used uninitialized). The tagged type 
should have a function
"Initialized" that returns a Boolean. As soon as a tagged type does 
provide this mechanism,
all child types need to implement it too (provide an own initialization 
function that calls
one of its parent's initializers), so that this state is consistent 
throughout the type
hierarchy.

The problem is that the Ada language does not endorse this or any other 
pattern. In
C++, copy constructors are the way to go because the language supports 
them aggressively.
In Ada, it may be inconvenient to check Initialized every time before 
we use an object in
any way (well, Ada 2012 has the Pre aspect for such things). And now 
the most important thing:
For this to work in the case I described in my first post, the base 
type given as generic
parameter needs to implement this pattern! Because From_Parent is not 
implementable with
extension aggregates (one cannot assign a value to an abstract type), 
so we would need to
have an initialization method for the Vector type. This is why Ada 
should endorse some
pattern of object construction: If I define one myself, it may work 
with my own code,
but it's just not interoperable with the standard library types or 
potentially third-party
code.


 [1]: 
http://en.wikibooks.org/wiki/Ada_Style_Guide/Object-Oriented_Features#Constructors 


-- 
Felix Krause
http://flyx.org/

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-07-22 22:03 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-19 17:46 orthogonal inheritance and extension aggregates Felix Krause
2013-07-19 18:00 ` Adam Beneschan
2013-07-22 16:02   ` Adam Beneschan
2013-07-22 18:44     ` Dmitry A. Kazakov
2013-07-22 18:59     ` Adam Beneschan
2013-07-22 19:19       ` Adam Beneschan
2013-07-22 22:03       ` Felix Krause
2013-07-19 19:05 ` Dmitry A. Kazakov
2013-07-20  5:49   ` Randy Brukardt
2013-07-20  6:36     ` Dmitry A. Kazakov
2013-07-20  7:54       ` Niklas Holsti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox