comp.lang.ada
 help / color / mirror / Atom feed
* 'Protected' abstract subprograms
@ 2014-01-10 22:00 sbelmont700
  2014-01-10 22:30 ` Randy Brukardt
                   ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: sbelmont700 @ 2014-01-10 22:00 UTC (permalink / raw)


I find it to be a fairly common occurrence and, depending on who you ask, a programming best practice to have a publically visible non-abstract dispatching operation re-dispatch to an abstract subprogram (i.e. the 'template pattern').  But Ada cannot have abstract private subprograms, presumably "because a nonabstract type extension declared outside the package would not know about any abstract primitive subprograms..."

But this doesn't really seem like the case, since A) it can already kind of 'see into' the private part to actually extend the type and B) the private part of a child package can *actually* see into the private part of the parent, which is presumably where the operation would be overridden anyhow.  C++ can have protected/private pure virtual functions, so what's stopping Ada?

In any case, does anyone know of a workaround to achieve the same sort of behavior?  I can always just leave both subprograms public, but that leaves an ugly scab I just need to pick at.

-sb


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

* Re: 'Protected' abstract subprograms
  2014-01-10 22:00 'Protected' abstract subprograms sbelmont700
@ 2014-01-10 22:30 ` Randy Brukardt
  2014-01-11 16:12   ` sbelmont700
  2014-01-11  8:41 ` J-P. Rosen
  2014-01-11  8:59 ` Dmitry A. Kazakov
  2 siblings, 1 reply; 30+ messages in thread
From: Randy Brukardt @ 2014-01-10 22:30 UTC (permalink / raw)


<sbelmont700@gmail.com> wrote in message 
news:839fee13-2743-49f6-a7f3-f95578386201@googlegroups.com...
>I find it to be a fairly common occurrence and, depending on who you ask, a 
>programming
>best practice to have a publically visible non-abstract dispatching 
>operation re-dispatch to
>an abstract subprogram (i.e. the 'template pattern').  But Ada cannot have 
>abstract private
>subprograms, presumably "because a nonabstract type extension declared 
>outside the
>package would not know about any abstract primitive subprograms..."

Right. Redispatching seems like a potential cause of problems, but perhaps 
it is OK in this case if it happens immediately (nothing else is executed).

>But this doesn't really seem like the case, since A) it can already kind of 
>'see into' the private
>part to actually extend the type and B) the private part of a child package 
>can *actually* see
>into the private part of the parent, which is presumably where the 
>operation would be overridden
>anyhow.  C++ can have protected/private pure virtual functions, so what's 
>stopping Ada?

You're very confused. Ada takes privacy *very* seriously, something other 
languages barely try. One of the Ada design's unchangable rules is that the 
legality of a client can never be affected by anything in the private part 
of tha package. (The private part can only affect the runtime behavior.) 
We've abandoned many good ideas over the years because of this issue -- it's 
the same reason that interfaces cannot be hidden. If we allowed abstract 
operations in the private part, then the legality of extensions would depend 
on the contents of the private part -- or we'd have to convert that into a 
runtime check rather than a compile-time one, which is the wrong direction 
to go.

(B) is irrelevant, because Ada has no way to restrict extensions to child 
packages, and the problems have to be solved when extending in a non-child 
package -- which is the original problem of enforcing privacy. Besides, the 
idea of extending in child packages works if you have a small, shallow 
hierarchy (admittedly quite common) -- but if you have something deep (like 
the window hierarchy in Claw) you can't do it lest the package names get out 
of hand. (Note: Package use clauses are evil, IMHO, so they don't help.)

>In any case, does anyone know of a workaround to achieve the same sort of 
>behavior?  I can
>always just leave both subprograms public, but that leaves an ugly scab I 
>just need to pick at.

We never tried to do exactly what you want to do, but for Claw, we do have 
many implementation routines that are declared in the private part (mainly 
so that clients can't use them and louse things up). Those of course are not 
abstract, so we have a default implementation that does something, and then 
we override that as needed (in the private part of children, of course). 
Note that this pattern does not work unless you have a strictly matching 
hierarchy of children -- that caused us lots of trouble with Claw since we 
couldn't do that for reasons previously discussed.

My recommendation would be to forget it and use dispatching operations 
directly. Moreover, one shouldn't be afraid of static binding of calls; it 
seems to me that someone who thinks it is a "best practice" to ensure 
maximum call overhead (forcing everything to dispatch even when it doesn't 
need to) has a problem with static binding.

                             Randy.





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

* Re: 'Protected' abstract subprograms
  2014-01-10 22:00 'Protected' abstract subprograms sbelmont700
  2014-01-10 22:30 ` Randy Brukardt
@ 2014-01-11  8:41 ` J-P. Rosen
  2014-01-11  8:59 ` Dmitry A. Kazakov
  2 siblings, 0 replies; 30+ messages in thread
From: J-P. Rosen @ 2014-01-11  8:41 UTC (permalink / raw)


Le 10/01/2014 23:00, sbelmont700@gmail.com a écrit :
> I find it to be a fairly common occurrence and, depending on who you
> ask, a programming best practice to have a publically visible
> non-abstract dispatching operation re-dispatch to an abstract
> subprogram (i.e. the 'template pattern').

Could you give a concrete example of what you are trying to achieve?
Remember that Ada has features that don't exist in other languages (like
the separation between specific and class-wide types), therefore the
solution to a problem may be to use different tools.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

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

* Re: 'Protected' abstract subprograms
  2014-01-10 22:00 'Protected' abstract subprograms sbelmont700
  2014-01-10 22:30 ` Randy Brukardt
  2014-01-11  8:41 ` J-P. Rosen
@ 2014-01-11  8:59 ` Dmitry A. Kazakov
  2014-01-11 13:42   ` Niklas Holsti
  2 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-11  8:59 UTC (permalink / raw)


On Fri, 10 Jan 2014 14:00:31 -0800 (PST), sbelmont700@gmail.com wrote:

> I find it to be a fairly common occurrence and, depending on who you ask,
> a programming best practice to have a publically visible non-abstract
> dispatching operation re-dispatch to an abstract subprogram (i.e. the
> 'template pattern').

Fortunately, in Ada you don't need to re-dispatch because Ada directly
supports composing operations out of primitive operations. That is what
class-wide operations are for.

   type T is abstract ...;
   procedure Bar (X : T) is abstract; -- Primitive operation
   procedure Foo (X : T'Class); -- Class-wide operation

   procedure Foo (X : T'Class) is
   begin
       ...
       Bar (X); -- This dispatches
       ...
   end Foo;

> In any case, does anyone know of a workaround to achieve the same sort of
> behavior?

First, and foremost, never re-dispatch, that is semantically broken [*],
potentially unmaintainable (due to substitutability hell) and inefficient
too.

Secondly. There is another method of hiding operations. You pack it into a
set of implementation packages. The packages declare the operation public,
but the type itself is from some ancestor without the operation:

   type T is new Public_View with private;
private
   type T is new Implementation_View with ...;

The user of T does not know about Implementation_View, which itself is
public of course.

The drawback of this model is construction of new objects derived from T.
But since that is completely broken in Ada, anyway, I mean the mess of
limited aggregates, constructing functions etc, you will have fight that in
any case.

---------
* When you dispatch in a body of an operation that means that the body is
valid for more than one type. Many types = class. Operation for all class =
class-wide operation. It cannot be primitive, per definition. Re-dispatch
breaks this model and effectively makes your design un/weakly typed.

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

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

* Re: 'Protected' abstract subprograms
  2014-01-11  8:59 ` Dmitry A. Kazakov
@ 2014-01-11 13:42   ` Niklas Holsti
  2014-01-11 19:35     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Niklas Holsti @ 2014-01-11 13:42 UTC (permalink / raw)


On 14-01-11 10:59 , Dmitry A. Kazakov wrote:

> First, and foremost, never re-dispatch, that is semantically broken [*],

Not all of us agree with that, and I'm one of them. (I'm just adding a
note to this conversation; I'm not trying to reopen our earlier
discussion on this point with Dmitry, which did not lead anywhere.)

> potentially unmaintainable (due to substitutability hell) and inefficient
> too.

I've had no such problems.

> * When you dispatch in a body of an operation that means that the body is
> valid for more than one type. Many types = class. Operation for all class =
> class-wide operation.

Yes, but "many types" is not the same as "all class". I find it useful
to have primitive operations that implement some behaviour that is not
class-wide, because some types in the class need to alter (override) the
behaviour, yet these operations depend on type-specific lower-level
behaviour, and therefore they call primitive operations with redispatch.

> Re-dispatch breaks this model and effectively makes your design
> un/weakly typed.

I don't agree, because my conceptual "model" is different. Your model is
stronger (more specific) than mine, which paradoxically means that it is
easier to break :-)

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



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

* Re: 'Protected' abstract subprograms
  2014-01-10 22:30 ` Randy Brukardt
@ 2014-01-11 16:12   ` sbelmont700
  2014-01-14  3:45     ` Randy Brukardt
  0 siblings, 1 reply; 30+ messages in thread
From: sbelmont700 @ 2014-01-11 16:12 UTC (permalink / raw)


On Friday, January 10, 2014 5:30:55 PM UTC-5, Randy Brukardt wrote:
> 
> You're very confused. Ada takes privacy *very* seriously, something other 
> 
> languages barely try. One of the Ada design's unchangable rules is that the 
> 
> legality of a client can never be affected by anything in the private part 
> 
> of tha package. (The private part can only affect the runtime behavior.) 
> 
> We've abandoned many good ideas over the years because of this issue -- it's 
> 
> the same reason that interfaces cannot be hidden. If we allowed abstract 
> 
> operations in the private part, then the legality of extensions would depend 
> 
> on the contents of the private part -- or we'd have to convert that into a 
> 
> runtime check rather than a compile-time one, which is the wrong direction 
> 
> to go.
> 
> 

Unfortunately, I am often confused :-(.  The idea that the private part cannot invalidate the client is a good rule, but there often seems to be exceptions and loopholes with child packages; i.e. if I extend a type in a child package by adding a few elements, and then go back and try to add those elements to the parent, I get a compile-time name conflict error in the child.  This implies that the child package is not technically a 'client', but just a logical extension of the parent.  But if that's the case, then the child package could also 'see' an abstract subprogram in the private part, and could in theory overload it.  I'm sure there are all sorts of good reasons and tradeoffs, but I've had more occasion to want to inherit abstract subprograms from the private part in a child package then to extend a private type from a non-child package.

> 
> My recommendation would be to forget it and use dispatching operations 
> 
> directly.
> 

To elaborate on the use case, the intent is not to just ferry a static call to a re-dispatching call, but to use a 'middleman' abstract type to establish reusable code for related groups of implementations.  Wikipedia, GoF, etc all have better descriptions than I can provide, but the idea is that sometimes varied implementations will operate mostly the same, but with smaller differences.  For instance, Vehicle's abstract 'Move' subprogram might be overridden by all manner of plane, train, and automobile, but all the automobiles follow the same basic algorithm (turn key, press accelerator, steer, whatever).  You create an Automobile class that implements the basic driving algorithm for a Car, but that also adds additional abstract operations that represent the particulars (e.g. Turn_Key).  The Drive operation dispatches to these new operations to implement the algorithm.  Now each concrete car type only has to implement the few new additional operations however it sees fit, and the inherited drive operation eliminates duplicating the same algorithm over and over and over for every Car.

Again, it works by just making these publically visible, which is not normally not a big deal since the clients work with the Vehicle'Class anyway, but pedantically the operations should be hidden from everything except the children and not have default implementations, and it's unfortunate that Ada makes you pick one or the other.

Thank you everyone for your responses.

-sb


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

* Re: 'Protected' abstract subprograms
  2014-01-11 13:42   ` Niklas Holsti
@ 2014-01-11 19:35     ` Dmitry A. Kazakov
  2014-01-12  9:19       ` Niklas Holsti
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-11 19:35 UTC (permalink / raw)


On Sat, 11 Jan 2014 15:42:39 +0200, Niklas Holsti wrote:

>> * When you dispatch in a body of an operation that means that the body is
>> valid for more than one type. Many types = class. Operation for all class =
>> class-wide operation.
> 
> Yes, but "many types" is not the same as "all class".

Per design pattern it is all class. Anyway, it is certainly not the
singleton type specified in the pattern, because that is type is abstract.

But of course, if you want to propose changes in the language which would
allow specification of narrower subclasses for such cases, it would be most
welcome.

>> Re-dispatch breaks this model and effectively makes your design
>> un/weakly typed.
> 
> I don't agree, because my conceptual "model" is different. Your model is
> stronger (more specific) than mine, which paradoxically means that it is
> easier to break :-)

Wouldn't that be arguing against strong typing?

The point is that the thing is semantically inconsistent with the types as
annotated. You can say that it is the types here to blame, let's do less
typing. I say, that types are OK, they must be used correctly and not
fought against.

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


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

* Re: 'Protected' abstract subprograms
  2014-01-11 19:35     ` Dmitry A. Kazakov
@ 2014-01-12  9:19       ` Niklas Holsti
  2014-01-12 10:22         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Niklas Holsti @ 2014-01-12  9:19 UTC (permalink / raw)


(I said I wouldn't, but here I go...)

On 14-01-11 21:35 , Dmitry A. Kazakov wrote:
> On Sat, 11 Jan 2014 15:42:39 +0200, Niklas Holsti wrote:
> 
>>> * When you dispatch in a body of an operation that means that the body is
>>> valid for more than one type. Many types = class. Operation for all class =
>>> class-wide operation.
>>
>> Yes, but "many types" is not the same as "all class".
> 
> Per design pattern it is all class. Anyway, it is certainly not the
> singleton type specified in the pattern, because that is type is abstract.
> 
> But of course, if you want to propose changes in the language which would
> allow specification of narrower subclasses for such cases, it would be most
> welcome.

As I see it, it is you who are proposing a change: you say that
redispatch should never be used, so you are proposing a reduced Ada
language which does not *have* redispatch.

>>> Re-dispatch breaks this model and effectively makes your design
>>> un/weakly typed.
>>
>> I don't agree, because my conceptual "model" is different. Your model is
>> stronger (more specific) than mine, which paradoxically means that it is
>> easier to break :-)
> 
> Wouldn't that be arguing against strong typing?

Your concept of classes and types is stronger (more specific and
limiting) than what Ada provides -- in effect, you have certain design
rules which limit you to an Ada subset without redispatch. Ok, if you
find that these rules are beneficial to you, you are free to follow
them, and to suggest that others should follow them too. But you have
not convinced me that these rules are an improvement on the type model
that Ada provides, which includes redispatch.

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



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

* Re: 'Protected' abstract subprograms
  2014-01-12  9:19       ` Niklas Holsti
@ 2014-01-12 10:22         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-12 10:22 UTC (permalink / raw)


On Sun, 12 Jan 2014 11:19:41 +0200, Niklas Holsti wrote:

> (I said I wouldn't, but here I go...)
> 
> On 14-01-11 21:35 , Dmitry A. Kazakov wrote:
>> On Sat, 11 Jan 2014 15:42:39 +0200, Niklas Holsti wrote:
>> 
>>>> * When you dispatch in a body of an operation that means that the body is
>>>> valid for more than one type. Many types = class. Operation for all class =
>>>> class-wide operation.
>>>
>>> Yes, but "many types" is not the same as "all class".
>> 
>> Per design pattern it is all class. Anyway, it is certainly not the
>> singleton type specified in the pattern, because that is type is abstract.
>> 
>> But of course, if you want to propose changes in the language which would
>> allow specification of narrower subclasses for such cases, it would be most
>> welcome.
> 
> As I see it, it is you who are proposing a change: you say that
> redispatch should never be used, so you are proposing a reduced Ada
> language which does not *have* redispatch.

Firstly, when I say that re-dispatch should not be used, that is not same
as proposing to remove it = technically, to disallow view conversions in
the bodies of primitive operations. Though if you asked, yes I would do
that, providing Unchecked_Class instead.

Secondly, it is not reduced. On the contrary, if you want to be able to
re-dispatch then you must reduce the language by limiting dispatching
operation to strictly by-reference types and then reduce these types to
certain representations that would contain the parent's type
representation. It is a very serious and quite non-Ada constraint as it
meddles with representations.

Thirdly, I merely pointed out that if we agreed that re-dispatch refers to
a class, which in your opinion cannot be spelt in the language, then,
logically, you should, if you wanted to keep re-dispatch, change the
language so that this class could be properly specified. Of course,
carefully observing the result of such an extension, you could note that it
would not be re-dispatch anymore because the operation in question would
now act on some class rather than a specific type. Well, that is the point.
Re-dispatch is fundamentally wrong, which does not mean that the
functionality is wrong. You can keep the functionality, but not spell it as
re-dispatch.

>>>> Re-dispatch breaks this model and effectively makes your design
>>>> un/weakly typed.
>>>
>>> I don't agree, because my conceptual "model" is different. Your model is
>>> stronger (more specific) than mine, which paradoxically means that it is
>>> easier to break :-)
>> 
>> Wouldn't that be arguing against strong typing?
> 
> Your concept of classes and types is stronger (more specific and
> limiting) than what Ada provides -- in effect,

I used nothing but class = set of types (a closure of, being precise). How
is it stronger than Ada's concept of class/type? I thought it was the
concept Ada deployed.

> you have certain design
> rules which limit you to an Ada subset without redispatch.

merely strongly typing. Compare it to Unchecked_Conversion and argue
against the design rule to avoid Unchecked_Conversion.

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

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

* Re: 'Protected' abstract subprograms
  2014-01-11 16:12   ` sbelmont700
@ 2014-01-14  3:45     ` Randy Brukardt
  2014-01-14  9:05       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Randy Brukardt @ 2014-01-14  3:45 UTC (permalink / raw)


<sbelmont700@gmail.com> wrote in message 
news:b7ef903a-26f8-4cbc-b137-0f35fe5be406@googlegroups.com...
On Friday, January 10, 2014 5:30:55 PM UTC-5, Randy Brukardt wrote:

>> You're very confused. Ada takes privacy *very* seriously, something other
>> languages barely try. One of the Ada design's unchangable rules is that 
>> the
>> legality of a client can never be affected by anything in the private 
>> part
>> of tha package. (The private part can only affect the runtime behavior.)
>> We've abandoned many good ideas over the years because of this issue --  
>> it's
>> the same reason that interfaces cannot be hidden. If we allowed abstract
>> operations in the private part, then the legality of extensions would 
>> depend
>> on the contents of the private part -- or we'd have to convert that into 
>> a
>> runtime check rather than a compile-time one, which is the wrong 
>> direction
>> to go.

>Unfortunately, I am often confused :-(.  The idea that the private part 
>cannot invalidate
>the client is a good rule, but there often seems to be exceptions and 
>loopholes with child
>packages; i.e. if I extend a type in a child package by adding a few 
>elements, and then
>go back and try to add those elements to the parent, I get a compile-time 
>name conflict
>error in the child.  This implies that the child package is not technically 
>a 'client', but just
>a logical extension of the parent.

Correct.

> But if that's the case, then the child package could also 'see' an 
> abstract subprogram in
>the private part, and could in theory overload it.

Yes, but that would require some way of specifying that the private type 
cannot be extended anywhere *other* than a child of the package containing 
the private type. Without that (and Ada doesn't have it now), you would 
either have to break privacy (by making such non-child extensions illegal, 
which for compatibility could only be the case if private abstract 
operations were used) or convert it into some sort of runtime check. (Ugh.)

The point is that Ada doesn't have a limitation of WHERE you can write an 
extension. One could imagine adding an aspect for such a purpose (it would 
be a lot like Preelaborable_Initialization, which solves a similar problem 
for private types used to declare objects in Preelaborable packages). But in 
the absence of such an aspect or other marker, you would have to break 
privacy, and that's a non-starter for Ada.

As I said last week, Ada takes privacy very seriously, and that definitely 
makes the language design harder (but generally is an advantage to users and 
especially to maintainers of abstractions -- because they don't have to 
worry about users depending on most characteristics.)

                                  Randy.


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

* Re: 'Protected' abstract subprograms
  2014-01-14  3:45     ` Randy Brukardt
@ 2014-01-14  9:05       ` Dmitry A. Kazakov
  2014-01-15  0:36         ` Randy Brukardt
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-14  9:05 UTC (permalink / raw)


On Mon, 13 Jan 2014 21:45:24 -0600, Randy Brukardt wrote:

> Yes, but that would require some way of specifying that the private type 
> cannot be extended anywhere *other* than a child of the package containing 
> the private type.

Doesn't

   type T is private;

already do? It could be reused like

   type T is private [abstract] new ... with ...;

BTW, there already exist cases when you effectively cannot extend a type
publicly, because there would be no way to create an object of that type.

> As I said last week, Ada takes privacy very seriously,

Moderately serious I would say. In numerous cases privacy does not hold.
Worse is that frequently privacy cannot be imposed or requires serious
changes in the structure of types.

Furthermore, there is no support for non-cooperative privacy (run-time
enforced) whatsoever.

IMO, privacy should be taken much more seriously than Ada does now.

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


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

* Re: 'Protected' abstract subprograms
  2014-01-14  9:05       ` Dmitry A. Kazakov
@ 2014-01-15  0:36         ` Randy Brukardt
  2014-01-15  9:17           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Randy Brukardt @ 2014-01-15  0:36 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:on1zhsdlciqw.70mg9osrtb80$.dlg@40tude.net...
> On Mon, 13 Jan 2014 21:45:24 -0600, Randy Brukardt wrote:
>
>> Yes, but that would require some way of specifying that the private type
>> cannot be extended anywhere *other* than a child of the package 
>> containing
>> the private type.
>
> Doesn't
>
>   type T is private;
>
> already do? It could be reused like
>
>   type T is private [abstract] new ... with ...;

I don't understand. The OP would like to restrict the extensions of private 
type T to child packages, because those already can "see" that overriding of 
private abstract operations is needed. That would require some additional 
marking of the private type T in the specification of a package to avoid 
breaking privacy (legality rules cannot depend on the contents of the 
private part).

...
>> As I said last week, Ada takes privacy very seriously,
>
> Moderately serious I would say. In numerous cases privacy does not hold.
> Worse is that frequently privacy cannot be imposed or requires serious
> changes in the structure of types.

Privacy (like other visibility rules) is a compile-time construct only. 
Run-time features (like representation or dynamic checking) are not affected 
by privacy (or visibility). I'm not aware of any cases where privacy does 
not hold at compile-time - it is taken *very* seriously by Ada. (Note that 
child packages are considered part of their parent for visibility, including 
privacy -- you are waiving privacy when you use them -- a good reason to 
avoid them unless truly needed.)

                                            Randy.





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

* Re: 'Protected' abstract subprograms
  2014-01-15  0:36         ` Randy Brukardt
@ 2014-01-15  9:17           ` Dmitry A. Kazakov
  2014-01-15 14:11             ` Robert A Duff
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-15  9:17 UTC (permalink / raw)


On Tue, 14 Jan 2014 18:36:13 -0600, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:on1zhsdlciqw.70mg9osrtb80$.dlg@40tude.net...
>> On Mon, 13 Jan 2014 21:45:24 -0600, Randy Brukardt wrote:
>>
>>> Yes, but that would require some way of specifying that the private type
>>> cannot be extended anywhere *other* than a child of the package 
>>> containing
>>> the private type.
>>
>> Doesn't
>>
>>   type T is private;
>>
>> already do? It could be reused like
>>
>>   type T is private [abstract] new ... with ...;
> 
> I don't understand. The OP would like to restrict the extensions of private 
> type T to child packages, because those already can "see" that overriding of 
> private abstract operations is needed. That would require some additional 
> marking of the private type T in the specification of a package to avoid 
> breaking privacy (legality rules cannot depend on the contents of the 
> private part).

Hmm, of course they can and do. Do you mean legality of public part not
depending on the legality of private parts? Even they do.

Regarding private types, I mean that when T is declared private one cannot
extend it publicly but still can do privately. The following is legal Ada,
AFAIK:

   type T is limited private;
private
   type T is new Ada.Finalization.Limited_Controlled with null record;
   type S is new T with null record;

There is no obvious harm to allow:

   type T is abstract limited private;
private
   type T is abstract new Ada.Finalization.Limited_Controlled
      with null record;
   procedure Foo (X : T) is abstract;

and, more useful:

   type T is private abstract new Ada.Finalization.Limited_Controlled
      with private;
private
   type T is abstract new Ada.Finalization.Limited_Controlled
      with null record;
   procedure Foo (X : T) is abstract; -- OK

Because T is publicly private it cannot be extended publicly and so allowed
to have private abstract operations.

[Not that I propose this sort of language extension]

>>> As I said last week, Ada takes privacy very seriously,
>>
>> Moderately serious I would say. In numerous cases privacy does not hold.
>> Worse is that frequently privacy cannot be imposed or requires serious
>> changes in the structure of types.
> 
> Privacy (like other visibility rules) is a compile-time construct only.

Yep, that's what I meant under "cooperative" privacy. For many
applications, and the number of is growing rapidly, a "non-cooperative"
privacy is needed as well.

> Run-time features (like representation or dynamic checking) are not affected 
> by privacy (or visibility). I'm not aware of any cases where privacy does 
> not hold at compile-time - it is taken *very* seriously by Ada.

Just one trivial example of slack privacy. You cannot hide default values:

   type T is private;
   procedure Foo (X : T := V);
private
   type T is ...

Should have been something like:

   type T is private;
   procedure Foo (X : T := <>); -- The value is deferred
private
   type T is ...
   for Foo'Default (X) use V; -- Here it is, whichever syntax you prefer

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


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

* Re: 'Protected' abstract subprograms
  2014-01-15  9:17           ` Dmitry A. Kazakov
@ 2014-01-15 14:11             ` Robert A Duff
  2014-01-15 15:40               ` adambeneschan
                                 ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: Robert A Duff @ 2014-01-15 14:11 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> Hmm, of course they can and do. Do you mean legality of public part not
> depending on the legality of private parts? Even they do.

I think the principle is:

    The private part cannot affect the legality of clients.

It seems like a good principle, but it is violated all over the place.
Search for "see 12.3" in the RM to find a bunch.  For example:

    generic
       type Formal is tagged limited private;
    package A is
    private
       task type T;
       type Derived is new Formal with record
         Limited_Component: T;
       end record;
    end;

    with A;
    package B is
       type Actual is tagged null record;
       package Instance is new A(Actual);
    end;

Package B is illegal, because of something going on the private
part of A -- without Limited_Component it would be legal.
With Limited_Component, B.Instance.Derived is a nonlimited type
with a limited component, which is illegal.

I think maybe this is an indication that Ada's macro-expansion model
of generics is a wrong approach.

> Yep, that's what I meant under "cooperative" privacy. For many
> applications, and the number of is growing rapidly, a "non-cooperative"
> privacy is needed as well.

Well, in a language that allows Unchecked_Conversion, address clauses,
machine code inserts, etc., I don't see any way to achieve
non-cooperative privacy within a single process.  You can achieve it
in Ada via remote procedure calls, though.

> Just one trivial example of slack privacy. You cannot hide default values:
> 
>    type T is private;

If you have:

    function V return T;

then the default value is hidden.

>    procedure Foo (X : T := V);
> private
>    type T is ...
> 
> Should have been something like:
> 
>    type T is private;
>    procedure Foo (X : T := <>); -- The value is deferred
> private
>    type T is ...
>    for Foo'Default (X) use V; -- Here it is, whichever syntax you prefer

I don't see a need for any such feature.

- Bob

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

* Re: 'Protected' abstract subprograms
  2014-01-15 14:11             ` Robert A Duff
@ 2014-01-15 15:40               ` adambeneschan
  2014-01-15 21:21                 ` Robert A Duff
  2014-01-15 23:17               ` Randy Brukardt
  2014-01-16  8:52               ` Dmitry A. Kazakov
  2 siblings, 1 reply; 30+ messages in thread
From: adambeneschan @ 2014-01-15 15:40 UTC (permalink / raw)


On Wednesday, January 15, 2014 6:11:03 AM UTC-8, Robert A Duff wrote:

> I think the principle is:
> 
>     The private part cannot affect the legality of clients.
> 
> It seems like a good principle, but it is violated all over the place.
> Search for "see 12.3" in the RM to find a bunch.  For example:
> 
>     generic
>        type Formal is tagged limited private;
>     package A is
>     private
>        task type T;
>        type Derived is new Formal with record
>          Limited_Component: T;
>        end record;
>     end;
> 
>     with A;
>     package B is
>        type Actual is tagged null record;
>        package Instance is new A(Actual);
>     end;
> 
> Package B is illegal, because of something going on the private
> part of A -- without Limited_Component it would be legal.
> With Limited_Component, B.Instance.Derived is a nonlimited type
> with a limited component, which is illegal.
> 
> I think maybe this is an indication that Ada's macro-expansion model
> of generics is a wrong approach.

Or it could just mean that Ada didn't provide a complete enough way for generics to put conditions on the actual parameters.  You can say "type T is private;", in which case the actual must be nonlimited; or you can say "type T is limited private;", in which case the actual may be limited or nonlimited.  But you don't have a way to say "the actual must be limited", which is what would be needed here.  (And similarly for "tagged"; generics don't have a way to say "the actual must be untagged", and it seems that I submitted an AI in the last year or two about a case where using a tagged type as an actual for a generic formal private type led to a language hole involving derived types.)

                           -- Adam


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

* Re: 'Protected' abstract subprograms
  2014-01-15 15:40               ` adambeneschan
