comp.lang.ada
 help / color / mirror / Atom feed
From: "Matthew Heaney" <matthew_heaney@acm.org>
Subject: Re: Help me to chose between ADA 95 and C++
Date: 1999/12/18
Date: 1999-12-18T00:00:00+00:00	[thread overview]
Message-ID: <385bab78_3@news1.prserv.net> (raw)
In-Reply-To: 83dsno$5v2$1@nntp2.atl.mindspring.net

In article <83dsno$5v2$1@nntp2.atl.mindspring.net> , Richard D Riehle 
<laoXhai@ix.netcom.com>  wrote:

> In general this is true.  From time to time it might be useful to
> expand or contract the exported behavior for a particular numeric
> type.  For example, I saw a design not long ago with this declaration,
>
>        type Counter is private;
>        function Initialize return Counter;
>        function Increment return Counter;
>        function Decrement return Counter;
>
> where the full defintion was a integer type. The designer intended to
> prevent any operations on Counter except increment and decrement. For
> this application, that was a reasonable approach and eliminated any of
> the complications associated with a client doing more arithmetic than
> necessary.

But you can add and even subtract operations from a scalar type:

  type Counter is new Integer;

  function "+" (L, R : Counter) return Counter is abstract;

  function "-" (L, R : Counter) return Counter is abstract;

You can then use Counter'Succ and Counter'Pred.


> I can think of other circumstances where it would be
> useful to hide the actual type definition and export a restricted set
> of operations, or a special set of operations.  Moreover, it might be
> useful to expand the set of exceptions for that type and add pre- and
> post- conditions in the implementation of some operator/operation.

You can also replace operations:

  type Heading_Type_Base delta 1.0/2**(-16) range -720.0 .. 720.0;

  subtype Heading_Type is
    Heading_Type_Base range 0.0 .. Heading_Type_Base'Pred (360.0);

  function Predefined_Add
    (L, R : Heading_Type_Base) return Heading_Type_Base renames "+";

  function "+" (L, R : Heading_Type) return Heading_Type;

  function Predefined_Subtract
    (L, R : Heading_Type_Base) return Heading_Type_Base renames "-";

  function "-" (L, R : Heading_Type) return Heading_Type;

Now you can implement "+" and "-" to have wrap-around behaviour:

  H := 359.0;
  H := H + 2.0;  -- H = 1.0
  H := 5.0;
  H := H - 10.0;  -- H = 355.0


> Suppose, however, that we want to do a little more than that.
> Suppose the Divide operation is modified as (contrived example):
>
>     function "/"(L , R : T) return T is
>         Result : T;
>     begin
>        if R = Zero then ...          -- raise some exception?
>        elsif some-other-condition    -- raise some other exception
>        elsif even-another-condition  -- raise even-another-exception
>        else
>           Result := Division-operation
>        end if;
>        if Result is-in-some condition -- raise post-condition-exception
>            -- potentially more tests
>        else
>           return Result;
>        end if;
>      end "/";
>
> I fully understand the problems with this example, but I also recognize
> that, in the absence of exportable pre- and post-conditions in Ada, we
> have few options but to check for these within the code itself.

But pre- and post-condition checking is a separate issue from overriding
predefined operators of a scalar type.  We could declare your divide op
for a non-private type:

  type T is new Float;

  function Predefined_Divide (L, R : T) return T renames "/";

  function "/" (R, L : T) return T;


You may prefer to not use an infix operator at all:

  type T is new Float;

  function Div (Dividend, Divisor : T) return T;


In any case you're free to raise whatever exceptions are appropriate.

As far as pre- and post-condition checking goes, I prefer to check using
pragma Assert.  No, this is not an official standard, but it is a de
facto standard.  (There's even an AI to add this pragma to the
language.)

The benefit using a pragma is that the assertion check can be turned on
or off using switches, analogous to suppressing constraint checks.


> Under these circumstances, I might want to write my own operators to ensure
> conformity with rules that cannot be described through simple range
> constraints.

Agreed, but this doesn't mean you have to declare the type as private.


> I agree that this is an additional problem.  Deferred constants seem
> to violate many of the principles of object-oriented programming.

They have their place.  If I write an ADT for exclusive use within a
subsystem -- where I know no type derivation will occur -- then I'd
probably use a deferred constant.

However, if you write an ADT for general consumption, and you don't
really know who your clients are, then I'd use a function.  (Again,
because they might do some derivations, and we want the function to be
inherited.  Constants aren't inherited.)

This issue rears its ugly head for another reason.  If you use a
deferred constant, and elaboration of the constant requires nonstatic
initialization, then you won't be able to use pragma Preelaborate:

package Lists is

  pragma Preelaborate;  --illegal...

  type List_Type is private;

  Null_List : List_Type;
  ...
private
  type List_Type is new Controlled with
    record
      Head : Node_Access;
    end record;

  Null_List : constant List_Type := (Controlled with Head => null);
   -- ... because this is nonstatic

