From: Marek Janukowicz on
Hello

I'm still working on a problem I asked about last week (thanks for all the
answers). Another question that arose recently: is there any way of calling
an instantiation of generic operation with prefixed notation?

Given a simplified example:

type Model is tagged record
null
end record;

generic
Attr_Name : String;
procedure Get_Attribute( M : Model );

procedure Get_Name is new Get_Attribute( "Name" );

Now I can call it with:
Get_Name( M );

but I'd rather use
M.Get_Name;

which complains about Get_Name not being present.

Is there any other way to achieve it?

--
Marek Janukowicz

--- news://freenews.netfront.net/ - complaints: news(a)netfront.net ---
From: Dmitry A. Kazakov on
On Mon, 14 Jun 2010 19:47:09 +0200, Marek Janukowicz wrote:

> I'm still working on a problem I asked about last week (thanks for all the
> answers). Another question that arose recently: is there any way of calling
> an instantiation of generic operation with prefixed notation?
>
> Given a simplified example:
>
> type Model is tagged record
> null
> end record;
>
> generic
> Attr_Name : String;
> procedure Get_Attribute( M : Model );
>
> procedure Get_Name is new Get_Attribute( "Name" );
>
> Now I can call it with:
> Get_Name( M );
>
> but I'd rather use
> M.Get_Name;
>
> which complains about Get_Name not being present.
>
> Is there any other way to achieve it?

Prefix notation is considered harmful. Anyway,. you need the operation
primitive:

One unit, declares the interface:

type Abstract_Model is abstract tagged null record;
procedure Get_Name (M : Abstract_Model) is abstract;

Same or another unit, provides a generic implementation:
generic
type Model_Type is new Abstract_Model with private;
Attr_Name : String;
procedure Get_Attribute (M : Model_Type);

Yet another unit brings both together:

type Model is new Abstract_Model with null record;
overriding procedure Get_Name (M : Model);

In its body:

procedure Get_Name_Implementation is new Get_Attribute (Model, "Name");
procedure Get_Name (M : Model) renames Get_Name_Implementation;

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Yannick Duchêne (Hibou57) on
Le Mon, 14 Jun 2010 19:47:09 +0200, Marek Janukowicz
<marek(a)janukowicz.net> a écrit:

Hi Marek,

> Given a simplified example:
>
> type Model is tagged record
> null
> end record;
>
> generic
> Attr_Name : String;
> procedure Get_Attribute( M : Model );
Here, Get_Attribute is not a primitive operation of Model I suppose.
If it is not a primitive operation of Model, you cannot invok it using the
dotted notation.

For a subprogram to be a primitive, it must be declared in the same
package as the one which declares the type (here Modem). That is OK here
for that. However, it also additionally requires the type is not frozen.
Here, when you define a generic using a Model as an argument, I'm pretty
sure this makes Model frozen.

Basically, a type is made frozen as soon as some reference to it requires
some important stuff are already defined. When you make some kind of
reference to a type, it suppose the type is frozen, that is, all these
important stuff are already defined.

Hint (as kind of personal opinion): I prefer to restrict to dotted
notation to access record fields in implementation, and just use the
classic subprogram invocation even with tagged. However, this is not
always handy with inherited operation.

--
There is even better than a pragma Assert: a SPARK --# check.
--# check C and WhoKnowWhat and YouKnowWho;
--# assert Ada;
-- i.e. forget about previous premises which leads to conclusion
-- and start with new conclusion as premise.
From: Adam Beneschan on
On Jun 14, 11:11 am, Yannick Duchêne (Hibou57)
<yannick_duch...(a)yahoo.fr> wrote:
> Le Mon, 14 Jun 2010 19:47:09 +0200, Marek Janukowicz  
> <ma...(a)janukowicz.net> a écrit:
>
> Hi Marek,
>
> > Given a simplified example:
>
> >   type Model is tagged record
> >     null
> >   end record;
>
> >   generic
> >     Attr_Name : String;
> >   procedure Get_Attribute( M : Model );
>
> Here, Get_Attribute is not a primitive operation of Model I suppose.
> If it is not a primitive operation of Model, you cannot invok it using the  
> dotted notation.
>
> For a subprogram to be a primitive, it must be declared in the same  
> package as the one which declares the type (here Modem). That is OK here  
> for that. However, it also additionally requires the type is not frozen.  
> Here, when you define a generic using a Model as an argument, I'm pretty  
> sure this makes Model frozen.
>
> Basically, a type is made frozen as soon as some reference to it requires  
> some important stuff are already defined. When you make some kind of  
> reference to a type, it suppose the type is frozen, that is, all these  
> important stuff are already defined.

Actually, I'm not sure that the generic declaration freezes Model.
The problem here is that the generic requires a body, and if you try
to instantiate it before the body is seen, you'd get a Program_Error.
But if you put the body of Get_Attribute before the instantiation
(assuming this isn't in a package spec), then *that* would cause Model
to be frozen.

I can't really tell whether the operation is legal or primitive,
however, or what kind of freezing has taken place, because the code
isn't a complete example. I don't know whether the declarations are
in a package spec, a package body, the declarative part of a
procedure, or just taken out of context from various parts of the
program.

-- Adam