@ 2014-01-15 21:21                 ` Robert A Duff
  2014-01-15 23:10                   ` Randy Brukardt
  0 siblings, 1 reply; 30+ messages in thread
From: Robert A Duff @ 2014-01-15 21:21 UTC (permalink / raw)


adambeneschan@gmail.com writes:

> Or it could just mean that Ada didn't provide a complete enough way
> for generics to put conditions on the actual parameters.You can say
> "type T is private;", in which case the actual must be nonlimited; or
> you can say "type T is limited private;", in which case the actual may
> be limited or nonlimited.  But you don't have a way to say "the actual
> must be limited", which is what would be needed here.

Yes, that approach could work, but there are dozens of these "generic
private part" rules in the RM, and I suspect they all break privacy.

>...(And similarly
> for "tagged"; generics don't have a way to say "the actual must be
> untagged", and it seems that I submitted an AI in the last year or two
> about a case where using a tagged type as an actual for a generic
> formal private type led to a language hole involving derived types.)

- Bob

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

* Re: 'Protected' abstract subprograms
  2014-01-15 21:21                 ` Robert A Duff
@ 2014-01-15 23:10                   ` Randy Brukardt
  2014-01-16  0:51                     ` Robert A Duff
  0 siblings, 1 reply; 30+ messages in thread
From: Randy Brukardt @ 2014-01-15 23:10 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wcc38kpgcui.fsf@shell01.TheWorld.com...
> adambeneschan@gmail.com writes:
>
>> Or it could just mean that Ada didn't provide a complete enough way
>> for generics to put conditions on the actual parameters.You can say
>> "type T is private;", in which case the actual must be nonlimited; or
>> you can say "type T is limited private;", in which case the actual may
>> be limited or nonlimited.  But you don't have a way to say "the actual
>> must be limited", which is what would be needed here.
>
> Yes, that approach could work, but there are dozens of these "generic
> private part" rules in the RM, and I suspect they all break privacy.

But Adam's point still holds: with enough ability to qualify the actuals, 
these rules aren't needed. The problem is really one of trade-off of 
capability vs. proper qualification. If we did have a way to carefully 
specify what is allowed, in many cases you'd need many copies of a generic 
unit in order to cover the general case.

I forget the exact case, but I recall something like that fairly recently --  
we wanted to require some property to match on generic formals, but then 
many generics would have to be duplicated in order that they would work both 
with and without that property. (Was it predicates? Can't remember anymore.) 
To really get proper working, you have to have "with property", "without 
property", and "don't care about property", but of course the latter brings 
up the legality issues again.

In any case, when I was talking about Ada taking privacy seriously, I wasn't 
thinking about (or caring about) generic instantiation. There is no real 
privacy for generic specifications, nor can there be (at least with the 
model of instantiation that Ada uses). [After all, Ada essentially has 
special rules for the meaning of Legality Rules in generic units - those 
override all other language principles, whether or not that is a good idea.] 
Privacy only really matters for concrete things like packages or instances 
of generic packages.

My point was that that doesn't allow pricavy breaking (for Legality Rules) 
within normal packages. I can't think of any exceptions to that - there 
probably is one that I've forgotten but I doubt it invalidates the point.

                        Randy.


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

* Re: 'Protected' abstract subprograms
  2014-01-15 14:11             ` Robert A Duff
  2014-01-15 15:40               ` adambeneschan
@ 2014-01-15 23:17               ` Randy Brukardt
  2014-01-16  8:52               ` Dmitry A. Kazakov
  2 siblings, 0 replies; 30+ messages in thread
From: Randy Brukardt @ 2014-01-15 23:17 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wcck3e18he0.fsf@shell01.TheWorld.com...
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
...
>> Just one trivial example of slack privacy. You cannot hide default 
>> values:
>>
>>    type T is private;
>
> If you have:
>
>    function V return T;
>
> then the default value is hidden.

Or of course you can use a deferred constant, again the value isn't visible.

    V : constant T;

It's mildly unfortunate that this latter and the former aren't semantically 
equivalent (they should be), but that doesn't have much to do with the 
point.

Dmitry might be wanting to hide the *name* of the value, but that's a silly 
thing to do. Most of the time, people want *more* access to these things, 
not less. If we did provide a way to hide the name of the value, we'd also 
have to provide a way to get the name without using the name:
   Foo.X'Default
Which is just a lot more complex way of making that name visible in your 
interface. All it would do is add a lot more language complexity.

(This problem has come up repeatedly in Ada; the most recent one is a 
request to access the Default_Value for a type; there is no such mechanism 
in Ada 2012, in large part because what the value ought to be for a type 
that doesn't have Default_Value specified is uncertain.)

Ada might have cases of "slack privacy", but I don't think this is one of 
them.

                         Randy.




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

* Re: 'Protected' abstract subprograms
  2014-01-15 23:10                   ` Randy Brukardt
@ 2014-01-16  0:51                     ` Robert A Duff
  2014-01-16 10:43                       ` AdaMagica
  0 siblings, 1 reply; 30+ messages in thread
From: Robert A Duff @ 2014-01-16  0:51 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> But Adam's point still holds: with enough ability to qualify the actuals, 
> these rules aren't needed.

Sure.  And my point was that without a complete change in the way
generics work, that would require dozens of additional contractual
specifications.

