comp.lang.ada
 help / color / mirror / Atom feed
* Record type with check?
@ 2001-01-09  8:12 Matthias Teege
  2001-01-09 16:37 ` Florian Weimer
  2001-01-09 22:12 ` Stephen Leake
  0 siblings, 2 replies; 8+ messages in thread
From: Matthias Teege @ 2001-01-09  8:12 UTC (permalink / raw)



Moin,

ist there any way to build a record type like this: 

type Datum is
   record
      Var_A  : Integer;
      Var_B  : Integer;
   end record;

which guarantees that Var_B is bigger than Var_A?

Many thanks
Matthias



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

* Re: Record type with check?
  2001-01-09  8:12 Record type with check? Matthias Teege
@ 2001-01-09 16:37 ` Florian Weimer
  2001-01-09 22:12 ` Stephen Leake
  1 sibling, 0 replies; 8+ messages in thread
From: Florian Weimer @ 2001-01-09 16:37 UTC (permalink / raw)


Matthias Teege <matthias@mteege.de> writes:

> ist there any way to build a record type like this: 
> 
> type Datum is
>    record
>       Var_A  : Integer;
>       Var_B  : Integer;
>    end record;
> 
> which guarantees that Var_B is bigger than Var_A?

No, I don't think there is.

Of course, you can 'Datum' a private type and use get/set subprograms
to access 'Var_A' and 'Var_B', but that's probably not what you are
asking for.



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

* Re: Record type with check?
  2001-01-09  8:12 Record type with check? Matthias Teege
  2001-01-09 16:37 ` Florian Weimer
@ 2001-01-09 22:12 ` Stephen Leake
  2001-01-10  7:47   ` Matthias Teege
  1 sibling, 1 reply; 8+ messages in thread
From: Stephen Leake @ 2001-01-09 22:12 UTC (permalink / raw)


Matthias Teege <matthias@mteege.de> writes:

> Moin,
> 
> ist there any way to build a record type like this: 
> 
> type Datum is
>    record
>       Var_A  : Integer;
>       Var_B  : Integer;
>    end record;
> 
> which guarantees that Var_B is bigger than Var_A?

This sounds like a homework problem, so I'll only give hints. If it's
not homework, please reply with more info on why you need this.

You cannot simply declare a type that has this property. But you can
write a package that declares an abstract data type that does enforce
this property. It must have a Create procedure that checks that A < B,
and access procedures that let clients access A and B.

-- 
-- Stephe



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

* Re: Record type with check?
  2001-01-09 22:12 ` Stephen Leake
@ 2001-01-10  7:47   ` Matthias Teege
  2001-01-10 17:05     ` Nick Roberts
  2001-01-10 21:41     ` Robert Dewar
  0 siblings, 2 replies; 8+ messages in thread
From: Matthias Teege @ 2001-01-10  7:47 UTC (permalink / raw)


Stephen Leake <stephen.a.leake.1@gsfc.nasa.gov> writes:

> Matthias Teege <matthias@mteege.de> writes:
> 
> > Moin,
> > 
> > ist there any way to build a record type like this: 
> > 
> > type Datum is
> >    record
> >       Var_A  : Integer;
> >       Var_B  : Integer;
> >    end record;
> > 
> > which guarantees that Var_B is bigger than Var_A?
> 
> This sounds like a homework problem, so I'll only give hints. If it's
> not homework, please reply with more info on why you need this.

No it isn't a homework (see http://www.mteege.de/index_en.html) 
but your assumption describe my knowledge level very
well. ;-) Learning Ada is only a hobby. 

The type should represent ranges from Var_A to Var_B and
associate Var_C with this range. Somthing like this:

Var_A  Var_B  Var_C
 1      2      10
 2      4      12
 4      7      13
..

> You cannot simply declare a type that has this property. But you can
> write a package that declares an abstract data type that does enforce
> this property. It must have a Create procedure that checks that A < B,
> and access procedures that let clients access A and B.

Ok, thats the answer I'm looking for. If nobody knows a
better representation I'll made a private type. ;-)

Many thanks
Matthias

-- 
Matthias Teege -- matthias@mteege.de -- http://emugs.de
make world not war
PGP-Key auf Anfrage



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

* Re: Record type with check?
  2001-01-10  7:47   ` Matthias Teege
@ 2001-01-10 17:05     ` Nick Roberts
  2001-01-10 21:41     ` Robert Dewar
  1 sibling, 0 replies; 8+ messages in thread
From: Nick Roberts @ 2001-01-10 17:05 UTC (permalink / raw)


I'd like to throw in a couple of thoughts.

First, although it is generally good to define abstract types to enforce the
properties expected, occasionally it is better not to, either because it
would be overkill for a simple program, or (very unusual) because it would
slow down the program too much.

The other thought is that you may need to consider solitaire and null
ranges. If you enforce A < B, you will not be able to have a range that
consists of one integer. Even if you enforce only A <= B, how will you
represent a null range? If your problem does not require solitaire or null
ranges, then this point might not matter; otherwise, it will!

One further, perhaps rather esoteric, thought. You may - possibly, but not
necessarily - find that it is better to define an abstract data type (ADT)
at a level higher than for type Datum. For example, you might find it better
to define an ADT for a Datum_List - which holds a list of ranges - and have
operations for it such as below.

   type Datum_List is limited private;

   procedure Delete_All (List: in out Datum_List); -- makes empty
   procedure Add_Datum (List: in out Datum_List; Lo, Hi: in Integer);

   procedure Restart (List: in out Datum_List);
   procedure Advance (List: in out Datum_List);
   function At_End (List: in Datum_List) return Boolean;
   function Lo (List: in Datum_List) return Integer;
   function Hi (List: in Datum_List) return Integer;

