comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Construction initialization problem
Date: Fri, 5 Dec 2008 19:42:40 -0600
Date: 2008-12-05T19:42:40-06:00	[thread overview]
Message-ID: <ghclba$2m5$1@munin.nbi.dk> (raw)
In-Reply-To: d16z537mbee4$.wp9rmx0b7kjf.dlg@40tude.net

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:d16z537mbee4$.wp9rmx0b7kjf.dlg@40tude.net...
> On Thu, 4 Dec 2008 16:17:56 -0600, Randy Brukardt wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:oscmgxrpod50$.g7h7snlssha0$.dlg@40tude.net...
>>> Consider this:
>>>
>>>   type A is tagged limited null record;
>>>   type B (X : not null access A'Class) is tagged limited null record;
>>>
>>> Now we want to specialize B so that its instances would already contain 
>>> A:
>>
>> You never explained why you would want the discriminant in the first 
>> place.
>
> Huh, that is a mix-in, a major excuse for not to have multiple inheritance
> in Ada!

A waste of effort. I don't believe in multiple inheritance (in any form); it 
seems to me to be an excuse for sloppy design.

...
> No, in the case I have in mind, mix-in is appropriate. Consider layered
> network protocols. "A" were a transport layer. "B" were a protocol. There
> can be many different transports for the same protocol so an 
> implementation
> of B shall dispatch to the operations of A. If B would inherit to A that
> would require permanent conversions to A'Class inside the operations of B
> (=a mess).

I agree. I think it would be best to keep the two types totally separate. 
And use a function constructor to glue them together.

> Now consider that at some point you decided which transport
> (some type derived from A) and which protocol (some type derived from B) 
> to
> take. You want to put it all into one opaque object. That would be the 
> type
> C.

I'm dubious that this is a good idea. But I think you could do so just fine 
with an appropriate constructor function.

> But you cannot, without pointers and dynamic allocation. Welcome back to 
> C++!

If you have to resort to a dynamically allocated component, just wrap it in 
a holder container. Then there is no possibility of data loss or (visible) 
dynamic allocation. It would be nice to have a way to access the object 
directly in such a container (a problem that I am working on for Amendment 
2), but that is not a critical part to be able to do this.

>> Access discriminants have a fairly high overhead in Ada (because of the
>> possibility of coextensions), so unless you *need* coextensions, they 
>> ought
>> to be avoided.
>
> Do you mean space or time overhead?

Yes. :-)

...
>> But the only time you must use a discriminant is
>> if you have a discriminant-dependent component, and there is no 
>> interesting
>> way to make a component dependent on an access discriminant. So I'd 
>> prefer
>> to just avoid the discriminant.
>>
>> If you're using discriminants to stand in for a proper constructor, I say
>> "don't!!" Use a constructor function as the language intends (and force 
>> it
>> with a (<>) if you need it).
>
> Oh no, been there. The problem arose from inability to write such a
> function! You must be able to write an aggregate to return it from the
> function. The components of the aggregate will have the constraints
> impossible to spell.

The reason that we added extended return statements to the language is so 
that you don't have to write the entire return thing as an aggregate. The 
only reason you would have to do that is because you used a discriminant 
rather than a component. If it hurts, *don't do that*!!

> ----------------------------
> The language problem is lack of abstraction. If there were abstract access
> types, then you could make an instance of A implement the interface of
> "access A" and them simply put an object of A as a discriminant for B:
>
>   type AA is new A and access A with null record; -- A and access to A
>   overriding function "'Access" (X : A) return access A;
>   function Create return AA; -- Creates an instance of AA
>   B_with_A : B (Create); -- Constrain it by an object

I don't understand this point at all. But it doesn't matter, because a 
function like your function "access" doesn't work: the accessibility will be 
wrong. Currently it would be library level, meaning that you could only 
return 'Unchecked_Access and essentially everything would be a dangling 
pointer. Tucker has a proposal to fix that (AI05-0051-1), but it requires a 
lot of additional runtime overhead for functions returning anonymous access 
types. That's probably not what you want, especially given that you could 
not do much with the result other than dereferencing it. (With Tucker's 
current proposal, 'Access would still always be illegal; that can be fixed 
to allow accessibility to the point of the call, but that doesn't help if 
you want to keep the access longer.)

I've been trying to work on this problem, but the obvious solutions would 
require full dynamic accessibility checks, including passing the 
accessibility of all by-reference parameters -- and that is way too 
expensive to consider. Plus dynamic checks provide a new failure mechanism 
for code; it's not clear that is an advantage.

I think that I might be able to fix the problem in the context of the 
containers only, and for dereference of the objects only, but it is not 
clear that the fix is worth the effort.

                                                       Randy.





  reply	other threads:[~2008-12-06  1:42 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-04 16:08 Construction initialization problem Dmitry A. Kazakov
2008-12-04 17:35 ` Adam Beneschan
2008-12-04 22:17 ` Randy Brukardt
2008-12-04 23:02   ` Adam Beneschan
2008-12-06  1:47     ` Randy Brukardt
2008-12-05  9:00   ` Dmitry A. Kazakov
2008-12-06  1:42     ` Randy Brukardt [this message]
2008-12-06 10:16       ` 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