> I forget the exact case, but I recall something like that fairly recently --  
> we wanted to require some property to match on generic formals, but then 
> many generics would have to be duplicated in order that they would work both 
> with and without that property. (Was it predicates? Can't remember anymore.) 
> To really get proper working, you have to have "with property", "without 
> property", and "don't care about property", but of course the latter brings 
> up the legality issues again.

I'm not sure what property you're referring to, but "limited" is such a
property.  E.g., you'd like to have Ada.Containers.Vectors contain a
Vector type that is limited if and only if the element type is limited.
It works for arrays, but it doesn't work for vectors.  There are other
cases like that -- e.g. you'd like to be able to say that Vector is
derived from Sortable if and only if the Element_Type has relevant
comparison ops.

> In any case, when I was talking about Ada taking privacy seriously, I wasn't 
> thinking about (or caring about) generic instantiation. There is no real 
> privacy for generic specifications, nor can there be (at least with the 
> model of instantiation that Ada uses). [After all, Ada essentially has 
> special rules for the meaning of Legality Rules in generic units - those 
> override all other language principles, whether or not that is a good idea.] 
> Privacy only really matters for concrete things like packages or instances 
> of generic packages.

Right.  That's (part of) why I think the macro expansion model is wrong.
We pretend that the instance is actually there, and complain about
illegalities in its private part, as if those are the fault of the
person who wrote the instantiation (when in fact, that person did NOT
write that private part).

> My point was that that doesn't allow pricavy breaking (for Legality Rules) 
> within normal packages. I can't think of any exceptions to that - there 
> probably is one that I've forgotten but I doubt it invalidates the point.

The only case I know of where the code in a package private part can affect the
legality of code outside that package is this:

    package Recursive_Types is

       type T1 is private;

       package Nested is
          type T2 is private;
       private
          type T2 is record
             X: T1;
          end record;
       end Nested;

    private
       type T1 is record
          Y: Nested.T2; -- Illegal!
       end record;
    end Recursive_Types;

You're not allowed to have two records that are mutually recursive
like that.  So the legality of T1 depends on the code in Nested's
private part.

But one might argue that this case doesn't count, because there's
no separate compilation here.  You can't get this effect if Nested
is changed to a library unit.

- Bob

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

* Re: 'Protected' abstract subprograms
  2014-01-15 14:11             ` Robert A Duff
  2014-01-15 15:40               ` adambeneschan
  2014-01-15 23:17               ` Randy Brukardt
@ 2014-01-16  8:52               ` Dmitry A. Kazakov
  2 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-16  8:52 UTC (permalink / raw)


On Wed, 15 Jan 2014 09:11:03 -0500, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> Yep, that's what I meant under "cooperative" privacy. For many
>> applications, and the number of is growing rapidly, a "non-cooperative"
>> privacy is needed as well.
> 
> Well, in a language that allows Unchecked_Conversion, address clauses,
> machine code inserts, etc., I don't see any way to achieve
> non-cooperative privacy within a single process.

Using memory protection and routing certain calls through the sealed RTL.
Just the way most OSes do it. Of course RTL could use certain OS services
for that, like it does in the case of tasks mapped on system threads. E.g.
a part of RTL could be implemented as a driver etc.

> You can achieve it
> in Ada via remote procedure calls, though.

Yes, though using network connection is much overhead comparing to
switching contexts. Furthermore RPC is a procedural paradigm unsuitable for
the purpose of privacy in an OO language like Ada, too much heavy-weight.

As a challenge for uncooperative privacy consider User_Credentials object.
Its implementation would store the password inaccessible otherwise than
through operations provided. The instances are kept on memory pages
unmapped for the rest of the program. The bodies of the operations run on
another context, which is switched upon the call. The call also validates
the object's 'reference' and converts it to the true address.

Though from the programmer's perspective semantically the difference from
protected objects Ada already has is not that big, if any.

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


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

* Re: 'Protected' abstract subprograms
  2014-01-16  0:51                     ` Robert A Duff
@ 2014-01-16 10:43                       ` AdaMagica
  2014-01-16 16:32                         ` adambeneschan
  2014-01-17  1:49                         ` Robert A Duff
  0 siblings, 2 replies; 30+ messages in thread
From: AdaMagica @ 2014-01-16 10:43 UTC (permalink / raw)


On Thursday, January 16, 2014 1:51:31 AM UTC+1, Robert A Duff wrote:
> The only case I know of where the code in a package private part can affect the
> legality of code outside that package is this:
>
>     package Recursive_Types is
>
>        type T1 is private;
>
>        package Nested is
>           type T2 is private;
>        private
>           type T2 is record
>              X: T1;

I think this is illegal since it would freeze T1. Wouldn't it?

>           end record;
>        end Nested;
>
>     private
> 
>        type T1 is record


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

* Re: 'Protected' abstract subprograms
  2014-01-16 10:43                       ` AdaMagica
@ 2014-01-16 16:32                         ` adambeneschan
  2014-01-17  1:49                         ` Robert A Duff
  1 sibling, 0 replies; 30+ messages in thread
From: adambeneschan @ 2014-01-16 16:32 UTC (permalink / raw)


On Thursday, January 16, 2014 2:43:36 AM UTC-8, AdaMagica wrote:
> On Thursday, January 16, 2014 1:51:31 AM UTC+1, Robert A Duff wrote:
> 
> > The only case I know of where the code in a package private part can affect the
> > legality of code outside that package is this:
> 
> >     package Recursive_Types is
> >        type T1 is private;
> 
> >        package Nested is
> >           type T2 is private;
> >        private
> >           type T2 is record
> >              X: T1;

> I think this is illegal since it would freeze T1. Wouldn't it?

No, it wouldn't; nothing has yet occurred that would require that the representation of T2 be completely determined (which would also require T1 to be frozen).

                           -- Adam


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

* Re: 'Protected' abstract subprograms
  2014-01-16 10:43                       ` AdaMagica
  2014-01-16 16:32                         ` adambeneschan
@ 2014-01-17  1:49                         ` Robert A Duff
  2014-01-17 23:23                           ` Randy Brukardt
  1 sibling, 1 reply; 30+ messages in thread
From: Robert A Duff @ 2014-01-17  1:49 UTC (permalink / raw)


AdaMagica <christ-usch.grein@t-online.de> writes:

> On Thursday, January 16, 2014 1:51:31 AM UTC+1, Robert A Duff wrote:
>> The only case I know of where the code in a package private part can affect the
>> legality of code outside that package is this:
>>
>>     package Recursive_Types is
>>
>>        type T1 is private;
>>
>>        package Nested is
>>           type T2 is private;
>>        private
>>           type T2 is record
>>              X: T1;
>
> I think this is illegal since it would freeze T1. Wouldn't it?

No, declaring an object of type T1 would freeze T1, but a component
does not.

The freezing rules make my brain hurt.  Even though I had a hand in
writing them!  ;-)

A better-designed language would not have anything like freezing rules.

>>           end record;
>>        end Nested;
>>
>>     private
>> 
>>        type T1 is record

- Bob

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

* Re: 'Protected' abstract subprograms
  2014-01-17  1:49                         ` Robert A Duff
@ 2014-01-17 23:23                           ` Randy Brukardt
  2014-01-19 21:07                             ` Robert A Duff
  0 siblings, 1 reply; 30+ messages in thread
From: Randy Brukardt @ 2014-01-17 23:23 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wccvbxje5sn.fsf@shell01.TheWorld.com...
...
> The freezing rules make my brain hurt.  Even though I had a hand in
> writing them!  ;-)
>
> A better-designed language would not have anything like freezing rules.

That's a facinating assertion from the guy that's responsible for most the 
AARM notes describing the freezing rules. Especially as you guys pretty much 
redesigned that area in Ada 95 -- you essentially created a whole new 
language design for it. It makes me wonder how a language could be better 
designed and not "have anything like freezing rules".

After all, a compiler has to have a known representation for types and 
objects at some point, certainly before code generation. If one is going to 
support some sort of separate compilation (especially *safe* separate 
compilation), freezing rules or something like them seems manditory. [There 
is an argument to be made that a truly modern language doesn't need to 
support separate compilation at the language level, given that it is now 
practical to delay compilation until bind time. But that seems awfully 
radical and would seem to put an upper limit on the sizes of programs that 
could be written in the language. I don't think that's what you meant.]

Ada's freezing rules are far more detailed than absolutely necessary, but 
the obvious way to get simplify them would be to require that all types are 
declared before all objects (a-la Pascal) -- and we have evidence that's too 
inflexible. There don't seem to be any obvious way to simplify them if 
objects can be declared anywhere.

