comp.lang.ada
 help / color / mirror / Atom feed
* using interface types: guru assistance begged
@ 2006-07-06 15:20 (see below)
  2006-07-06 22:50 ` Randy Brukardt
  0 siblings, 1 reply; 3+ messages in thread
From: (see below) @ 2006-07-06 15:20 UTC (permalink / raw)


I am trying to learn how to use Ada 2005's interface types,
using GNAT GPL 2006 on MacOS X,
with an example along the following lines (much trimmed):

generic
   type a_member_type is (<>);
package generic_sets_interface is

   type a_set is interface;

   function is_empty (trial_set : a_set) return Boolean is abstract;
   pragma Inline(is_empty);
   
   function empty_set return a_set is abstract;
   pragma Inline(empty_set);
   
   function bit (candidate : a_member_type) return a_word_set;
   pragma Inline (bit);
...
end generic_sets_interface;

......

with generic_sets_interface;
generic
   type a_basis_type  is mod <>;
   type a_member_type is (<>);
package generic_word_masks is

   package generic_word_masks_interface is new
generic_sets_interface(a_member_type);
      
   type a_set is new generic_word_masks_interface.a_set with private;

   function is_empty (trial_set : a_word_set) return Boolean;
   pragma Inline(is_empty);
   
   function empty_set return a_word_set;
   pragma Inline(empty_set);
...
private
   type a_word_set is new generic_word_masks_interface.a_set with
      record
         basis : a_basis_type;
      end record;
end generic_word_masks;

......

package body generic_word_masks is

   function shift_right (v : a_basis_type; amount : Natural) return
a_basis_type;
   pragma Import(Convention => Intrinsic,  Entity => shift_right);

   empty_basis : constant a_basis_type := 0;
   
   function is_empty (trial_set : a_word_set) return Boolean is
   begin
      return (trial_set.basis = empty_basis);
   end is_empty;
   
   function empty_set return a_word_set is
   begin
      return a_word_set'(basis => empty_basis);
   end empty_set;
 
   function bit (candidate : a_member_type) return a_word_set is
   begin
      return a_word_set'(basis => shift_left(1,
Natural(a_member_type'Pos(candidate))));
   end bit;
...
end generic_word_masks ;


As written this compiles and runs correctly.
However, I would prefer the derivation of a_word_set to be private, thus:

private with generic_sets_interface;
generic
   type a_basis_type  is mod <>;
   type a_member_type is (<>);
package generic_word_masks is

   type a_word_set is private;
   
   function is_empty (trial_set : a_word_set) return Boolean;
   pragma Inline(is_empty);
   
   function empty_set return a_word_set;
   pragma Inline(empty_set);
...
private
   package generic_word_masks_interface is new
generic_sets_interface(a_member_type);
   
   type a_word_set is new generic_word_masks_interface.a_set with
      record
         basis : a_basis_type;
      end record;
end generic_word_masks;

But when I do this, the instantiation in my test program fails, thus:

           type i32 is mod 2**32;
           type fivetrack is range 0..31;
    13.    package word_masks_32 is new generic_word_masks(i32, fivetrack);
           |
        >>> instantiation error at generic_word_masks.ads:76
        >>> type must be declared abstract or "is_empty" overridden
        >>> "is_empty" has been inherited at generic_word_masks.ads:76,
instance at line 13
        >>> "is_empty" has been inherited from subprogram at
generic_sets_interface.ads:13, instance at generic_word_masks.ads:74,
instance at line 13
        >>> instantiation error at generic_word_masks.ads:76
        >>> type must be declared abstract or "empty_set" overridden
        >>> "empty_set" has been inherited at generic_word_masks.ads:76,
instance at line 13
        >>> "empty_set" has been inherited from subprogram at
generic_sets_interface.ads:16, instance at generic_word_masks.ads:74,
instance at line 13

And so on, for all of the subprograms declared in generic_word_masks.
Can anyone tell me what I am doing wrong here, and whether there is
any way to achieve the desired information hiding?

With thanks.
-- 
Bill Findlay
<surname><forename> chez blueyonder.co.uk





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

* Re: using interface types: guru assistance begged
  2006-07-06 15:20 using interface types: guru assistance begged (see below)
@ 2006-07-06 22:50 ` Randy Brukardt
  0 siblings, 0 replies; 3+ messages in thread