Here, it is the procedure Add_Datum which checks that Lo and Hi have
mutually acceptable values. The essence of this example is that the
abstraction is at the level of the list of data, rather than the individual
datum. Sometimes it makes sense to do this, and sometimes it doesn't,
depending on the problem and the circumstances of the program. You might
like to compare this example with the way complex numbers are handled within
Ada.Numerics.Generic_Complex_Types (see RM95 Annex G).

Good luck,

--
Nick Roberts
http://www.AdaOS.org






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

* Re: Record type with check?
  2001-01-10  7:47   ` Matthias Teege
  2001-01-10 17:05     ` Nick Roberts
@ 2001-01-10 21:41     ` Robert Dewar
  2001-01-13  0:19       ` mark_lundquist
  1 sibling, 1 reply; 8+ messages in thread
From: Robert Dewar @ 2001-01-10 21:41 UTC (permalink / raw)


In article <87hf373l3a.fsf@moon.mteege.de>,
  Matthias Teege <matthias@mteege.de> wrote:
> If nobody knows a
> better representation I'll made a private type. ;-)

A private type *IS* a better representation. Nearly all types
should be private if they are at all complex, and most
certainly if invariants like this are to be preserved, the
appropriate interface is an abstract data type.


Sent via Deja.com
http://www.deja.com/



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

* Re: Record type with check?
  2001-01-10 21:41     ` Robert Dewar
@ 2001-01-13  0:19       ` mark_lundquist
  2001-01-13  1:08         ` Robert Dewar
  0 siblings, 1 reply; 8+ messages in thread
From: mark_lundquist @ 2001-01-13  0:19 UTC (permalink / raw)


In article <93ikth$ik5$1@nnrp1.deja.com>,
  Robert Dewar <robert_dewar@my-deja.com> wrote:
> In article <87hf373l3a.fsf@moon.mteege.de>,
>   Matthias Teege <matthias@mteege.de> wrote:
> > If nobody knows a
> > better representation I'll made a private type. ;-)
>
> A private type *IS* a better representation. Nearly all types
> should be private if they are at all complex, and most
> certainly if invariants like this are to be preserved, the
> appropriate interface is an abstract data type.

Matthias, don't say "I'll make it private if I have to", say "I'll make
it _public_ only if I have to!"

The full heuristic is something like this:

   1) Don't assume all type definitions belong in a package spec.

      Before putting a type in a spec, consider whether it might
      really belong in the body.  That's the essence of the advice
      in Nick Roberts' post (one way to look at it anyway --
      another is "think abstraction first, representation second").

      This is not at all to say it's categorically more desirable
      for type definitions to be in a body.  Just think about it,
      that's all.  If the essence of the abstraction is that clients
      declare instances of it, then it belongs in the spec; if it's
      needed to implement something within the body, put it in
      the body.  (You wouldn't, for instance, decide to use an "opaque
      handle" idiom for everything, just to keep types out of
      specs...)

   2) If the type belongs in the spec, it should go in the private
      part unless you have a reason for it to be public...

      Now if it's private, there are two ways to have better control
      over the abstraction:

      2a) Make the public view limited.

          Then clients cannot do assignment of instances of the type.
          You control whether they can test for equality (because you
          have to provide "="), and you control whether/how copies are
          made (since there's no assignment, copying would have to be
          by a subprogram that you provide).

          (Another way to control copying is to derive privately from
          Ada.Finalization.Controlled and override Adjust...)

      2b) Declare the public view with unknown discriminants, e.g.

              type Foo_Type (<>) is private;

          Then, whether the full view actually has discriminants or
          not, the only way for the client to declare an object of the
          type is with an initialization expression (because the client'
          has no other way to constrain the object!).  In your package,
          you can declare "constructor" functions that return an
          instance of the type, initialized correctly, and perform any
          side-effects associated with creation of the object.  The
          only way a client can create an object is to call one of your
          Create functions, E.g.,

              X : Foo.Foo_Type; -- Illegal!  Must be constrained...

              -- This works:
              --
              X : Foo.Foo_Type := Foo.Create (-- blah, blah, blah..);

          (Another way to control initialization is to derive privately
          from type Controlled or Limited_Controlled in
          Ada.Finalization and override Initialize, but that only gets
          you a "default constructor", i.e. with no parameters).

          If you make the public view limited *and* with unknown
          discriminants, then the client can't declare an instance
          of the type at all!  It can only set up functional
          "plumbing", because your package owns all the instances.

   3) If none of the above can work, then you know you have a type
      whose full view belongs in the public part of the spec! :-)

Have fun!

Mark Lundquist
Rational Software


Sent via Deja.com
http://www.deja.com/



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

* Re: Record type with check?
  2001-01-13  0:19       ` mark_lundquist
@ 2001-01-13  1:08         ` Robert Dewar
  0 siblings, 0 replies; 8+ messages in thread
From: Robert Dewar @ 2001-01-13  1:08 UTC (permalink / raw)


In article <93o6v2$dbi$1@nnrp1.deja.com>,
  mark_lundquist@my-deja.com wrote:

> Matthias, don't say "I'll make it private if I have to", say
> "I'll make it _public_ only if I have to!"

Mark, that's *very* nice, one for the memory banks :-)


Sent via Deja.com
http://www.deja.com/



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

end of thread, other threads:[~2001-01-13  1:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-01-09  8:12 Record type with check? Matthias Teege
2001-01-09 16:37 ` Florian Weimer
2001-01-09 22:12 ` Stephen Leake
2001-01-10  7:47   ` Matthias Teege
2001-01-10 17:05     ` Nick Roberts
2001-01-10 21:41     ` Robert Dewar
2001-01-13  0:19       ` mark_lundquist
2001-01-13  1:08         ` Robert Dewar

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