So I have to wonder what sort of "well-designed language" you have in mind.

                                 Randy.







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

* Re: 'Protected' abstract subprograms
  2014-01-17 23:23                           ` Randy Brukardt
@ 2014-01-19 21:07                             ` Robert A Duff
  2014-01-20  8:40                               ` Dmitry A. Kazakov
  2014-01-21  1:21                               ` Randy Brukardt
  0 siblings, 2 replies; 30+ messages in thread
From: Robert A Duff @ 2014-01-19 21:07 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
> news:wccvbxje5sn.fsf@shell01.TheWorld.com...
> ...
>> The freezing rules make my brain hurt.  Even though I had a hand in
>> writing them!  ;-)
>>
>> A better-designed language would not have anything like freezing rules.
>
> That's a facinating assertion from the guy that's responsible for most the 
> AARM notes describing the freezing rules. Especially as you guys pretty much 
> redesigned that area in Ada 95 -- you essentially created a whole new 
> language design for it.

Not really.  Ada 83 had "forcing occurrences" regarding rep clauses.
And I think a bunch of similar rules regarding premature use
of private types.  IIRC, we decided that these two sets of rules
should be combined.  Also, the rules were buggy, and we wanted
to fix them.

The actual rules in Ada 95 are almost the same as in Ada 83.  They
don't look the same, because the wording was changed a lot.  But
the things that are legal and illegal in Ada 83 didn't change
much in Ada 95.

In other words:  Don't mix up "the Ada language" with "the words we
use to describe the Ada Language in the RM".  The latter can change
without changing the former.  And in this case, the latter changed
a lot while the former changed a little.

>... It makes me wonder how a language could be better 
> designed and not "have anything like freezing rules".

Well, I'm too lazy to give all the details, but here's one key point:

It is obvious[*] that module specs should not be elaborated.  They should
be purely a compile-time description of the interface, and should not
exist at all at run time.

[*] I'm just kidding about "obvious".  It took me years to figure that
out.  But having done so, it's obvious (to me).

Another point:  Something like Ada's aspect clauses are better than
pragmas and separate syntax for rep clauses.  That's because aspect
clauses are physically attached to the declaration, so there's less
of an issue about when things are evaluated.  Also, you don't have
to refer to the thing by name; you're just saying "this thing has
so an so properties".  Every time you refer to something by name,
you put a (slight) burden on the person reading the code, who has
to match up uses with declarations.

> After all, a compiler has to have a known representation for types and 
> objects at some point, certainly before code generation. If one is going to 
> support some sort of separate compilation (especially *safe* separate 
> compilation), freezing rules or something like them seems manditory. [There 
> is an argument to be made that a truly modern language doesn't need to 
> support separate compilation at the language level, given that it is now 
> practical to delay compilation until bind time. But that seems awfully 
> radical and would seem to put an upper limit on the sizes of programs that 
> could be written in the language. I don't think that's what you meant.]

No, that's not what I meant.

> Ada's freezing rules are far more detailed than absolutely necessary, but 
> the obvious way to get simplify them would be to require that all types are 
> declared before all objects (a-la Pascal) -- and we have evidence that's too 
> inflexible. There don't seem to be any obvious way to simplify them if 
> objects can be declared anywhere.

I hate that aspect of Pascal.  I wouldn't call Pascal a well-designed
language, although it is much better than many others in many respects.

> So I have to wonder what sort of "well-designed language" you have in mind.

Well, I gave some hints above.

- Bob

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

* Re: 'Protected' abstract subprograms
  2014-01-19 21:07                             ` Robert A Duff
@ 2014-01-20  8:40                               ` Dmitry A. Kazakov
  2014-01-21 14:37                                 ` Robert A Duff
  2014-01-21  1:21                               ` Randy Brukardt
  1 sibling, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-20  8:40 UTC (permalink / raw)


On Sun, 19 Jan 2014 16:07:41 -0500, Robert A Duff wrote:

> In other words:  Don't mix up "the Ada language" with "the words we
> use to describe the Ada Language in the RM".  The latter can change
> without changing the former.  And in this case, the latter changed
> a lot while the former changed a little.

Wow! (Remembering my discussions in c.l.a...)

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

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

* Re: 'Protected' abstract subprograms
  2014-01-19 21:07                             ` Robert A Duff
  2014-01-20  8:40                               ` Dmitry A. Kazakov
@ 2014-01-21  1:21                               ` Randy Brukardt
  2014-01-21 14:35                                 ` Robert A Duff
  1 sibling, 1 reply; 30+ messages in thread
From: Randy Brukardt @ 2014-01-21  1:21 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wccob37vfxe.fsf@shell01.TheWorld.com...
> "Randy Brukardt" <randy@rrsoftware.com> writes:
>
>> "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
>> news:wccvbxje5sn.fsf@shell01.TheWorld.com...
>> ...
>>> The freezing rules make my brain hurt.  Even though I had a hand in
>>> writing them!  ;-)
>>>
>>> A better-designed language would not have anything like freezing rules.
>>
>> That's a facinating assertion from the guy that's responsible for most 
>> the
>> AARM notes describing the freezing rules. Especially as you guys pretty 
>> much
>> redesigned that area in Ada 95 -- you essentially created a whole new
>> language design for it.
>
> Not really.  Ada 83 had "forcing occurrences" regarding rep clauses.
> And I think a bunch of similar rules regarding premature use
> of private types.  IIRC, we decided that these two sets of rules
> should be combined.  Also, the rules were buggy, and we wanted
> to fix them.
>
> The actual rules in Ada 95 are almost the same as in Ada 83.  They
> don't look the same, because the wording was changed a lot.  But
> the things that are legal and illegal in Ada 83 didn't change
> much in Ada 95.
>
> In other words:  Don't mix up "the Ada language" with "the words we
> use to describe the Ada Language in the RM".  The latter can change
> without changing the former.  And in this case, the latter changed
> a lot while the former changed a little.

