comp.lang.ada
 help / color / mirror / Atom feed
* Trouble with overriding and class-wide parameters
@ 2006-07-15 17:00 Yves Bailly
  2006-07-15 18:00 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Yves Bailly @ 2006-07-15 17:00 UTC (permalink / raw)


Hello all,

Here's a problem I'm encountering, while developping a (rather
huge) library using Ada 2005, for now using only the latest GNAT
GPL compiler from AdaCore (i.e. GNAT-2006).

Given a first package, defining a tagged type:
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
package Pkg is
   type Some_Type is tagged null record;
   not overriding
   procedure Setup(st: not null access Some_Type;
                   p :          access Some_Type'Class);
end Pkg;
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
The procedure just Put_Line() a string to identify itself.

Then take a second package, with a type derived from the previous:
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
with Pkg; use Pkg;
package Sub_Pkg is
   type Sub_Type is new Some_Type with null record;
   not overriding
   procedure Setup(st: not null access Sub_Type;
                   p :          access Sub_Type'Class);
end Sub_Pkg;
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
Here again the procedure just print something to identify itself.

Now the test program:
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
with Pkg; use Pkg;
with Sub_Pkg; use Sub_Pkg;
procedure Test is
   st: aliased Sub_Type;
begin
   st.Setup(null);
end Test;
--8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---

I would expect the call to Setup() to invoke the Sub_Pkg.Setup()
procedure, as "st" is of type Sub_Type. However the procedure
actually called is Pkg.Setup(), as shown by the output :
Pkg.Setup(Some_Type)

What am I missing? I suspect the value "null" to be part of this,
but I can't find a workaround.

Sorry in advance if it's a silly question, I have a huge background
of C++ and not yet very skilled with Ada type system.

Thanks for any hint !

Best regards,

-- 
(o< | Yves Bailly  : http://kafka-fr.net   | -o)
//\ | Linux Dijon  : http://www.coagul.org | //\
\_/ |                                      | \_/`



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-15 17:00 Trouble with overriding and class-wide parameters Yves Bailly
@ 2006-07-15 18:00 ` Dmitry A. Kazakov
  2006-07-15 18:20   ` Yves Bailly
  2006-07-15 18:52 ` Jeffrey R. Carter
  2006-07-16 10:00 ` Javier Miranda
  2 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2006-07-15 18:00 UTC (permalink / raw)


On Sat, 15 Jul 2006 19:00:00 +0200, Yves Bailly wrote:

> Hello all,
> 
> Here's a problem I'm encountering, while developping a (rather
> huge) library using Ada 2005, for now using only the latest GNAT
> GPL compiler from AdaCore (i.e. GNAT-2006).
> 
> Given a first package, defining a tagged type:
> --8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
> package Pkg is
>    type Some_Type is tagged null record;
>    not overriding
>    procedure Setup(st: not null access Some_Type;
>                    p :          access Some_Type'Class);
> end Pkg;
> --8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
> The procedure just Put_Line() a string to identify itself.
> 
> Then take a second package, with a type derived from the previous:
> --8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
> with Pkg; use Pkg;
> package Sub_Pkg is
>    type Sub_Type is new Some_Type with null record;
>    not overriding
>    procedure Setup(st: not null access Sub_Type;
>                    p :          access Sub_Type'Class);
> end Sub_Pkg;
> --8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
> Here again the procedure just print something to identify itself.
> 
> Now the test program:
> --8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
> with Pkg; use Pkg;
> with Sub_Pkg; use Sub_Pkg;
> procedure Test is
>    st: aliased Sub_Type;
> begin
>    st.Setup(null);
> end Test;
> --8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<---
> 
> I would expect the call to Setup() to invoke the Sub_Pkg.Setup()
> procedure, as "st" is of type Sub_Type. However the procedure
> actually called is Pkg.Setup(), as shown by the output :
> Pkg.Setup(Some_Type)
> 
> What am I missing? I suspect the value "null" to be part of this,
> but I can't find a workaround.

What are you trying to achieve? The code looks wrong to me. Why are you 
using access types in a procedure? Why do you want to overload two 
different Setup? If the second parameter has to be covariant then Ada does 
support it:

   procedure Setup (St : in out Some_Type; p : in out Some_Type);

If you want it contravariant Ada supports that as well:

   procedure Setup (St : in out Some_Type; p : in out Some_Type'Class);

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-15 18:00 ` Dmitry A. Kazakov
@ 2006-07-15 18:20   ` Yves Bailly
  2006-07-15 19:12     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: Yves Bailly @ 2006-07-15 18:20 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> What are you trying to achieve? The code looks wrong to me. Why are you
> using access types in a procedure? Why do you want to overload two
> different Setup? If the second parameter has to be covariant then Ada does
> support it:

It's only a very reduced sample code, extracted from a much larger
code base. The particular needs for access types are specific to
this code base. That said, replace any "not null access" for the
first parameters with "in out" and you'll get the same effect. The
second parameter *has* to be an access type, as it can be null
on purpose. See it as "parent object", in a tree-like structure
(just to give an idea).

I understand all of this might seem a little bit odd, now I really
would like to understand what happens and why it's not the second
Setup() (from Sub_Pkg) which is called.

Regards,

-- 
(o< | Yves Bailly  : http://kafka-fr.net   | -o)
//\ | Linux Dijon  : http://www.coagul.org | //\
\_/ |                                      | \_/`



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-15 17:00 Trouble with overriding and class-wide parameters Yves Bailly
  2006-07-15 18:00 ` Dmitry A. Kazakov
@ 2006-07-15 18:52 ` Jeffrey R. Carter
  2006-07-15 20:03   ` Yves Bailly
  2006-07-16 10:00 ` Javier Miranda
  2 siblings, 1 reply; 10+ messages in thread
From: Jeffrey R. Carter @ 2006-07-15 18:52 UTC (permalink / raw)


Yves Bailly wrote:
> 
> package Pkg is
>    type Some_Type is tagged null record;
>    not overriding
>    procedure Setup(st: not null access Some_Type;
>                    p :          access Some_Type'Class);
> end Pkg;
> 
> with Pkg; use Pkg;
> package Sub_Pkg is
>    type Sub_Type is new Some_Type with null record;
>    not overriding
>    procedure Setup(st: not null access Sub_Type;
>                    p :          access Sub_Type'Class);
> end Sub_Pkg;

Note that Sub_Type is not a subtype.

Sub_Pkg defines 2 procedures named Setup:

1. Implicitly, from the primitive Setup for Some_Type, with "not null 
access Sub_Type" and "access Some_Type'Class". The implementation of 
this is identical to the implementation of Pkg.Setup.

2. Explicitly, "not null access Sub_Type" and "access Sub_Type'Class", 
since it's "not overriding".

> with Pkg; use Pkg;
> with Sub_Pkg; use Sub_Pkg;
> procedure Test is
>    st: aliased Sub_Type;
> begin
>    st.Setup(null);
> end Test;

I would expect this to be ambiguous, since it matches the profile for 
both of the Setup procedures. If I'm correct, this would be a compiler 
error.

> Sorry in advance if it's a silly question, I have a huge background
> of C++ and not yet very skilled with Ada type system.

In the C/++ mind set, it's common to have visible pointers and pointer 
parameters all over the place. In the Ada mind set, access types, 
parameters, and values are avoided whenever possible, and hidden when 
not. This isolates memory management, making memory-management errors 
easier to find, and usually makes the package easier for the client to 
use. It's rare, in a well designed Ada system, to have access 
types/values/parameters in package specifications. There's probably a 
way to design your system to avoid having access parameters in the specs.

As an Ada beginner, you will probably find it valuable to avoid "use" 
clauses. This may seem like more work, but you will learn useful things 
that way. In this case, you have no need for Pkg at all, and so should 
not even "with" it; typing "Sub_Pkg." in the declaration of St is 
actually less work than typing " use Sub_Pkg;".

-- 
Jeff Carter
"Sir Robin the-not-quite-so-brave-as-Sir-Lancelot,
who had nearly fought the Dragon of Angnor,
who nearly stood up to the vicious Chicken of Bristol,
and who had personally wet himself at the
Battle of Badon Hill."
Monty Python & the Holy Grail
68



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-15 18:20   ` Yves Bailly
@ 2006-07-15 19:12     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2006-07-15 19:12 UTC (permalink / raw)


On Sat, 15 Jul 2006 20:20:58 +0200, Yves Bailly wrote:

> Dmitry A. Kazakov wrote:
>> What are you trying to achieve? The code looks wrong to me. Why are you
>> using access types in a procedure? Why do you want to overload two
>> different Setup? If the second parameter has to be covariant then Ada does
>> support it:
> 
> It's only a very reduced sample code, extracted from a much larger
> code base. The particular needs for access types are specific to
> this code base. That said, replace any "not null access" for the
> first parameters with "in out" and you'll get the same effect. The
> second parameter *has* to be an access type, as it can be null
> on purpose. See it as "parent object", in a tree-like structure
> (just to give an idea).

In that case yet another version of Setup without the second parameter
would be a better choice. Pointers aren't much Ada way.

Anyway that does no explain the motives, so it is difficult to say how to
solve it in an Ada way. As for workarounds and kludges, you can use a fully
qualified name the Setup you want to call to:

Sub_Pkg.Setup (st'Access, ...);

> I understand all of this might seem a little bit odd, now I really
> would like to understand what happens and why it's not the second
> Setup() (from Sub_Pkg) which is called.

See the post by Jeffrey Carter. It is probably a compiler bug, because the
program looks illegal.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-15 18:52 ` Jeffrey R. Carter
@ 2006-07-15 20:03   ` Yves Bailly
  2006-07-16  0:20     ` Jeffrey R. Carter
  0 siblings, 1 reply; 10+ messages in thread
From: Yves Bailly @ 2006-07-15 20:03 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> Note that Sub_Type is not a subtype.

Yes I know ;-) a better name would have been "Derived_Type" I guess.
 
> Sub_Pkg defines 2 procedures named Setup:
> 
> 1. Implicitly, from the primitive Setup for Some_Type, with "not null
> access Sub_Type" and "access Some_Type'Class". The implementation of
> this is identical to the implementation of Pkg.Setup.
> 
> 2. Explicitly, "not null access Sub_Type" and "access Sub_Type'Class",
> since it's "not overriding".

OK, now it's clearer for me. I hadn't perceived the "implicitiness" of
such packages/types structures.
 
> I would expect this to be ambiguous, since it matches the profile for
> both of the Setup procedures. If I'm correct, this would be a compiler
> error.

Actually, if I replace "st.Setup(null)" by "Sub_Pkg.Setup(st'Access, null)"
then I received an error, telling me it's ambiguous... which seems
sensible to me now and matches your comments. Maybe it's a compiler bug if
the error does not arise when using dotted notation, I'll send a message 
to GNAT developers.
 
> In the C/++ mind set, it's common to have visible pointers and pointer
> parameters all over the place. In the Ada mind set, access types,
> parameters, and values are avoided whenever possible, and hidden when
> not. This isolates memory management, making memory-management errors
> easier to find, and usually makes the package easier for the client to
> use. It's rare, in a well designed Ada system, to have access
> types/values/parameters in package specifications. There's probably a
> way to design your system to avoid having access parameters in the specs.

I understand this, several people already told this to me. So I guess
I'll review everything to hide pointers as much as possible. Thanks all
for your advices, though they imply more work than expected ;-)

> As an Ada beginner, you will probably find it valuable to avoid "use"
> clauses. This may seem like more work, but you will learn useful things
> that way. In this case, you have no need for Pkg at all, and so should
> not even "with" it

That's true, in fact it's just a remain of experiments.

> ; typing "Sub_Pkg." in the declaration of St is 
> actually less work than typing " use Sub_Pkg;".

Well, I'm not really a truely beginner in Ada, however my experience is
back to Ada83... There's a huge gap between Ada83 and Ada2005, but with
all your nice helps I'm sure I'll succeed in learning.

Thanks a lot all again for your help.

-- 
(o< | Yves Bailly  : http://kafka-fr.net   | -o)
//\ | Linux Dijon  : http://www.coagul.org | //\
\_/ |                                      | \_/`



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-15 20:03   ` Yves Bailly
@ 2006-07-16  0:20     ` Jeffrey R. Carter
  0 siblings, 0 replies; 10+ messages in thread
From: Jeffrey R. Carter @ 2006-07-16  0:20 UTC (permalink / raw)


Yves Bailly wrote:
> 
> Actually, if I replace "st.Setup(null)" by "Sub_Pkg.Setup(st'Access, null)"
> then I received an error, telling me it's ambiguous... which seems
> sensible to me now and matches your comments. Maybe it's a compiler bug if
> the error does not arise when using dotted notation, I'll send a message 
> to GNAT developers.

It does look like a compiler error, then.

> Well, I'm not really a truely beginner in Ada, however my experience is
> back to Ada83... There's a huge gap between Ada83 and Ada2005, but with
> all your nice helps I'm sure I'll succeed in learning.

Welcome back, then.

-- 
Jeff Carter
"From this day on, the official language of San Marcos will be Swedish."
Bananas
28



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-15 17:00 Trouble with overriding and class-wide parameters Yves Bailly
  2006-07-15 18:00 ` Dmitry A. Kazakov
  2006-07-15 18:52 ` Jeffrey R. Carter
@ 2006-07-16 10:00 ` Javier Miranda
  2006-07-16 12:11   ` Ludovic Brenta
  2 siblings, 1 reply; 10+ messages in thread
From: Javier Miranda @ 2006-07-16 10:00 UTC (permalink / raw)
  To: Yves Bailly; +Cc: comp.lang.ada


On Jul 15, 2006, at 1:00 PM, Yves Bailly wrote:

> Here's a problem I'm encountering, while developping a (rather
> huge) library using Ada 2005, for now using only the latest GNAT
> GPL compiler from AdaCore (i.e. GNAT-2006).
>
...
>
> I would expect the call to Setup() to invoke the Sub_Pkg.Setup()
> procedure, as "st" is of type Sub_Type. However the procedure
> actually called is Pkg.Setup(), as shown by the output :
> Pkg.Setup(Some_Type)
>
> What am I missing? I suspect the value "null" to be part of this,
> but I can't find a workaround.

This is a bug in the implementation of the Object.Operation notation
in the compiler because your call to Setup should be diagnosed as
ambiguous by the frontend.

The workaround is just to use the Ada95 procedural notation (instead
of the Ada 2005 object.operation notation). That is:

     Setup(st, null);

We take care of fixing this problem in the next release of the
compiler.

Regards,

---- Javier Miranda



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

* Re: Trouble with overriding and class-wide parameters
  2006-07-16 10:00 ` Javier Miranda
@ 2006-07-16 12:11   ` Ludovic Brenta
  2006-07-16 13:36     ` Javier Miranda
  0 siblings, 1 reply; 10+ messages in thread
From: Ludovic Brenta @ 2006-07-16 12:11 UTC (permalink / raw)


Javier Miranda <jmiranda@iuma.ulpgc.es> writes:
> This is a bug in the implementation of the Object.Operation notation
[...]
> We take care of fixing this problem in the next release of the
> compiler.

"We"?  Do you mean that people outside AdaCore actually contribute to
GNAT?

-- 
Ludovic Brenta.




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

* Re: Trouble with overriding and class-wide parameters
  2006-07-16 12:11   ` Ludovic Brenta
@ 2006-07-16 13:36     ` Javier Miranda
  0 siblings, 0 replies; 10+ messages in thread
From: Javier Miranda @ 2006-07-16 13:36 UTC (permalink / raw)
  To: Ludovic Brenta; +Cc: comp.lang.ada


On Jul 16, 2006, at 8:11 AM, Ludovic Brenta wrote:

>> We take care of fixing this problem in the next release of the
>> compiler.
>
> "We"?  Do you mean that people outside AdaCore actually contribute to
> GNAT?

I am part of the AdaCore development team (sorry to have not noticed
that I replied with my University mail address).

Regards,

--- Javier Miranda



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

end of thread, other threads:[~2006-07-16 13:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-15 17:00 Trouble with overriding and class-wide parameters Yves Bailly
2006-07-15 18:00 ` Dmitry A. Kazakov
2006-07-15 18:20   ` Yves Bailly
2006-07-15 19:12     ` Dmitry A. Kazakov
2006-07-15 18:52 ` Jeffrey R. Carter
2006-07-15 20:03   ` Yves Bailly
2006-07-16  0:20     ` Jeffrey R. Carter
2006-07-16 10:00 ` Javier Miranda
2006-07-16 12:11   ` Ludovic Brenta
2006-07-16 13:36     ` Javier Miranda

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