Mega Search
23.2 Million


Sign Up

Make a donation  
container cursor type cannot be tagged  
News Group: comp.lang.ada

In trying to build my own container package, I ran into a problem; the
Cursor type cannot be tagged. Which means we can't use "Cursor.op"
notation, which I've grown to really like.

The reason it can't be tagged is these two functions defined by
Ada.Iterator_Interfaces (and similar ones for reverse iteration):

   overriding function First (Object : Iterator) return Cursor;
   overriding function Next
     (Object   : Iterator;
      Position : Cursor)
     return Cursor;

Iterator is a tagged type, so Cursor can't be; Ada 2012 doesn't support
dispatching on multiple tagged types (LRM 3.9.3 12).

One solution to this is to define a new aspect Controlling_Type:

   overriding function First (Object : Iterator) return Cursor
   with Controlling_Type => Iterator;

which says to not use Cursor to dispatch calls to this subprogram. That
would be useful in other similar situations. I didn't find an AI on this
issue; would this be worth a proposal?

Another solution would be to provide another version of
Ada.Iterator_Interfaces, where Cursor is explicitly tagged, and these
functions use Cursor'Class. That seems more of a kludge.

-- 
-- Stephe

Vote for best question.
Score: 0  # Vote:  0
Date Posted: 28-Aug-2014, at 2:21 PM EST
From: Stephen Leake
 
Re: container cursor type cannot be tagged  
News Group: comp.lang.ada
"Dmitry A. Kazakov"  wrote in message 
news:c8utnmednhss.tg5692sifke0$.dlg@40tude.net...
> On Thu, 28 Aug 2014 15:25:59 -0500, Randy Brukardt wrote:
>
>> If it was me, I'd put a container parameter on every operation (which 
>> would
>> be the prefix), and cursors would work soley like array indexes.
>
> Huh, remember our discussion about cursor/iterator being a bad idea?

No sorry, I don't. But I do know that I was against that model of cursors 
from the beginning; I just wasn't able to explain why well enough to 
convince anyone else.

> That is another of multiple reasons why. Cursor tend to become a full 
> class
> with descendants and primitive operations which ends up in multiple
> dispatch, for whatever reason not available. An index almost always can be
> a "final" type which makes everything a lot easier.

But please note that iterators are a very different case. They necessarily 
encapsulate some state and that state is intimately tied to the container --  
it doesn't make sense to separate them.

Also note that a cursor would always need to include some indication of the 
container it belongs to, in order that the library can prevent using the 
cursor with the wrong container. Since these are almost always going to be 
implemented as wrapped access types, using one with the wrong container 
would lead to havoc. (And one of the most important properties of the Ada 
containers is that they never cause more havoc than a bare, fully checked 
array could.)

The problem comes from using the cursor separately from the container, not 
so much from the fact that cursors know their containers. (The indication 
does not need to be a pointer in this model, a serial number would be 
enough, so just because there is an indication doesn't mean that one could 
use the cursor without the container.)

                                                        Randy.



Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 6:08 PM EST
From: Randy Brukardt
 
Re: container cursor type cannot be tagged  
News Group: comp.lang.ada
"Stephen Leake"  wrote in message 
news:85d2bjxscf.fsf@stephe-leake.org...
> "Randy Brukardt"  writes:
>> That seems to make more sense, honestly. But how are you dealing with the
>> "can't have two tagged types" problem for the container itself?
>
> I don't see the problem; I declared my container with tagged container
> and cursor, and only had a problem when I tried to instantiate
> Ada.Iterator_Interfaces.

How did you do that? Any operation that takes a container and a cursor is 
illegal if both are tagged. I don't see how you could have a constructor for 
a cursor in that case (it must at least take a container and return a 
cursor), and operations involving container updates could work as 
cursor-only operations but are dangerous (because they would allow writing 
constant containers).