end Lists;


We'd like to use the strongest form of categorization pragma possible.
Above, we'd have to change down to pragma Elaborate_Body.

The solution is to declare Null_List as a primitive operation of the
type:

package Lists
  pragma Preelaborate;  -- legal ...
  type List_Type is private;

  function Null_List return List_Type;
    -- ... because this returns its value at run-time

private
  type List_Type is <as above>
end Lists;


> I think we are once again in agreement on most points.

Yes.

--
Creationists attempt to draw a line between evolutionary biology and the
rest of science by remarking that large-scale evolution cannot be
observed.  This tactic fails.  Large-scale evolution is no more
inaccessible to observation than nuclear reactions or the molecular
composition of water.

Abusing Science: The Case Against Creationism
Philip Kitcher




  reply	other threads:[~1999-12-18  0:00 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-12-15  0:00 Help me to chose between ADA 95 and C++ Robert C. Leif, Ph.D.
1999-12-16  0:00 ` Richard D Riehle
1999-12-16  0:00   ` Matthew Heaney
1999-12-17  0:00     ` Richard D Riehle
1999-12-18  0:00       ` Matthew Heaney [this message]
1999-12-20  0:00         ` Richard D Riehle
  -- strict thread matches above, loose matches on Subject: below --
1999-12-22  0:00 Help me to chose between ADA 95 and C++ ( Ehud Lamm
1999-12-14  0:00 Help me to chose between ADA 95 and C++ Robert C. Leif, Ph.D.
1999-12-15  0:00 ` Richard D Riehle
1999-11-26  0:00 Robert
1999-11-26  0:00 ` Preben Randhol
1999-11-26  0:00   ` Preben Randhol
1999-11-26  0:00 ` Andreas Winckler
1999-11-26  0:00 ` Harald Schmidt
1999-11-26  0:00   ` Andreas Winckler
1999-11-26  0:00     ` Florian Weimer
1999-12-04  0:00   ` Richard D Riehle
     [not found]     ` <01bf3e32$0b9dc880$022a6282@dieppe>
1999-12-10  0:00       ` Chris Powell
1999-12-13  0:00         ` Richard D Riehle
1999-12-14  0:00           ` Chris Powell
1999-12-14  0:00             ` Simon Wright
1999-12-15  0:00               ` Chris Powell
1999-12-15  0:00                 ` Robert A Duff
1999-12-14  0:00             ` Richard D Riehle
1999-12-14  0:00               ` Matthew Heaney
1999-12-14  0:00             ` Ray Blaak
1999-12-14  0:00             ` Larry Kilgallen
1999-12-15  0:00               ` Robert A Duff
2000-01-12  0:00                 ` Richard Pinkall-Pollei
1999-12-15  0:00             ` Ted Dennison
1999-12-20  0:00               ` Stefan Skoglund
1999-12-16  0:00             ` Pascal Obry
1999-12-16  0:00               ` Rakesh Malhotra
1999-12-21  0:00                 ` Geoff Bull
1999-12-16  0:00               ` Lutz Donnerhacke
1999-12-16  0:00               ` Aidan Skinner
1999-12-21  0:00             ` Robert Dewar
1999-12-21  0:00               ` Chris Powell
1999-12-21  0:00               ` Ted Dennison
1999-12-21  0:00                 ` Robert Dewar
1999-12-13  0:00         ` Marin D. Condic
1999-12-13  0:00         ` Brian Rogoff
1999-12-14  0:00           ` Chris Powell
1999-12-14  0:00             ` Preben Randhol
1999-12-14  0:00               ` Stephen Leake
1999-12-14  0:00                 ` Tucker Taft
1999-12-15  0:00                   ` Stephen Leake
1999-12-15  0:00                 ` Preben Randhol
1999-12-14  0:00             ` Brian Rogoff
1999-12-15  0:00           ` Richard Pinkall-Pollei
1999-12-15  0:00             ` Richard Pinkall-Pollei
1999-12-21  0:00             ` Geoff Bull
1999-12-21  0:00               ` Tucker Taft
1999-12-22  0:00                 ` Ted Dennison
1999-12-13  0:00         ` DuckE
1999-12-14  0:00           ` Matthew Heaney
1999-12-14  0:00         ` Matthew Heaney
1999-12-14  0:00           ` Chris Powell
1999-12-14  0:00             ` Matthew Heaney
1999-12-15  0:00               ` Hyman Rosen
1999-12-14  0:00             ` Tucker Taft
1999-12-14  0:00               ` Matthew Heaney
1999-12-23  0:00               ` Chris Powell
1999-12-27  0:00                 ` Robert A Duff
1999-12-14  0:00             ` Stephen Leake
1999-12-23  0:00               ` Chris Powell
1999-11-27  0:00 ` Lionel Draghi
replies disabled

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