comp.lang.ada
 help / color / mirror / Atom feed
From: Maciej Sobczak <see.my.homepage@gmail.com>
Subject: Proper program structure
Date: Wed, 30 Sep 2009 14:25:57 -0700 (PDT)
Date: 2009-09-30T14:25:57-07:00	[thread overview]
Message-ID: <638d582c-f275-48a9-aa2a-237f2edd123c@c37g2000yqi.googlegroups.com> (raw)

First, thank you all for the replies to my previous questions.
But I have more. :-)

Consider the following example. It is imaginary, but shows the actual
problem, even though the analogy is not always exact.

package Cars is
   type Car (<>) is limited private;
   ...
private
   type Car is limited record
      Body : ...
      Engine : ...
      Gear_Box : ...
      Wheels : ...
   end record;

Note: in the actual project some of the components need to know about
the others, but the "links" are always acyclic.

To keep the sizes of all packages at a reasonable volume I decided to
define each type in a separate package.
The following shows the history of failures:

1. Some of the components of the car make sense in isolation and can
be reused in other contexts, but some might be tied to the project
with no chance for any reuse. Intuitively I thought they could be
defined in private children of the Cars package (private means that
users of Car will not use them by mistake and children to physically
reflect the hierarchy). This is not possible, because the Cars package
would need to "with" these private children packages and that
introduces cyclic dependencies. Too bad.

2. Defining them in non-child packages means that they cannot see the
complete structure of the Car and therefore they cannot be "wired" by
discriminants like here:

   -- wrong:
   type Car is limited record
      Body : Body_Type (Car'Access);
      Engine : Engire_Type (Car'Access);
      -- and so on

3. So they have to be wired individually, but discriminants will still
not work, as sibling components of the same record cannot be used to
constrain each other:

   -- wrong:
   type Car is limited record
      Gear_Box : aliased Gear_Box_Type;
      Engine : Engire_Type (Gear_Box'Access);
      -- and so on

4. So they have to be wired individually by some initialization
subprogram, presumably the Car's constructor function (because Car has
a constructor function).
There are two ways of doing it:

4a. By defining some Init procedure for each component type, which
will establish the links. This means that all components are aliased
and the Car's constructor function needs to call Init for each
component and provide proper links to dependent components. I don't
like the idea of having two-phase initialization and 'Unchecked_Access
all over the shop, so this solution just sucks.

4b. By allocating all components dynamically and keeping them by
access values. They can be allocated in the proper order with proper
links to other components provided at the allocation time (there are
no cycles, so there is always some proper order to do this), but then
it does not look like a composition anymore and it is essentially
"Java in Ada".

In other words, all the solutions I can think of are either illegal or
crappy.
Am I over-sensitive or did I really hit a design problem?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



             reply	other threads:[~2009-09-30 21:25 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-30 21:25 Maciej Sobczak [this message]
2009-09-30 22:16 ` Proper program structure Robert A Duff
2009-10-01  7:13   ` Maciej Sobczak
2009-09-30 23:43 ` Adam Beneschan
2009-10-01  7:35   ` Maciej Sobczak
2009-10-01  6:34 ` Brad Moore
2009-10-01  7:44   ` Maciej Sobczak
2009-10-01  9:39   ` Maciej Sobczak
2009-10-01 15:36     ` Brad Moore
2009-10-01 20:01       ` Maciej Sobczak
2009-10-02  5:44         ` Brad Moore
2009-10-02 13:10           ` Brad Moore
2009-10-01  8:08 ` Dmitry A. Kazakov
replies disabled

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