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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,b19fa62fdce575f9 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-12-03 10:11:08 PST Newsgroups: comp.lang.ada Path: bga.com!news.sprintlink.net!howland.reston.ans.net!news2.near.net!noc.near.net!inmet!dsd!stt From: stt@dsd.camb.inmet.com (Tucker Taft) Subject: Re: Strong numeric type checking Message-ID: Sender: news@inmet.camb.inmet.com Organization: Intermetrics, Inc. References: <3aa7jo$7j@Starbase.NeoSoft.COM> <3bldlu$84r@gnat.cs.nyu.edu> <3bo402$23a@felix.seas.gwu.edu> Date: Sat, 3 Dec 1994 18:06:14 GMT Date: 1994-12-03T18:06:14+00:00 List-Id: In article <3bo402$23a@felix.seas.gwu.edu>, Michael Feldman wrote: >In article <3bldlu$84r@gnat.cs.nyu.edu>, >Robert Dewar wrote: > >>Really the only step you could go further is to specifically add units >>support to the language, but for most people that is feature overkill. > >Yeah, we lost the battle on that one. See the note by do-while jones on this one. Actually one possibility we did consider seriously was allowing any two floating point types to be multiplied together without requiring explicit conversions. This would have eliminated strong type checking for multiplying operators, while retaining it for adding and subtracting. That might have been a reasonable compromise, but there were some thorny ambiguity and upward-compatibility problems. Note that this route was taken for fixed-point, to simplify use of the new "decimal" fixed-point types. >>IN practice, I find the strong type protection of different integer types >>to be of minimal value, strong typing is most important at a higher level >>than that, but that's a matter of personal taste. > >In general I agree, and find that subtypes give the needed range checks >without getting the programmer into type-compatibility stew, but there >are these persistent "urban myths" about Fortran codes whose mangled >dimension analysis sent space probes off the wrong way, etc. I rarely disagree with the Professor, but if you are primarily using the integer types as indices into various arrays, then strong type checking is quite useful to help make sure you don't use an apple number to index into a crate of oranges. For the average systems programmer, integers are probably used much more for counting, adding, and indexing, than they are used for multiplying. If you are primarily doing arithmetic (beyond just adding and subtracting), and you don't feel the urge to define the appropriate cross-product operators, then using subtypes rather than distinct types makes the most sense. Note that in Ada 9X, you can effectively "disable" undesired multiplying operators by overriding them with an abstract function definition. E.g.: function "*"(Left, Right : Meters) return Meters is abstract; This eliminates the need to declare the types as private just to get rid of unwanted operators. >Mike Feldman -Tucker Taft stt@inmet.com P.S. For those who have not already seen similar offerings, here is a sampling of some generics that could make it easier to define interesting dimensioned types, and associated cross-product operators, if the strong type checking is felt to be worth the effort in some given application. generic type Left_Type is digits <>; type Right_Type is digits <>; type Result_Type is digits <>; function Product(Left : Left_Type; Right : Right_Type) return Result_Type; pragma Inline(Product); function Product(Left : Left_Type; Right : Right_Type) return Result_Type is begin return Result_Type(Left) * Result_Type(Right); end Product; We could also define a package with a dimensionless floating point type (which would have all the multiplying operations) plus a root type with the multiplying operators made abstract, but with ones with a dimensionless operand one added back, such as: with Product, Quotient; generic type Impl_Type is digits <>; -- Impl Type should be Float/Long_Float/etc. package Generic_Units is type Dimensionless is new Impl_Type; type Dimensioned is new Impl_Type; /* First "disable" the undesirable operations */ function "*"(Left, Right : Dimensioned) return Dimensioned is abstract; function "/"(Left, Right : Dimensioned) return Dimensioned is abstract; function "**"(Left : Dimensioned; Right : Integer) return Dimensioned is abstract; /* Now define some additional ones */ function "*" is new Product(Dimensioned, Dimensionless, Dimensioned); function "*" is new Product(Dimensionless, Dimensioned, Dimensioned); function "/" is new Quotient(Dimensioned, Dimensionless, Dimensioned); function "/" is new Quotient(Dimensioned, Dimensioned, Dimensionless); end Generic_Units; After instantiating this with the appropriate implementation type, subtypes of Dimensionless could be used for dimensionless types, and derivatives of Dimensioned could be used for each dimensioned type, followed by any additional multiplying operators needed for the application. E.g.: with Generic_Units; package Units is new Generic_Units(Float); with Generic_Units; package Long_Units is new Generic_Units(Long_Float); with Long_Units; use Long_Units; with Product, Quotient; package CGS is subtype Ratio is Dimensionless; type Cm is new Dimensioned; type Gm is new Dimensioned; type Sec is new Dimensioned; type Cm_Per_Sec is new Dimensioned; function "/" is new Quotient(Cm, Sec, Cm_Per_Sec); function "*" is new Product(Cm_Per_Sec, Sec, Cm); function "*" is new Product(Sec, Cm_Per_Sec, Cm); ... end CGS; -TT