* Re: Mutual distrust
@ 1991-07-10 22:17 cis.ohio-state.edu!magnus.acs.ohio-state.edu!zaphod.mps.ohio-state.edu!ho
0 siblings, 0 replies; 2+ messages in thread
From: cis.ohio-state.edu!magnus.acs.ohio-state.edu!zaphod.mps.ohio-state.edu!ho @ 1991-07-10 22:17 UTC (permalink / raw)
>From article <EACHUS.91Jul10150645@largo.mitre.org>,
by eachus@largo.mitre.org (Robert I. Eachus):
>
> 2) Take advantage of the simplifying factor, which allows the following
> package dependancy to be established...
>
> This is the solution I ended up using, but I don't like the assymetry
> of it, and I don't like what I have to do to it to allow OCCUPANT to
> return a set of people instead of a single PERSON.
>
> -- What's the problem? ...
The problem turns out to have been a classic Ada problem -- I was casually
equating the concepts of package and abstract data type. Someone kindly
pointed this out to me by E-mail, and everything fell into place.
What I did was have the package POPULATION export both PERSON and PEOPLE,
where PEOPLE is an abstract set of PERSON. The type PEOPLE is quite
handy within POPULATION, it is the type returned by OCCUPANT( PLACE ),
and it is reasonable to implement it by renaming a generic instantiation
of a set or list package within POPULATION.
Making the set of people in a separate package from POPULATION that
depends on POPULATION was clearly wrong, and my casual equation of
package with abstract data type prevented me from seeing that both the
singular and set types should be exported from the same package.
Doug Jones
jones@cs.uiowa.edu
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Mutual distrust
@ 1991-07-10 22:06 Robert I. Eachus
0 siblings, 0 replies; 2+ messages in thread
From: Robert I. Eachus @ 1991-07-10 22:06 UTC (permalink / raw)
In article <6883@ns-mx.uiowa.edu> jones@pyrite.cs.uiowa.edu (Douglas W. Jones,2
01H MLH,3193350740,3193382879) writes:
Here's a problem I've come up against in designing a simulation
program voluntarily written in Ada... The problem: Each PLACE must
have an associated set of people who occupy that PLACE, and each
PERSON must know what place he (or she) is in and what other people
occupy that same place. This implies a cyclic relationship between
the packages GEOGRAPHY and POPULATION.
The one simplifying factor is that there is only one place in which it is
necessary for the PLACE occupied by a PERSON to be known, and that is
inside the action routines applied to that particular PERSON, which are
inside POPULATION.
Here are the possible solutions I thought up:
1) Add a third package -- something of a relational package that associates
people with places, so that given a PLACE it can supply the set of all
people there, and given a PERSON, it can tell what PLACE that person
occupies.
This has the advantage of allowing GEOGRAPHY and POPULATION to be
completely independant, but because PERSON and PLACE are private
types, there is no way I can think of to efficiently implement this
third package.
-- There is an easy way to do this using the Tucker Taft amendment,
-- which allows an incomplete type declaration in a private part to be
-- completed in the body of the package...
package POPULATION is
type PERSON is private;
-- operrations on PERSONs not explicitly involving PLACEs.
...
private
type PERSON_RECORD;
type PERSON is access PERSON_RECORD;
end POPULATION;
package GEOGRAPHY is
type PLACE is private;
-- operations on PLACEs not explicitly involving people.
...
private
type PLACE_RECORD is private;
type PLACE is access PLACE_RECORD;
end GEOGRAPHY;
with POPULATION; with GEOGRAPHY;
package PEOPLE_AND_PLACES is
-- operations involving both people and places...
end PEOPLE_AND_PLACES;
with POPULATION; with GEOGRAPHY;
package HIDDEN is
type REAL_PERSON is record...
type REAL_PLACE is record...
function GET_REAL(P: in POPULATION.PERSON) return REAL_PERSON;
function GET_REAL(P: in GEOGRAPHY.PLACE) return REAL_PLACE;
end HIDDEN;
with UNCHECKED_CONVERSION;
package body HIDDEN is
type PERSON_POINTER is access REAL_PERSON;
function CONVERT is new UNCHECKED_CONVERSION
(POPULATION.PERSON, PERSON_POINTER);
function GET_REAL(P: in POPULATION.PERSON) return REAL_PERSON is
begin return CONVERT(P); end GET_REAL;
-- do the same for PLACEs
...
end HIDDEN;
with HIDDEN;
package body GEOGRAPHY is
type PLACE_RECORD is new HIDDEN.REAL_PLACE;
-- Now you can see the actual record declarations in POPULATION,
-- GEOGRAPHY, and PEOPLE_AND_PLACES (assuming that these bodies and
-- only these bodies say with HIDDEN. Revising either of the record
-- structures will require recompiling the bodies of all three
-- packages but you would have to recomile two of them anyway.
-- However, the only specification which requires recompilation is
-- that for HIDDEN.
-- I usually only advocate packages like HIDDEN as a way of
-- minimizing recompilations, but sometimes it has other advantages.
2) Take advantage of the simplifying factor, which allows the following
package dependancy to be established...
This is the solution I ended up using, but I don't like the assymetry
of it, and I don't like what I have to do to it to allow OCCUPANT to
return a set of people instead of a single PERSON.
-- What's the problem? Have two functions one, call it COUNT,
-- returns the number of residents and the other, OCCUPANTS, returns an
-- array of PERSONs. The loop which processes this may have to use a
-- different trick... Let's say that POPULATION.PEOPLE is an array
-- (POSITIVE range <>) of PERSON.
loop
SOMEPLACE := ...
-- get next location
declare
SOMEPEOPLE: constant POPULATION.PEOPLE :=
OCCUPANTS(SOMEPLACE);
begin
for I in SOMEPEOPLE'RANGE loop
PROCESS(SOMEPEOPLE(I));
end loop;
end;
end loop;
-- The constant keyword is the magic cookie which allows you to
-- declare SOMEPEOPLE without supplying the range. Since PERSON is an
-- access type, PROCESS is allowed to change fields of the various
-- records but not to assign a new access value to SOMEPEOPLE(I).
--
Robert I. Eachus
with STANDARD_DISCLAIMER;
use STANDARD_DISCLAIMER;
function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~1991-07-10 22:17 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1991-07-10 22:17 Mutual distrust cis.ohio-state.edu!magnus.acs.ohio-state.edu!zaphod.mps.ohio-state.edu!ho
-- strict thread matches above, loose matches on Subject: below --
1991-07-10 22:06 Robert I. Eachus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox