News for hackers. Stuff that matters.
Re:Ada for the C++ and Java Developer [pdf] by tmcb on Sunday March 28, 2021 @08:37AM (#26609813)
I am not an Ada expert, but I came up with this. Please notice that the idea here is not to have the compiler do proper dimensional analysis but simply to avoid the default operator overloading of "*" for the Distance type that also returns a Distance value.

Nothing very high-level, as we need to explicitly manipulate the single-component records, but it does the job.

    with Ada.Text_IO; use Ada.Text_IO;
    
    procedure Main is
       type Distance is record
          Value : Float;
       end record;
    
       type Area is record
          Value : Float;
       end record;
    
       function "*" (Left, Right : Distance) return Area is
       begin
          return (Value => Left.Value * Right.Value);
       end "*";
    
       D1 : constant Distance := (Value => 10.0);
    
       D2 : constant Distance := (Value => 20.0);
    
       -- D3 : constant Distance := D1 * D2;
       -- Does not compile. GNAT returns the following error:
       --   main.adb:21:33: expected type "Distance" defined at line 4
       --   main.adb:21:33: found type "Area" defined at line 8
    
       A : constant Area := D1 * D2;
    begin
       Put_Line ("Area A is " & Float'Image(A.Value));
    end Main;*
Re:Ada for the C++ and Java Developer [pdf] by yannickmoy on Monday March 29, 2021 @03:38AM (#26618624)
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;
Re:Ada for the C++ and Java Developer [pdf] by tmcb on Monday March 29, 2021 @04:26AM (#26618863)
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.
Re:Ada for the C++ and Java Developer [pdf] by OneWingedShark on Tuesday March 30, 2021 @09:28AM (#26634356)
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;
Re:Ada for the C++ and Java Developer [pdf] by tmcb on Tuesday March 30, 2021 @11:28AM (#26635730)
That seems to do the trick for an individual predefined operator specification. Thanks!
Re:Ada for the C++ and Java Developer [pdf] by ajdude on Sunday March 28, 2021 @01:51PM (#26612458)
This is the right way to approach it on my opinion.