From: Randy Brukardt @ 2006-07-06 22:50 UTC (permalink / raw)


"(see below)" <yaldnif.w@blueyonder.co.uk> wrote in message
news:C0D2E8C5.586FF%yaldnif.w@blueyonder.co.uk...
> I am trying to learn how to use Ada 2005's interface types,
> using GNAT GPL 2006 on MacOS X,
> with an example along the following lines (much trimmed):
...
> As written this compiles and runs correctly.

If it does, I'd be amazed. You define something called "a_set", and then a
bit later do various operations on "a_word_set" which is never defined
anywhere. My original guess was that you forgot to change some names. But
then, you define an operation returning "a_word_set":
function bit (candidate : a_member_type) return a_word_set;
which is not abstract. So if "a_word_set" was changed to "a_set", this would
be illegal. At this point, I gave up; that's only the first package and a
quick glance at the others doesn't make it any clearer. Please repost your
code that really does compile...

Even so, I can give you a very quick answer:

> However, I would prefer the derivation of a_word_set to be private, thus:
...
> And so on, for all of the subprograms declared in generic_word_masks.
> Can anyone tell me what I am doing wrong here, and whether there is
> any way to achieve the desired information hiding?

I didn't look at the error messages; probably you need to make sure that you
are declaring an abstract type in the instance.

But in any case, the quick answer is no. Ada 2005 requires that interfaces
are never hidden. The way interfaces work is that they are a property of a
type: either it has that interface property or it does not. In particular,
it is not possible for a type to have the same interface twice.

But, if you could hide interfaces, you'd have to break privacy by looking
into the private part in order to determine whether it was OK to add an
interface to the type. (If you didn't do that, you could add the same
interface twice, with different operations defined each time. Then, if
dispatched on Interface'Class(), which operation would be called? It would
be very hard to tell.)

So Ada 2005 does not allow hiding of interfaces; all of the interfaces used
in the full view also have to be used on the private view. (They don't
necessarily have to have the same names, just the same set of interfaces.)

Rules of thumb:
   * If you need hiding, use abstract tagged types;
   * If you need concrete operations or components in the root type, use
abstract tagged types;
   * If you need multiple inheritance (more than one parent), use
interfaces;
   * If you need to complete the type with tasks or protected types, use
interfaces;
   * If you need to do a combination of the above, you're s**t out of luck.
;-)

                         Randy.





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

* Re: using interface types: guru assistance begged
@ 2006-07-07 17:54 (see below)
  0 siblings, 0 replies; 3+ messages in thread
From: (see below) @ 2006-07-07 17:54 UTC (permalink / raw)


On 6/7/06 23:50, in article lqqdnR6QtY_nDjDZnZ2dnUVZ_oadnZ2d@megapath.net,
"Randy Brukardt" <randy@rrsoftware.com> wrote:

>> As written this compiles and runs correctly.
> 
> If it does, I'd be amazed. You define something called "a_set", and then a
> bit later do various operations on "a_word_set" which is never defined
> anywhere. My original guess was that you forgot to change some names.

Oops, sorry, yes - I must have copied from an out-of-date editor window. 8-(
(The consistent code *does* compile & run correctly.)

> But in any case, the quick answer is no.
...
> But, if you could hide interfaces, you'd have to break privacy by looking
> into the private part in order to determine whether it was OK to add an
> interface to the type. (If you didn't do that, you could add the same
> interface twice, with different operations defined each time. Then, if
> dispatched on Interface'Class(), which operation would be called? It would
> be very hard to tell.)

Right. I see that (I think 8-).

> So Ada 2005 does not allow hiding of interfaces; all of the interfaces used
> in the full view also have to be used on the private view. (They don't
> necessarily have to have the same names, just the same set of interfaces.)
> 
> Rules of thumb:
...

OK. That's very illuminating.
Many thanks for the comprehensive tutorial.

-- 
Bill Findlay
<surname><forename> chez blueyonder.co.uk





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

end of thread, other threads:[~2006-07-07 17:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-06 15:20 using interface types: guru assistance begged (see below)
2006-07-06 22:50 ` Randy Brukardt
  -- strict thread matches above, loose matches on Subject: below --
2006-07-07 17:54 (see below)

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