From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6b6619eb9cada212 X-Google-Attributes: gid103376,public From: "Matthew Heaney" Subject: Re: Help me to chose between ADA 95 and C++ Date: 1999/12/16 Message-ID: <3859abde_3@news1.prserv.net>#1/1 X-Deja-AN: 561795436 Content-transfer-encoding: 7bit References: <83b8il$i5k$1@nntp4.atl.mindspring.net> Content-Type: text/plain; charset="US-ASCII" X-Complaints-To: abuse@prserv.net X-Trace: 17 Dec 1999 03:19:58 GMT, 129.37.213.16 Organization: Global Network Services - Remote Access Mail & News Services Mime-version: 1.0 Newsgroups: comp.lang.ada Date: 1999-12-16T00:00:00+00:00 List-Id: In article <83b8il$i5k$1@nntp4.atl.mindspring.net> , Richard D Riehle wrote: > I am sure Matt Heaney will have some good things to say about this too. Well, I have some things to say, but I'm not sure they qualify as "good." > The answer is that one must export the methods appropriate to any > private type. If that type is a numeric, then methods for all of > its uses are necessary. My advice is not to declare a numeric type as private. In a sense, the type is already private, so you're hiding a type whose representation is already hidden. For example, the floating point declaration package P is type T is digits 8; end P; already has a "hidden" representation, which includes a sign bit, mantissa, and exponent. So hiding the floating point type behind yet another wall, ie package P is type T is private; private type Rep is digits 8; type T is new Rep; end P; doesn't seem to be buying you a whole lot. (Note that the private derivation is there to keep public and private namespaces separate. Public operations are implemented by internally converting the subprogram parameter from type T to type Rep, and then using Rep's operations.) Even an integer type has a "hidden" representation. For example: type T is range 100_000 .. 100_255; for T'Size use 8; forces T to have a biased representation. Publicly, of course, you refer to literal values in the stated range: O : T := 100_100; ... O := 100_111; but internally the compiler is using a representation that has the range 0 .. 255. > type Number is private; > > function Set (To : Integer) return Number; > function Zero_Equivalent return Number; > function Unit_Increment return Number; > function Unit_Decrement return Number; You can do this without declaring a private type: type Number is new Integer; > In the opinion of many OO practitioners, one should only export > services in the public part of a specification. For example, even > the popular deferred constant, under this viewpoint, would be better > designed as a function returning a constant. That makes it more > maintainable and defers information about the constant to the > package body. I agree that, for abstract data types, it's better to use a function instead of a deferred constant, but for a different reason. The problem with constants is that they aren't inherited during a derivation. Functions, because they're primitive operations, are inherited. > One of the benefits of Ada is its openess to multiple models of > object-oriented design. Not every type needs to be value extensible. > Ada child packages, and rules of elementary types, provide a model > for method extensibility that has far less overhead than might > be found in a language where the only mechanism for extensibility > is inheritance. Amen to that. Many programmers using other languages (and incredibly, many Ada programmers) don't appreciate how you can decouple abstractions when you don't use inheritance. For example, in a recent thread, someone had written: with Semphores; use Semaphores; generic type Semaphore_Type is new Root_Semaphore_Type with private; package Semaphore_Constrols_G is type Semaphore_Control (Semaphore : access Semaphore_Type'Class) is limited private; ... end Semaphore_Controls; This is wrong, because it unnecessarily couples the abstraction Semaphore_Controls to the abstraction Semaphores. Better is to simply import the type as a formal private type: generic type Semaphore_Type is limited private; with procedure Seize (Sema : in out Semaphore_Type) is <>; with procedure Release (Sema : in out Semaphore_Type) is <>; package Semaphore_Controls is ...; This can be used with *any* type that has the indicated operations. The operations don't even have to be named "seize" and "release". There is no reason to create a hierarchy of semaphores, nor is there any reason to marry semaphore controls to that particular hierarchy. -- I see no good reasons why the views given in this volume should shock the religious feelings of anyone. Charles Darwin, The Origin of Species