comp.lang.ada
 help / color / mirror / Atom feed
From: Maciej Sobczak <see.my.homepage@gmail.com>
Subject: Re: Task components, the rationale
Date: Wed, 13 Jul 2011 13:58:36 -0700 (PDT)
Date: 2011-07-13T13:58:36-07:00	[thread overview]
Message-ID: <d85499cd-83f1-4bd7-a74c-7e21b9aba550@z39g2000yqz.googlegroups.com> (raw)
In-Reply-To: amvut7owrm0l$.1mn2ip1iluzxa$.dlg@40tude.net

On Jul 13, 8:52 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

> Now, if My_Worker started before completion of Initialize then this body
>
>    task body Worker is
>    begin
>        Self.Foo; -- Boom!
>
> could call Foo of T or any of its derived type *before* Initialize, i.e.
> before the object's construction is done! That would be a much worse
> problem.

I don't even think you need to introduce tasks to show the problem -
what if the component is of another controlled type? Then you have two
nested calls to distinct Initialize operations - the first one for the
component (where you have the discriminant access value to play with)
and the second one for the whole, which is too late:

with Ada.Finalization;
with Ada.Text_IO;

procedure Test is

   type Outer;

   type Inner (Shell : access Outer) is
     new Ada.Finalization.Limited_Controlled with null record;

   overriding procedure Initialize (Self : in out Inner);

   type Outer is new Ada.Finalization.Limited_Controlled with record
      I : Inner (Outer'Access);
      Some_Value : Integer;
   end record;

   overriding procedure Initialize (Self : in out Outer);

   procedure Initialize (Self : in out Inner) is
   begin
      Ada.Text_IO.Put_Line
        ("initializing inner, Self.Shell.Some_Value =" &
           Integer'Image (Self.Shell.all.Some_Value));
   end Initialize;

   procedure Initialize (Self : in out Outer) is
   begin
      Self.Some_Value := 123;
      Ada.Text_IO.Put_Line
        ("initialized outer, Some_Value =" &
           Integer'Image (Self.Some_Value));
   end Initialize;

   X : Outer;

begin
   null;
end Test;

$ gnatmake test
...
$ ./test
initializing inner, Self.Shell.Some_Value = 0
initialized outer, Some_Value = 123
$

We are messing with the state that does not yet exist. Oops.

> There is no simple solution for this.

You have to just, you know, simply, introduce constructors to the
language. This is my pet feature for Ada 2020. :-)

> To start with tasks must be
> inheritable from and their bodies must be primitive or class-wide
> operations, because aggregation (composition) + Rosen's trick is
> necessarily broken.

It's not about tasks, it's about access discriminants to outer records
- they introduce circular references (outer has inner, inner knows
outer) and as such are evil.

--
Maciej Sobczak * http://www.msobczak.com * http://www.inspirel.com



  reply	other threads:[~2011-07-13 20:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-13 18:52 Task components, the rationale Dmitry A. Kazakov
2011-07-13 20:58 ` Maciej Sobczak [this message]
2011-07-14  8:52   ` Georg Bauhaus
2011-07-14 18:15     ` Maciej Sobczak
2011-07-22 23:28       ` Randy Brukardt
2011-07-14  9:23   ` Dmitry A. Kazakov
replies disabled

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