comp.lang.ada
 help / color / mirror / Atom feed
* Array Index: substitute integer with enumeration
@ 2020-06-04 16:54 hreba
  2020-06-04 17:49 ` Jeffrey R. Carter
  2020-06-09 17:25 ` Shark8
  0 siblings, 2 replies; 5+ messages in thread
From: hreba @ 2020-06-04 16:54 UTC (permalink / raw)


Just as an example, let's assume there is a general geometry package 
which requires a function from the client which transforms cartesian 
coordinates into a client-specific coordinate system:

type Point is array (range 1..3) of Float;

type Transform_T is access Function (p: Point) return Point;

As a client who implements spherical coordinates, I would then write a 
function:

function To_Spherical (p: Point) return Point is
begin
   return
     ( Sqrt(p(1)**2 + p(2)**2 + p(3)**2),	-- r
       Arctan(p(2)/p(1)),			-- phi
       ...
     )
end To_Spherical.

Enumerations would make this less error-prone, but somewhat clumsy. With

type Cart_Coord is (x, y, z);

p(1) could be written as p(x'Pos+1). This is safer, but if I would 
define additionally

  type Spherical_Coord is (r, phi, theta)

the compiler wouldn't notice a mix-up of x'Pos and r'Pos. But now I 
could write

type Cart_Point is array (Cart_Coord) of Float;

function To_Spherical (p: Point) return Point is
   pc: Cart_Point:= p;
begin
   return
     ( Sqrt(pc(x)**2 + pc(y)**2 + pc(z)**2),	-- r
       Arctan(p(y)/p(x)),			-- phi
       ...
     )
end To_Spherical.

My questions are now:

1. Does the initialization of pc involve any copying at run time?
2. If so, how can it be avoided?

-- 
Frank Hrebabetzky, Kronach	+49 / 9261 / 950 0565

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Array Index: substitute integer with enumeration
  2020-06-04 16:54 Array Index: substitute integer with enumeration hreba
@ 2020-06-04 17:49 ` Jeffrey R. Carter
  2020-06-05 15:16   ` hreba
  2020-06-09 17:25 ` Shark8
  1 sibling, 1 reply; 5+ messages in thread
From: Jeffrey R. Carter @ 2020-06-04 17:49 UTC (permalink / raw)


On 6/4/20 6:54 PM, hreba wrote:
> 
> function To_Spherical (p: Point) return Point is
>    pc: Cart_Point:= p;
> begin
>    return
>      ( Sqrt(pc(x)**2 + pc(y)**2 + pc(z)**2),    -- r
>        Arctan(p(y)/p(x)),            -- phi
>        ...
>      )
> end To_Spherical.
> 
> My questions are now:
> 
> 1. Does the initialization of pc involve any copying at run time?

1. If you can get your code to compile, you can check the object code to see.

The only reason for worrying about this is if it causes Storage_Error or failure 
to meet your quantitative timing requirements. Since you haven't tried it, you 
don't know that will happen, so there's no reason for concern.

Seems to me that with a design like

package Cartesian is
    type Point is record
       X : Float := 0.0;
       Y : Float := 0.0;
       Z : Float := 0.0;
    end record;

    -- Operations of Point

    generic
       type Client_Point is private;
       with function To_Cartesian (P : Client_Point) return Point;
       with function To_Client (P : Point) return Client_Point;
    package Client is
       -- Operations of Client_Point
    end Client;
end Cartesian;

type Point is record
    R     : Float := 0.0;
    Phi   : Float := 0.0;
    Theta : Float := 0.0;
end record;

function To_Cartesian (P : Point) return Cartesian.Point;
function To_Spherical (P : Cartesian.Point) return Point;

package Spherical is new Cartesian.Client (Client_Point => Point,
                                           To_Cartesian  => To_Cartesian,
                                           To_Client     => To_Spherical);

copying would not be a concern.

-- 
Jeff Carter
"When Bell Labs were invited to evaluate C against the DoD requirements
[for Ada], they said that there was no chance of C meeting the
requirements of readability, safety, etc. for which we were striving,
and that it should not even be on the list of evaluated languages."
William Whitaker
116

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Array Index: substitute integer with enumeration
  2020-06-04 17:49 ` Jeffrey R. Carter
@ 2020-06-05 15:16   ` hreba
  2020-06-05 17:15     ` Jeffrey R. Carter
  0 siblings, 1 reply; 5+ messages in thread
From: hreba @ 2020-06-05 15:16 UTC (permalink / raw)


On 6/4/20 7:49 PM, Jeffrey R. Carter wrote:
> 
> 1. If you can get your code to compile, you can check the object code to 
> see.
> 
It ends here. I thought index types with the same length were 
convertible, but learned now that they aren't. Moreover, 'Pos is an 
attribute not of a variable, but of a type, what makes the expressions 
still more clumsy. So, If I don't want to fumble around with numbers, I 
have to define integer constants for the indices.
> 
> Seems to me that with a design like
> Unfortunately the type is defined in an external library, so I cannot 
change it.
-- 
Frank Hrebabetzky, Kronach	+49 / 9261 / 950 0565

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Array Index: substitute integer with enumeration
  2020-06-05 15:16   ` hreba
@ 2020-06-05 17:15     ` Jeffrey R. Carter
  0 siblings, 0 replies; 5+ messages in thread
From: Jeffrey R. Carter @ 2020-06-05 17:15 UTC (permalink / raw)


On 6/5/20 5:16 PM, hreba wrote:
>>
>> Unfortunately the type is defined in an external library, so I cannot 
> change it.

The definition of the library's point type isn't important. What's important is 
that clients who want to use another coordinate system can use whatever 
definition of a point they think is appropriate, provided they can convert it to 
and from the library's point type. You can still define a generic that will 
allow the use of the library with any arbitrary point type, provided it can be 
converted to and from the library's point type.

-- 
Jeff Carter
"Sheriff murdered, crops burned, stores looted,
people stampeded, and cattle raped."
Blazing Saddles
35

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Array Index: substitute integer with enumeration
  2020-06-04 16:54 Array Index: substitute integer with enumeration hreba
  2020-06-04 17:49 ` Jeffrey R. Carter
@ 2020-06-09 17:25 ` Shark8
  1 sibling, 0 replies; 5+ messages in thread
From: Shark8 @ 2020-06-09 17:25 UTC (permalink / raw)


On Thursday, June 4, 2020 at 10:54:57 AM UTC-6, hreba wrote:
> Just as an example, let's assume there is a general geometry package 
> which requires a function from the client which transforms cartesian 
> coordinates into a client-specific coordinate system:
> 
> type Point is array (range 1..3) of Float;
> 
> type Transform_T is access Function (p: Point) return Point;

You don't need accesses in any of your program-facing compilation-units; you *might* for the library-facing interfaces. The type Point can also be modeled differently for the program-facing side and the library-facing side. — That is, you can do everything you need to interface the library in the private-section and/or body (body would arguably be preferable, because if you discard the library's usage, you've constrained the library only to the body and thus only have one thing to change.

Using coordinates + enumerations you could, perhaps, use:
   Type Point is record
      r, phi, theta: Interfaces.IEEE_Float_32;
   End Record
   with Size => Interfaces.IEEE_Float_32*3;

and then in your library interfacing part, have:
    Type Library_Point is Array(1..3) of Interfaces.IEEE_Float_32
       with Convention => Fortran, Size => Interfaces.IEEE_Float_32*3;
    Pragma Assert( Point'Size = Library_Point'Size,
                  "Point-type sizes must match."    );
    -- Imported functions.
    -- To_Cartesian and To_Spherical, etc.
    
    Function Convert( Input : Point ) return Library_Point is
       -- Isolating the Unchecked Conversion.
       Function Cvt is new Ada.Unchecked_Conversion(Point, Library_Point);
    Begin
       Return Result : constant Library_Point := To_Cartesian( Cvt(Input) );
    End Convert;
    
    Function Convert( Input : Library_Point ) return Point is
       -- Isolating the Unchecked Conversion.
       Function Cvt is new Ada.Unchecked_Conversion(Library_Point, Point);
    Begin
       Return Result : constant Library_Point := To_Spherical( Cvt(Input) );
    End Convert;

and take your conversion functions
    To_Cartesian and To_Spherical and passing their accesses to the imported functions that need them.


TL;DR — Make the interface you want to present to your program first then, in the body, do all your interfacing and library-importing.

> My questions are now:
> 
> 1. Does the initialization of pc involve any copying at run time?
IIRC, parameters are passed as reference for arrays and records; so if that's what you're using to model a point, it shouldn't for functions. Initialization, especially with aggregates, is a different matter and one I'm less sure on. (I seem to recall someone, Lucretia?, doing some work with GNAT and coming to the conclusion that if there was an "Others" in the aggregate there would be a loop generated, which might have copying.)
> 2. If so, how can it be avoided?
Usually by things like shown: isolate your critical functions, and then (a) present an interface for the rest of the program to use while (b) ensuring those critical functions behave as you want. (This might take a little more expertise on the subject, as it sounds like you could be messing with embedded and my experience there is extremely limited.)

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-06-09 17:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-04 16:54 Array Index: substitute integer with enumeration hreba
2020-06-04 17:49 ` Jeffrey R. Carter
2020-06-05 15:16   ` hreba
2020-06-05 17:15     ` Jeffrey R. Carter
2020-06-09 17:25 ` Shark8

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox