news:w94h61g5wpzn.a60iwvyn0g83$.dlg@40tude.net...
> On Wed, 25 Apr 2012 21:08:06 -0500, Randy Brukardt wrote:
>
>> "Dmitry A. Kazakov" <
mai...@dmitry-kazakov.de> wrote in message
>> news:mdgi0fhwon01$.18b871w98pjl6.dlg@40tude.net...
>> ...
>>> There is no means to flatten P making declarations of Q be directly
>>> visible
>>> for clients of P. E.g. something like
>>>
>>> package P is
>>> package Q is new Foo (...);
>>> use all Q; -- Make things from Q declared directly in P
>>> end P;
>>
>> We tried to do this for Ada 2012; we made heroic efforts to do so. The
>> problem is, this feature is a massive potential maintenance problem which
>> destroys most of the Ada concepts of visibility and maintainablity. (It's
>> all of the mistakes of package "use" multiplied a hundred-fold.)
>>
>> The biggest problem comes when there is a conflict between things
>> declared
>> in P and things declared in Q. Resolving that proved impossible without
>> introducing major headaches.
>
> Certainly there must be a generic mechanism for handling this. Because the
> same issue arises with MI.
Right, MI definitely has similar problems. Indeed, inheritance in general
(no 'M' needed) has similar issues.
But there are two mitigating factors that help cause the problems to be
hidden in inheritance cases:
(1) If the underlying package never gets maintained, problems caused by
maintenance are irrelevant. The easy way to see that is to compare a package
use clause given on Ada.Text_IO versus some under-development package.
Text_IO changes only when a new compiler version is installed, and usually
not even then (it really only changes when the language version does). In
those cases, the issues caused by the new version greatly outweighs any
issues caused by package use, and thus the effect is unnoticable. OTOH, if
you have an actively developed package specification, changes are frequent,
and errors caused by those changes on unrelated code become a significant
effect (and drag on productivity). I suspect that you seem similar effects
based on how much the root type changes.
(2) Ada uses "cancelation" to avoid so-called Beaujolias effects, where a
change causes one legal program to morph into a different legal program.
Cancelation is contained for overloadable entities (the profiles have to
match, which is not very likely, and suggests a definitional problem if
routines with different meaning but the same name and profile exist), but
for non-overloadable things (objects, types, exceptions, packages), anything
with the same name is canceled, which causes a wide net of damage.
Inheritance only involves overloadable entities in Ada, so the damage is
greatly contained in that case.
I tried to suggest making objects overloadable as a mitigation to the
maintenance problems (I don't think we can ever do better than that; at some
point it has to be the case that entities that are too similar are not
considered "unrelated"). But that of course added a whole 'nother level of
complexity to the proposal, and of course it doesn't do anything for types
and packages.
> Probably something really revolutionary is needed here, something like
> introduction of T'Class was, which resolved all OO mess just per finger
> snap.
Not that revolutionary, not for Ada -- overload everything. Most languages
can only overload on parameters, which is way insufficient (objects usually
don't have parameters, and having all objects the same fixes nothing), but
of course Ada can. The problem is mostly one of compatibility; secondarily,
I don't see a good way to have overloaded types (exceptions aren't a
problem; they're just objects of a built-in type; not sure about packages -
package types would do the trick, but seem way over the top).
Probably this would have to wait for Ada-prime (or perhaps Bob Duff's
language :-).
Randy.