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,a90718b61c5de714 X-Google-Attributes: gid103376,public From: eachus@spectre.mitre.org (Robert I. Eachus) Subject: Re: assignments using different types Date: 1997/01/29 Message-ID: #1/1 X-Deja-AN: 213144977 references: <32EE4431.6D24@ti.com> organization: The Mitre Corp., Bedford, MA. newsgroups: comp.lang.ada Date: 1997-01-29T00:00:00+00:00 List-Id: In article <32EE4431.6D24@ti.com> David Dessert writes: > I have a question about readability and efficiency of assignments > when using strict types in Ada83. I'm using the TI-Tartan C40 > compiler, which has few Ada95 features. (In spite of the above comment, I'll answer for Ada 95, then relate back to Ada 83.) > Example: > type Distance_Type is new float range 0.0 .. 1000.0; > type Time_Type is new float range 0.0 .. 10.0; > type Velocity_Type is new float; In Ada 95, you should immediately declare: function "*"(L,R: Distance_Type) return Distance_Type is abstract; function "/"(L,R: Distance_Type) return Distance_Type is abstract; function "*"(L,R: Time_Type) return Time_Type is abstract; function "/"(L,R: Time_Type) return Time_Type is abstract; function "*"(L,R: Velocity_Type) return Velocity_Type is abstract; function "/"(L,R: Velocity_Type) return Velocity_Type is abstract; -- These declarations will have no effect at run-time, but will -- eliminate many type errors. (These declarations are Ada 95 only.) -- Now you can introduce the correct multiplication and division -- operations: function "*"(L: Velocity_Type, R: Time_Type) return Distance_Type; function "*"(L: Time_Type, R: Velocity_Type) return Distance_Type; function "/"(L: Distance_Type, R: Time_Type) return Velocity_Type; function "/"(L: Distance_Type, R: Velocity_Type) return Time_Type; -- The bodies are easy, just remember to convert to float... pragma Inline("*","/"); --might as well get rid of the overhead... Distance : Distance_Type := 100.0; Time : Time_Type := 10.0; Velocity : Velocity_Type; ... -- A difficult to read, but legal Ada assignment. Velocity := Velocity_Type(float(Distance) / float(Time)); > Can anyone provide me with suggestions to improve the readability > of the above assignment? Of course, I'd like efficiency to be > similar to that of using the same type for all the variables. -- Now you can write that: Velocity := Distance / Time; There can be a need for qualification if you use literals in an expression, but that is a detail. In Ada 83, the abstract declarations are not possible. You can just leave them out which won't affect correct programs. Or you can use private types: type Distance_Type is private; type Time_Type is private; type Velocity_Type is private; Now you may need to declare the adding and relational operators, but the real problem is that you lose the literals. So you have to declare: function To_Time(T: in Float) return Time_Type; ... Distance : Distance_Type := To_Distance(100.0); Time : Time_Type := To_Time(10.0); Velocity : Velocity_Type; However a lot of people prefer to declare the constants and operators necessary to write: Distance : Distance_Type := 100.0 * Kilometers; Time : Time_Type := 10.0 * Hours; But that is not my style. (I'd prefer to name Distance_Type Kilometers or Miles or whatever, and do the same for time and velocity.) If you have lots of different units in a program, you might want to look at something Paul Hilfinger came up with years ago. He made a single measurement record type with integer discriminants. So velocity would be: subtype Velocity is Measurement(Mass => 0, Length => 1, Time => -1); Now all the operations can check dimensionality. What is really neat is to then recompile with a body where all the dimensional checks are gone. With a good compiler the overhead will completely disappear. (You can change the type and subtype declarations if the compiler is not quite so smart.) But any good compiler will give you a warning if the units don't match at compile time, so recompiling is not leaving off the lifeboats since you know the checks will never fail--at least until the maintenance staff gets their hands on it. ;-) -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is...