comp.lang.ada
 help / color / mirror / Atom feed
From: matthew_heaney@acm.org (Matthew Heaney)
Subject: Re: How to Use Abstract Data Types
Date: 1998/05/05
Date: 1998-05-05T00:00:00+00:00	[thread overview]
Message-ID: <matthew_heaney-ya023680000505981941000001@news.ni.net> (raw)
In-Reply-To: 354F5C4D.DFF8286E@gsfc.nasa.gov


In article <354F5C4D.DFF8286E@gsfc.nasa.gov>, Stephen Leake
<stephen.leake@gsfc.nasa.gov> wrote:

(start of quote)
I like this technique, too, but one problem I have with it is it assumes
read-write access to the Library. Suppose I want to implement Find:

function Find (Title : in String; Library : in My_Library) return Book'class
is
    Iterator : Library_Iterator (Library'access); -- illegal
begin
    ...
end Find;

Since the Library parameter is "in", you cannot use it as the access
discriminant.
(end of quote)

If you're using GNAT, then you can use the Unrestricted_Access attribute, ie

   Iter : Lib_Iter (Lib'Unrestricted_Access);
begin
...

This gives you the ability to make state changes behind the scenes (or,
here, supply an in param as an actual discriminant), even though the object
is publically read-only.  (In Meyer's terminology, you change the
"concrete" state without changing the "abstract" state.)

C++ programmers take this ability for granted, because you can "cast away
const."  It's a bummer you can't do that portably in Ada 95.  Oh, well. 
Maybe some programmer will write another article in JOOP explaining that we
need to "extend the syntax" of Ada 95...


(start of quote)
The only way around this (that I have found) is to restructure
Find to be a procedure, with Library "in out" and the Book result as an "out"
parameter.
(end of quote)

Not necessarily.  You can keep the functional form by making library an
access parameter:

fuction Find (Title : String; Lib : access My_Lib) return Book'Class is
  Iter : Lib_Iter (Lib);
begin
   ...

Now the code is completely portable too.

Yes, it seems like  a bummer that I should have to make a param in out or
access, even though it's read-only.  But this is just a "feature" of the
language.

(start of quote)
With the generic package iterator:
   generic
      type Some_Library is new Library with private;
      This_Library: in  Some_Library;
   package Iterator is
      function More return Boolean;
      function Next return Book'Class;
   end Iterator;

"This_Library" is now read-only.
(end of quote)

I haven't played around with generic packages as iterators - though I have
imported iterators as a generic formal parameter.  See my follow-up post
that answers Adam's questions.

(start of quote)
Is there a good way to get read-only access with Iterator_Type?
(end of quote)

Non-portable way (GNAT only): yes, using O'Unrestricted_Access.

Portable way: no.   You have to either pass the param as an access param
(works for any kind of type, even non-tagged types) or as in out (works for
tagged types only).




  reply	other threads:[~1998-05-05  0:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-04-22  0:00 How to Use Abstract Data Types adam
1998-04-23  0:00 ` Jacob Sparre Andersen
1998-04-30  0:00 ` Robert I. Eachus
     [not found]   ` <matthew_heaney-ya023680003004981709380001@news.ni.net>
1998-05-05  0:00     ` Stephen Leake
1998-05-05  0:00       ` Matthew Heaney [this message]
1998-05-06  0:00         ` Stephen Leake
  -- strict thread matches above, loose matches on Subject: below --
1998-04-30  0:00 adam
1998-05-06  0:00 ` Robert I. Eachus
1998-05-04  0:00 adam
1998-05-06  0:00 ` Robert I. Eachus
replies disabled

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