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,1f0e8beefacb537e X-Google-Attributes: gid103376,public From: "Matthew Heaney" Subject: Re: Engineering types hierarchy Date: 1999/09/08 Message-ID: <37d663dd@news1.prserv.net>#1/1 X-Deja-AN: 522524329 Distribution: world Content-transfer-encoding: 7bit References: <7r50i7$e893@svlss.lmms.lmco.com> Content-Type: text/plain; charset="US-ASCII" X-Complaints-To: abuse@prserv.net X-Trace: 8 Sep 1999 13:25:49 GMT, 129.37.213.152 Organization: Global Network Services - Remote Access Mail & News Services Mime-version: 1.0 Newsgroups: comp.lang.ada Date: 1999-09-08T00:00:00+00:00 List-Id: In article <7r50i7$e893@svlss.lmms.lmco.com> , dkristol@see-my.sig (David Kristola) wrote: > Hello, > > I am trying to put together a robust and easily usable > hierarchy of types packages to support a collection of > engineering units (kilograms, meters, seconds, etc.) > in scalar, vector, and matrix forms. > [snip] > Is there a better way? In general, I like to keep it simple, and just name (scalar) types with their units: package Ownship is type Heading_In_Deg_Type_Base is delta 0.1 range -720.0 .. 720.0; for Heading_Type_In_Deg_Type_Base'Small use 0.1 subtype Heading_In_Deg_Type is Heading_In_Deg_Type_Base range 0.0 .. Heading_In_Deg_Type_Base'Pred (360.0); function Get_Heading_In_Deg return Heading_In_Deg_Type; type Speed_In_Knots_Type is ; function Get_Speed_In_Knots return Speed_In_Knots_Type; ... end Ownship; Naming selector functions with their units prevents this kind of error: declare Speed_In_MPH : constant Speed_In_MPH_Type := Speed_In_MPH_Type (Ownship.Get_Speed); begin This is a bug, because ownship speed is in knots. Compare it to: declare Speed_In_MPH : constant Speed_In_MPH_Type := Speed_In_MPH_Type (Ownship.Get_Speed_In_Knots .. huh??? and hopefully the programmer realizes immediately that there's a type conversion issue. When I need to go a units conversion, I just use a package of named numbers: package Conversions.Speed is Knots_Per_KPH : constant := ...; KPH_Per_Knots : constant := 1.0 / Knots_Per_KPH; MPH_Per_KPH : constant := ...; KPH_Per_MPH : constant := 1.0 / MPH_Per_KPH; ... end Conversions.Speed; Actually, if you have a similar package for length conversions (and maybe another for simple time conversions), you won't even really need a dedicated package for speed conversions. As you've already discovered, other approaches engender a combinatorial explosion. There's no way for you to know up front which conversions you're going to need, so just declare a minimal set (for length, mass, and time, say), and leave it up to the client to combine the primitive units conversions into the complex units he needs locally. It the time of conversion, I just declare the objects with their units and units-and-type: declare Speed_In_Knots : constant Speed_In_Knots_Type := Ownship.Get_Speed_In_Knots; Speed_In_Knots_As_MPH : constant Speed_In_MPH_Type'Base := Speed_In_MPH_Type'Base (Speed_In_Knots); Speed_In_MPH : constant Speed_In_MPH_Type := Speed_In_Knots_As_MPH * MPH_Per_Knots; begin Set_Speed (Of_Something, To => Speed_In_MPH); end; I find that this simple approach works best, and is more efficient than other, more complex schemes. It may be more verbose, but the conversions are done using baby steps, and I can tell exactly what's going on. Matt