* container cursor type cannot be tagged
@ 2014-08-28 19:21 Stephen Leake
2014-08-28 20:25 ` Randy Brukardt
0 siblings, 1 reply; 9+ messages in thread
From: Stephen Leake @ 2014-08-28 19:21 UTC (permalink / raw)
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-28 19:21 container cursor type cannot be tagged Stephen Leake
@ 2014-08-28 20:25 ` Randy Brukardt
2014-08-29 7:28 ` Dmitry A. Kazakov
2014-08-29 14:50 ` Stephen Leake
0 siblings, 2 replies; 9+ messages in thread
From: Randy Brukardt @ 2014-08-28 20:25 UTC (permalink / raw)
"Stephen Leake" <stephen_leake@stephe-leake.org> wrote in message
news:85ppfkxvwg.fsf@stephe-leake.org...
> 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.
We of course noticed that when we originally designed the containers --
operations that only take cursors cannot be called in prefix notation.
Originally, neither the container nor the cursor was tagged for this reason,
but eventually we decided it was silly to make it impossible to use prefix
notation at all just because it can't always be used.
There doesn't seem to be a good solution that would allow the cursor to be
tagged. But even untagged, you can't sensible extend the container because
you really need to derive both the container and the cursor together. I
tried to come up with a solution that would make both the container and
cursor tagged, and would derive them in lock-step, but that gets to be a
problem if the inherited routines are also primitive on other types.
Full multiple dispatch would of course work, but we've talked about that
enough here. (Thanks Dmitry! :-)
...
> 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.
Non-dispatching, non-class-wide tagged parameters almost always represent a
bug in a program (we had a bunch in Claw, which tended to crash programs
that derived things like fonts [tag check failures]; eventually we
eliminated almost all of them). That's not so clear-cut for returns, but it
seems weird to have a feature that only works for returns.
> 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? If it's
untagged, you have the same problem about not allowing prefix notation, just
in reverse (OK for cursors, bad for containers). If it's tagged, then the
cursor can't be tagged. So I don't see much point in solving it at the
iterator level if you can't solve it for the container itself (much more
important).
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. (This is
much better if you're writing preconditions and especially global
declarations, since you can then refer directly to the container rather than
having it implicit. The Ada.Containers design is sub-optimal for
correctness, unfortunately.) In such a case, you wouldn't need a cursor to
be tagged.
You'd still want some sort of co-extension, however, (so a container
extension would get a new cursor type) which Ada doesn't support.
Randy.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-28 20:25 ` Randy Brukardt
@ 2014-08-29 7:28 ` Dmitry A. Kazakov
2014-08-29 7:59 ` J-P. Rosen
2014-08-29 23:08 ` Randy Brukardt
2014-08-29 14:50 ` Stephen Leake
1 sibling, 2 replies; 9+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-29 7:28 UTC (permalink / raw)
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-29 7:28 ` Dmitry A. Kazakov
@ 2014-08-29 7:59 ` J-P. Rosen
2014-08-29 8:46 ` Dmitry A. Kazakov
2014-08-29 23:08 ` Randy Brukardt
1 sibling, 1 reply; 9+ messages in thread
From: J-P. Rosen @ 2014-08-29 7:59 UTC (permalink / raw)
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-29 7:59 ` J-P. Rosen
@ 2014-08-29 8:46 ` Dmitry A. Kazakov
0 siblings, 0 replies; 9+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-29 8:46 UTC (permalink / raw)
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-28 20:25 ` Randy Brukardt
2014-08-29 7:28 ` Dmitry A. Kazakov
@ 2014-08-29 14:50 ` Stephen Leake
2014-08-29 23:00 ` Randy Brukardt
1 sibling, 1 reply; 9+ messages in thread
From: Stephen Leake @ 2014-08-29 14:50 UTC (permalink / raw)
"Randy Brukardt" <randy@rrsoftware.com> 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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-29 14:50 ` Stephen Leake
@ 2014-08-29 23:00 ` Randy Brukardt
2014-08-30 15:16 ` Stephen Leake
0 siblings, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2014-08-29 23:00 UTC (permalink / raw)
"Stephen Leake" <stephen_leake@stephe-leake.org> wrote in message
news:85d2bjxscf.fsf@stephe-leake.org...
> "Randy Brukardt" <randy@rrsoftware.com> 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.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-29 7:28 ` Dmitry A. Kazakov
2014-08-29 7:59 ` J-P. Rosen
@ 2014-08-29 23:08 ` Randy Brukardt
1 sibling, 0 replies; 9+ messages in thread
From: Randy Brukardt @ 2014-08-29 23:08 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> 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.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: container cursor type cannot be tagged
2014-08-29 23:00 ` Randy Brukardt
@ 2014-08-30 15:16 ` Stephen Leake
0 siblings, 0 replies; 9+ messages in thread
From: Stephen Leake @ 2014-08-30 15:16 UTC (permalink / raw)
"Randy Brukardt" <randy@rrsoftware.com> writes:
> "Stephen Leake" <stephen_leake@stephe-leake.org> wrote in message
> news:85d2bjxscf.fsf@stephe-leake.org...
>> "Randy Brukardt" <randy@rrsoftware.com> 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),
It returns Cursor'class.
> Using Cursor'Class in this circumstance is a lie (there never will be any
> derived types that work)
Right. But I don't care about derived types; Container and Cursor are
tagged _only_ to allow using Object.Method.
> and of course forces checking to runtime (or not at all).
Yes. Which is why the Controlling_Type aspect is a better solution.
--
-- Stephe
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2014-08-30 15:16 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-28 19:21 container cursor type cannot be tagged Stephen Leake
2014-08-28 20:25 ` Randy Brukardt
2014-08-29 7:28 ` Dmitry A. Kazakov
2014-08-29 7:59 ` J-P. Rosen
2014-08-29 8:46 ` Dmitry A. Kazakov
2014-08-29 23:08 ` Randy Brukardt
2014-08-29 14:50 ` Stephen Leake
2014-08-29 23:00 ` Randy Brukardt
2014-08-30 15:16 ` Stephen Leake
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox