Hacker News new | ask | show | jobs
by yannickmoy 1911 days ago
As someone said, the best solution here is to use the dimensionality analysis in GNAT: https://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ug...

as in:

  with Ada.Text_IO; use Ada.Text_IO;
  with System.Dim.Float_Mks; use System.Dim.Float_Mks;
  with System.Dim.Float_Mks_IO; use System.Dim.Float_Mks_IO;

    procedure Main is
       subtype Distance is System.Dim.Float_Mks.Length;
       subtype Area is System.Dim.Float_Mks.Area;

       D1 : constant Distance := 10.0*m;

       D2 : constant Distance := 20.0*m;

       -- D3 : constant Distance := D1 * D2;
       -- Does not compile. GNAT returns the following error:
       --   main.adb:13:08: dimensions mismatch in object declaration
       --   main.adb:13:37: expected dimension [L], found [L**2]

       A : constant Area := D1 * D2;
    begin
       -- print: Area A is  2.00000E+02 m**2
       Put ("Area A is ");
       Put (Item => A);
       Put_Line ("");
    end Main;
1 comments

Oh, thanks for pointing it out. Honestly, I was more interested in leveraging the type system than on proper dimensional analysis. I could find no mechanism by which Ada allows the programmer to disable the default operation overloads, so I decided to try that out.
IIRC you can disable/forbid the default like so:

    Function "*"(Left, Right: Distance) return Distance is abstract;
then use:

    Function "*"(Left, Right : Distance) return Area;
That seems to do the trick for an individual predefined operator specification. Thanks!