Of course, I know this, but I don't really think that this is relevant. You 
("you" meaning Ada 9x team here since I don't know for sure who did what) 
could have changed the language more (since you guys had already decided to 
change the wording drastically), but you didn't. I would say that was mainly 
because it wasn't really possible to change the language further without 
changing it's philosphosy. After all, you did make a number of cases illegal 
that were legal in Ada 83.

>>... It makes me wonder how a language could be better
>> designed and not "have anything like freezing rules".
>
> Well, I'm too lazy to give all the details, but here's one key point:
>
> It is obvious[*] that module specs should not be elaborated.  They should
> be purely a compile-time description of the interface, and should not
> exist at all at run time.
>
> [*] I'm just kidding about "obvious".  It took me years to figure that
> out.  But having done so, it's obvious (to me).
>
> Another point:  Something like Ada's aspect clauses are better than
> pragmas and separate syntax for rep clauses.  That's because aspect
> clauses are physically attached to the declaration, so there's less
> of an issue about when things are evaluated.  Also, you don't have
> to refer to the thing by name; you're just saying "this thing has
> so an so properties".  Every time you refer to something by name,
> you put a (slight) burden on the person reading the code, who has
> to match up uses with declarations.

Right. Aspect clauses eliminate quite a bit of the need for freezing rules. 
(Although we ended up using them to describe the semantics of aspect 
clauses, that was mainly historical in nature -- it would have been better 
to wait until the end of the unit for those determinations, but that would 
have not allowed various things legal in Ada.)

I believe your point that a purely compile-time description would eliminate 
freezing. I'm not convinced that such a restriction would really be 
usable -- I suppose it depends on what could actually be described that way. 
(Personally, I find Ada interfaces useless; I much prefer package 
specifications for abstraction. I'm not sure if that carries over to your 
idea.)

Anyway, not particularly relevant for Ada, since we're surely not reducing 
what is allowed in a package specification.

                            Randy. 




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

* Re: 'Protected' abstract subprograms
  2014-01-21  1:21                               ` Randy Brukardt
@ 2014-01-21 14:35                                 ` Robert A Duff
  0 siblings, 0 replies; 30+ messages in thread
From: Robert A Duff @ 2014-01-21 14:35 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> Of course, I know this, but I don't really think that this is relevant. You 
> ("you" meaning Ada 9x team here since I don't know for sure who did what) 

I did most of the work on chapter 13.  I did the initial work on
freezing rules, and I think I'm responsible for the term "freezing".
We modified them over and over, trying to fix bugs, and trying to
clarify.  At some point, I got frustrated, and told Tucker I'm
sick of those rules, you (Tucker) please work on them, and I'll
finish up chapter 3 (which Tucker had been working on at the time).
So Tucker is responsible for the final wording of the freezing
rules in Ada 95.

> could have changed the language more (since you guys had already decided to 
> change the wording drastically), but you didn't. I would say that was mainly 
> because it wasn't really possible to change the language further without 
> changing it's philosphosy.

Not philosophy, so much as compatibility.

>...After all, you did make a number of cases illegal 
> that were legal in Ada 83.

Yes, but pretty obscure cases.  I don't remember the details, and I'm
too lazy to look them up, but I recall cases in Ada 83 where ARG had
ruled "X is legal" for some feature X.  But if you do X it's guaranteed
to raise an exception during elaboration (so for a library package, the
program is guaranteed to fail every time).  Also, in order to generate
correct code for X, the compiler has to KNOW that it's going to raise an
exception; otherwise it would generate code that would follow dangling
pointers and the like.

Clearly, making such an X illegal is an acceptable incompatibility.

> Right. Aspect clauses eliminate quite a bit of the need for freezing rules. 

Yeah, too bad they weren't invented in the late 1970's, in time for Ada 83.

> (Although we ended up using them to describe the semantics of aspect 
> clauses, that was mainly historical in nature -- it would have been better 
> to wait until the end of the unit for those determinations, but that would 
> have not allowed various things legal in Ada.)
>
> I believe your point that a purely compile-time description would eliminate 
> freezing. I'm not convinced that such a restriction would really be 
> usable -- I suppose it depends on what could actually be described that way. 

I'm convinced.  ;-)  In fact, my language design allows some useful things
that Ada does not.  For example, in Ada:

    package Sequences is
        type Sequence is private;
        function Make_Sequence(Length: Natural) return Sequence;
        Empty_Sequence : constant := Make_Sequence(Length => 0); -- Wrong!
        ...
    private
        ...
    end Sequences;

That won't work, and it's annoying.  In my language, it works fine,
because Make_Sequence is called during elaboration of the BODY of Sequences.

But that's not Ada, and it's not even possible to compatibly change
Ada in this way, so I should stop talking about off-topic stuff.  ;-)

> (Personally, I find Ada interfaces useless; I much prefer package 
> specifications for abstraction. I'm not sure if that carries over to your 
> idea.)
> 
> Anyway, not particularly relevant for Ada, since we're surely not reducing 
> what is allowed in a package specification.

In any case, you're right that SOME sort of rules are needed.  You need
to prevent circular things like X is of type T, and the Size of T
depends on the value of X.  I just don't think it needs to be
anywhere near as complicated as the freezing rules.

- Bob


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

* Re: 'Protected' abstract subprograms
  2014-01-20  8:40                               ` Dmitry A. Kazakov
@ 2014-01-21 14:37                                 ` Robert A Duff
  2014-01-22  8:27                                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Robert A Duff @ 2014-01-21 14:37 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Sun, 19 Jan 2014 16:07:41 -0500, Robert A Duff wrote:
>
>> In other words:  Don't mix up "the Ada language" with "the words we
>> use to describe the Ada Language in the RM".  The latter can change
>> without changing the former.  And in this case, the latter changed
>> a lot while the former changed a little.
>
> Wow! (Remembering my discussions in c.l.a...)

Well, please don't interpret my words above as saying one should
use the Humpty-Dumpty style.  ;-)

- Bob


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

* Re: 'Protected' abstract subprograms
  2014-01-21 14:37                                 ` Robert A Duff
@ 2014-01-22  8:27                                   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-22  8:27 UTC (permalink / raw)


On Tue, 21 Jan 2014 09:37:51 -0500, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Sun, 19 Jan 2014 16:07:41 -0500, Robert A Duff wrote:
>>
>>> In other words:  Don't mix up "the Ada language" with "the words we
>>> use to describe the Ada Language in the RM".  The latter can change
>>> without changing the former.  And in this case, the latter changed
>>> a lot while the former changed a little.
>>
>> Wow! (Remembering my discussions in c.l.a...)
> 
> Well, please don't interpret my words above as saying one should
> use the Humpty-Dumpty style.  ;-)

Surely the true "Ada language" is revealed only through mystical experience
of selected individuals. That is the point, right? (:-))

Anyway it is a little step forward from the attitude that anything not
found in the holly script is wrong, a heresy already... (:-))

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

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

end of thread, other threads:[~2014-01-22  8:27 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-10 22:00 'Protected' abstract subprograms sbelmont700
2014-01-10 22:30 ` Randy Brukardt
2014-01-11 16:12   ` sbelmont700
2014-01-14  3:45     ` Randy Brukardt
2014-01-14  9:05       ` Dmitry A. Kazakov
2014-01-15  0:36         ` Randy Brukardt
2014-01-15  9:17           ` Dmitry A. Kazakov
2014-01-15 14:11             ` Robert A Duff
2014-01-15 15:40               ` adambeneschan
2014-01-15 21:21                 ` Robert A Duff
2014-01-15 23:10                   ` Randy Brukardt
2014-01-16  0:51                     ` Robert A Duff
2014-01-16 10:43                       ` AdaMagica
2014-01-16 16:32                         ` adambeneschan
2014-01-17  1:49                         ` Robert A Duff
2014-01-17 23:23                           ` Randy Brukardt
2014-01-19 21:07                             ` Robert A Duff
2014-01-20  8:40                               ` Dmitry A. Kazakov
2014-01-21 14:37                                 ` Robert A Duff
2014-01-22  8:27                                   ` Dmitry A. Kazakov
2014-01-21  1:21                               ` Randy Brukardt
2014-01-21 14:35                                 ` Robert A Duff
2014-01-15 23:17               ` Randy Brukardt
2014-01-16  8:52               ` Dmitry A. Kazakov
2014-01-11  8:41 ` J-P. Rosen
2014-01-11  8:59 ` Dmitry A. Kazakov
2014-01-11 13:42   ` Niklas Holsti
2014-01-11 19:35     ` Dmitry A. Kazakov
2014-01-12  9:19       ` Niklas Holsti
2014-01-12 10:22         ` Dmitry A. Kazakov

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