comp.lang.ada
 help / color / mirror / Atom feed
* Isomorphic variant question
@ 1993-01-15 20:38 John Bollenbacher
  0 siblings, 0 replies; 3+ messages in thread
From: John Bollenbacher @ 1993-01-15 20:38 UTC (permalink / raw)


I often find myself with the following coding dilemma and would appreciate
any insights.

We build systems in which we use mail as our major inter-task communication
mechanism.  In general, the mail type takes the form of variant records.
>From time to time, we end up declaring such mail wherein more than one
discriminant has the same variants associated with it.  For example:

  type SHAPES is (CIRCLE, SQUARE, RECTANGLE);

  type SHAPE(KIND : SHAPES := SHAPES'FIRST) is record
    case KIND is
      when CIRCLE | SQUARE =>
        CENTER : CORRDINATES;
        RADIUS : UNITS;
      when ...
    end case;
  end record;

In the construction of a given piece of mail, we like to use aggregates to
ensure that any changes in mail declarations will result in the compiler
telling us what needs to change. 

So far so good.  My recurring problem arises when I have a code fragment
which is responsible for building such a piece of mail which does not need
to distinguish between these isomorphich variants (CIRCLE and SQUARE in
this case).  Due to the fact that discriminants in aggregates which control the
existence of variant fields must be static, I find myself unable to write 
straightforward code which reflects the fact that the fragment does not care 
about the specific value.

The three approaches I have come up with (and their perceived shortcomings) are
:

1. Duplicate the aggregates (Disadvantage: all of the disadvantages which 
accrue to duplicate code, in general):

  procedure POST(KIND : SHAPES) is
  begin
    case KIND is
      when CIRCLE =>
        SEND((KIND   => CIRCLE,
              CENTER => CENTER_OF_OBJECT,
              RADIUS => RADIUS_OF_OBJECT));              
      when SQUARE =>
        SEND((KIND   => SQUARE,
              CENTER => CENTER_OF_OBJECT,
              RADIUS => RADIUS_OF_OBJECT));              
       ...

2. Declare the object uninitialized and fill in the fields without an
aggregate (Disadvantage: future modifications to the mail type will not be
caught by the compiler):

   procedure POST(KIND : SHAPES) is
     MAIL : SHAPE(KIND);
   begin
     case KIND is
       when CIRCLE | SQUARE =>
         MAIL.CENTER := CENTER_OF_OBJECT;
         MAIL.RADIUS := RADIUS_OF_OBJECT;
         SEND(MAIL);
       ...

3. Declare a 'temporary' repository with an arbitrary discriminant and
initialize it with an aggregate.  Then declare the real object and fill in
the fields individually from the temporary object.  (Disadvantage: extra
copying required; a little unclear to future maintainers):

  procedure POST(KIND : SHAPE) is
    MAIL : SHAPE(KIND);
  begin
    case KIND is
      when CIRCLE | SQUARE =>
        declare
          TMP : constant SHAPE := (
            KIND   => CIRCLE,
            CENTER => CENTER_OF_OBJECT,
            RADIUS => RADIUS_OF_OBJECT);
        begin
          MAIL.CENTER := TMP.CENTER;
          MAIL.RADIUS := TMP.RADIUS;
          ...

Any comments or suggestions would be appreciated.


--
-----------------------------------------------------------------------------
- John Bollenbacher                                        jhb@dale.cts.com -
- Titan Linkabit Corp.                                       (619) 552-9963 -
- 3033 Science Park Rd.                                                     -
- San Diego, Ca. 92121                                                      -
-----------------------------------------------------------------------------

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

* Isomorphic variant question
@ 1993-01-20 23:56 John Bollenbacher
  0 siblings, 0 replies; 3+ messages in thread
From: John Bollenbacher @ 1993-01-20 23:56 UTC (permalink / raw)


I often find myself with the following coding dilemma and would appreciate
any insights.

We build systems in which we use mail as our major inter-task communication
mechanism.  In general, the mail type takes the form of variant records.
>From time to time, we end up declaring such mail wherein more than one
discriminant has the same variants associated with it.  For example:

  type SHAPES is (CIRCLE, SQUARE, RECTANGLE);

  type SHAPE(KIND : SHAPES := SHAPES'FIRST) is record
    case KIND is
      when CIRCLE | SQUARE =>
        CENTER : CORRDINATES;
        RADIUS : UNITS;
      when ...
    end case;
  end record;

In the construction of a given piece of mail, we like to use aggregates to
ensure that any changes in mail declarations will result in the compiler
telling us what needs to change. 

So far so good.  My recurring problem arises when I have a code fragment
which is responsible for building such a piece of mail which does not need
to distinguish between these isomorphich variants (CIRCLE and SQUARE in
this case).  Due to the fact that discriminants in aggregates which control the
existence of variant fields must be static, I find myself unable to write 
straightforward code which reflects the fact that the fragment does not care 
about the specific value.

The three approaches I have come up with (and their perceived shortcomings) are
:

1. Duplicate the aggregates (Disadvantage: all of the disadvantages which 
accrue to duplicate code, in general):

  procedure POST(KIND : SHAPES) is
  begin
    case KIND is
      when CIRCLE =>
        SEND((KIND   => CIRCLE,
              CENTER => CENTER_OF_OBJECT,
              RADIUS => RADIUS_OF_OBJECT));              
      when SQUARE =>
        SEND((KIND   => SQUARE,
              CENTER => CENTER_OF_OBJECT,
              RADIUS => RADIUS_OF_OBJECT));              
       ...

2. Declare the object uninitialized and fill in the fields without an
aggregate (Disadvantage: future modifications to the mail type will not be
caught by the compiler):

   procedure POST(KIND : SHAPES) is
     MAIL : SHAPE(KIND);
   begin
     case KIND is
       when CIRCLE | SQUARE =>
         MAIL.CENTER := CENTER_OF_OBJECT;
         MAIL.RADIUS := RADIUS_OF_OBJECT;
         SEND(MAIL);
       ...

3. Declare a 'temporary' repository with an arbitrary discriminant and
initialize it with an aggregate.  Then declare the real object and fill in
the fields individually from the temporary object.  (Disadvantage: extra
copying required; a little unclear to future maintainers):

  procedure POST(KIND : SHAPE) is
    MAIL : SHAPE(KIND);
  begin
    case KIND is
      when CIRCLE | SQUARE =>
        declare
          TMP : constant SHAPE := (
            KIND   => CIRCLE,
            CENTER => CENTER_OF_OBJECT,
            RADIUS => RADIUS_OF_OBJECT);
        begin
          MAIL.CENTER := TMP.CENTER;
          MAIL.RADIUS := TMP.RADIUS;
          ...

Any comments or suggestions would be appreciated.


--
-----------------------------------------------------------------------------
- John Bollenbacher                                        jhb@dale.cts.com -
- Titan Linkabit Corp.                                       (619) 552-9963 -
- 3033 Science Park Rd.                                                     -
- San Diego, Ca. 92121                                                      -
-----------------------------------------------------------------------------

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

* Re: Isomorphic variant question
@ 1993-01-22  1:00 Alex Blakemore
  0 siblings, 0 replies; 3+ messages in thread
From: Alex Blakemore @ 1993-01-22  1:00 UTC (permalink / raw)


In article <C16FuD.E5L@dale.cts.com> jhb@dale.cts.com (John Bollenbacher) write
s:
> So far so good.  My recurring problem arises when I have a code fragment
> which is responsible for building such a piece of mail which does not need
> to distinguish between these isomorphich variants

   procedure POST(KIND : SHAPES) is
   begin
     case KIND is
       when CIRCLE | SQUARE =>
         SEND((KIND   => KIND,
               CENTER => CENTER_OF_OBJECT,
               RADIUS => RADIUS_OF_OBJECT));              




-- 
---------------------------------------------------
Alex Blakemore alex@cs.umd.edu   NeXT mail accepted

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

end of thread, other threads:[~1993-01-22  1:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1993-01-20 23:56 Isomorphic variant question John Bollenbacher
  -- strict thread matches above, loose matches on Subject: below --
1993-01-22  1:00 Alex Blakemore
1993-01-15 20:38 John Bollenbacher

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