Using Cursor'Class in this circumstance is a lie (there never will be any 
derived types that work) and of course forces checking to runtime (or not at 
all).

                                  Randy.




Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 6:00 PM EST
From: Randy Brukardt
 
Re: container cursor type cannot be tagged  
News Group: comp.lang.ada
"Randy Brukardt"  writes:

>> One solution to this is to define a new aspect Controlling_Type:
>>
>>   overriding function First (Object : Iterator) return Cursor
>>   with Controlling_Type => Iterator;
>>
>> which says to not use Cursor to dispatch calls to this subprogram. That
>> would be useful in other similar situations. I didn't find an AI on this
>> issue; would this be worth a proposal?
>
> Well, that's up to you. I'd think it's pretty weird; if one really wants a 
> non-dispatching parameter, it should be declared as class-wide. 

Ok; at least you didn't say "we looked at that and it won't work because ...".

>> Another solution would be to provide another version of
>> Ada.Iterator_Interfaces, where Cursor is explicitly tagged, and these
>> functions use Cursor'Class. That seems more of a kludge.
>
> That seems to make more sense, honestly. But how are you dealing with the 
> "can't have two tagged types" problem for the container itself? 

I don't see the problem; I declared my container with tagged container
and cursor, and only had a problem when I tried to instantiate
Ada.Iterator_Interfaces. 

On the other hand, I hope that the Controlling_Type aspect could be used
to resolve any problems due to multiple tagged types.

I agree that deriving from the container and cursor together is not a
solved problem. This arises from the confusion of "derivable" and "can
use object.method" features; both depend on the type being tagged. In my
case, I don't care about further derivation, but I do care about
object.method. So my solution is just to say "this container design is
not intended to support derived containers". Perhaps we need to borrow
"final" from C++11/Java?

-- 
-- Stephe

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 9:50 AM EST
From: Stephen Leake
 
Re: container cursor type cannot be tagged  
News Group: comp.lang.ada
On Fri, 29 Aug 2014 09:59:03 +0200, J-P. Rosen wrote:

> Le 29/08/2014 09:28, Dmitry A. Kazakov a écrit :
>> That is another of multiple reasons why. Cursor tend to become a full class
>> with descendants and primitive operations which ends up in multiple
>> dispatch, for whatever reason not available. An index almost always can be
>> a "final" type which makes everything a lot easier.
> 
> Could you elaborate on what (in your view) is the difference between a
> cursor and an index?

Unlike index cursor/iterator carries the object's identity. It alone is
sufficient to access the element. This logically decouples it (and the
element as well) from the container. Any link to the container gets hidden.
The identity is assumed invariant to container updates, which is only a
felt invariant, since it cannot be statically enforced. All this has far
reaching consequences for the usage, design and implementation.

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

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 10:46 AM EST
From: Dmitry A. Kazakov
 
Re: container cursor type cannot be tagged  
News Group: comp.lang.ada
Le 29/08/2014 09:28, Dmitry A. Kazakov a écrit :
> That is another of multiple reasons why. Cursor tend to become a full class
> with descendants and primitive operations which ends up in multiple
> dispatch, for whatever reason not available. An index almost always can be
> a "final" type which makes everything a lot easier.

Could you elaborate on what (in your view) is the difference between a
cursor and an index?

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 9:59 AM EST
From: J-P. Rosen
 
Re: container cursor type cannot be tagged  
News Group: comp.lang.ada
On Thu, 28 Aug 2014 15:25:59 -0500, Randy Brukardt wrote:

> If it was me, I'd put a container parameter on every operation (which would 
> be the prefix), and cursors would work soley like array indexes.

Huh, remember our discussion about cursor/iterator being a bad idea?

That is another of multiple reasons why. Cursor tend to become a full class
with descendants and primitive operations which ends up in multiple
dispatch, for whatever reason not available. An index almost always can be
a "final" type which makes everything a lot easier.

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

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 29-Aug-2014, at 9:28 AM EST
From: Dmitry A. Kazakov