comp.lang.ada
 help / color / mirror / Atom feed
* RE: Proposed change to BC iterator parameters
@ 2003-12-10 13:36 amado.alves
  2003-12-10 16:47 ` Proposed change to BC iterator parameters [limitedness] Georg Bauhaus
                   ` (4 more replies)
  0 siblings, 5 replies; 46+ messages in thread
From: amado.alves @ 2003-12-10 13:36 UTC (permalink / raw)
  To: Simon Wright, comp.lang.ada

<<...
   generic
      type Param_Type is private;
      with procedure Apply (Elem : in Item;
                            Param : in Param_Type;
                            OK : out Boolean);
   procedure Visit_With_In_Param (Using : in out Iterator'Class;
                                  Param : in Param_Type);
>>

I've never found a situation where the following much simpler signature wouldn't suffice:

   generic
      with procedure Apply (Elem : in Item);
   procedure Visit_With_In_Param (Using : in out Iterator'Class);

with premature termination of the iteration done by raising inside Apply an exception which Visit_With_In_Param propagates by definition.

<<...      type Param_Type (<>) is limited private;

As I understand it, this allows users much more freedom (you can even
use a tagged type provided you instantiate with Tagged_Type'Class)...>>

Strictly you don't need the limited formal for (unlimited) tagged or class actuals. You need the limited formal for limited actuals, whatever their class. Limitedness is completely orthogonal to definiteness. I do like indefinite formals, but I pass well without limited ones. Most limited formals I've seen in libraries are accompanied by a formal assignment operation or some such, which prety much defeats the purpose of their (formal) limitedness, i.e. their logic is in clash with their definition.




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

* Re: Proposed change to BC iterator parameters [limitedness]
  2003-12-10 13:36 Proposed change to BC iterator parameters amado.alves
@ 2003-12-10 16:47 ` Georg Bauhaus
  2003-12-10 17:39 ` Proposed change to BC iterator parameters Martin Krischik
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 46+ messages in thread
From: Georg Bauhaus @ 2003-12-10 16:47 UTC (permalink / raw)


amado.alves <amado.alves@netcabo.pt> wrote:
: 
:
: I do like indefinite formals, but I pass well
: without limited ones. Most limited formals I've seen in libraries
: are accompanied by a formal assignment operation or some such,
: which prety much defeats the purpose of their (formal) limitedness,
: i.e. their logic is in clash with their definition. 

Sometimes I dearly wanted limited records but was defeated
by the library that could not store them (storing them was the
intention):

  type T(x: access D) is tagged limited private;

I want x to be constant plus initialised once and for all,
so access discriminants are just fine, but T has to
be limited then. Which would have been o.K., but not every library
allows this.

What should I do? Use pointers to the records? Afaics, this leads to
allocators or library level declarations (not always possible when
an unkown number of objects' lives start during the program's run?)
or 'unchecked_access.

Or use record compontens of
  type D_Ptr is access constant D;
and get rid of the access discriminants, and have a definite type?
How do I prevent then that tagged records can be declared but not
initialised?

Any suggestion would be very welcome.


Thanks,
-- Georg



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

* RE: Proposed change to BC iterator parameters
  2003-12-10 13:36 Proposed change to BC iterator parameters amado.alves
  2003-12-10 16:47 ` Proposed change to BC iterator parameters [limitedness] Georg Bauhaus
@ 2003-12-10 17:39 ` Martin Krischik
  2003-12-10 18:22 ` Jeffrey Carter
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 46+ messages in thread
From: Martin Krischik @ 2003-12-10 17:39 UTC (permalink / raw)


amado.alves wrote:

> indefinite formals, but I pass well without limited ones. Most limited
> formals I've seen in libraries are accompanied by a formal assignment
> operation or some such, which prety much defeats the purpose of their
> (formal) limitedness, i.e. their logic is in clash with their definition.

Well there is one exception here. It's File_Type. I can see the need to
write a container to a file with the help of an iterator. Here limited
might help.

Remember: we talk about an extra parameter to the iterator and not about the
data stored inside the container.

With Regards

Martin

-- 
mailto://krischik@users.sourceforge.net
http://adacl.sourceforge.net




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

* RE: Proposed change to BC iterator parameters [limitedness]
@ 2003-12-10 17:53 amado.alves
  2003-12-10 18:47 ` Georg Bauhaus
  2003-12-11 15:48 ` Robert A Duff
  0 siblings, 2 replies; 46+ messages in thread
From: amado.alves @ 2003-12-10 17:53 UTC (permalink / raw)
  To: comp.lang.ada

<<Sometimes I dearly wanted limited records but was defeated
by the library that could not store them (storing them was the
intention):...>>

I think there are (container) libraries that accept limited element types. And some libs that dont can easily (?) be changed in that direction. But as I indicated I think it is 'unatural' to store values of a limited type. For me it does not make sense to put constants in a container. So my advice can only be: rethink your program.




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

* Re: Proposed change to BC iterator parameters
  2003-12-10 13:36 Proposed change to BC iterator parameters amado.alves
  2003-12-10 16:47 ` Proposed change to BC iterator parameters [limitedness] Georg Bauhaus
  2003-12-10 17:39 ` Proposed change to BC iterator parameters Martin Krischik
@ 2003-12-10 18:22 ` Jeffrey Carter
  2003-12-10 23:00   ` Robert A Duff
  2003-12-10 20:50 ` Simon Wright
  2003-12-10 23:12 ` Robert A Duff
  4 siblings, 1 reply; 46+ messages in thread
From: Jeffrey Carter @ 2003-12-10 18:22 UTC (permalink / raw)


amado.alves wrote:

> Strictly you don't need the limited formal for (unlimited) tagged or
> class actuals. You need the limited formal for limited actuals,
> whatever their class. Limitedness is completely orthogonal to
> definiteness. I do like indefinite formals, but I pass well without
> limited ones. Most limited formals I've seen in libraries are
> accompanied by a formal assignment operation or some such, which
> prety much defeats the purpose of their (formal) limitedness, i.e.
> their logic is in clash with their definition.

The problem is that a generic formal part is a specification; it 
specifies what the generic needs, and the client must provide, for the 
generic to do its work. "Limited" implies 2 unrelated concepts: absence 
of assignment, and absence of predefined equality. To specify that the 
generic needs to be able to assign objects of a formal type, but does 
not need to perform equality comparisons, can only be done correctly 
with a limited private formal type, and a formal Assign procedure.

A non-limited formal type specifies that the generic needs to perform 
equality comparisons on values of the type, which is an error in 
specification. I know this seems a minor issue to many people, but 
precise specifications are essential to ensuring the correct usage of 
reusable components by their clients.

This connection between assignment and equality may have made sense in 
Ada 83, where equality could only be defined for limited types, but 
seems an unnecessary restriction in Ada 95.

In hindsight, it would have been better to eliminate the "limited" 
reserved word completely, and use instead

type T is private;
-- Same as Ada's "limited private"

type T is private with ":=";
-- Assignment defined; "=" not; no Ada equivalent

with the capability of defining "=" for either type.

-- 
Jeff Carter
"Perfidious English mouse-dropping hoarders."
Monty Python & the Holy Grail
10




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

* Re: Proposed change to BC iterator parameters [limitedness]
  2003-12-10 17:53 Proposed change to BC iterator parameters [limitedness] amado.alves
@ 2003-12-10 18:47 ` Georg Bauhaus
  2003-12-11 15:48 ` Robert A Duff
  1 sibling, 0 replies; 46+ messages in thread
From: Georg Bauhaus @ 2003-12-10 18:47 UTC (permalink / raw)


amado.alves <amado.alves@netcabo.pt> wrote:
: <<Sometimes I dearly wanted limited records but was defeated
: by the library that could not store them (storing them was the
: intention):...>>
: 
: I think there are (container) libraries that accept limited
element types.

Charles does (some of it).

: And some libs that dont can easily (?) be changed
: in that direction.  But as I indicated I think it is 'unatural'
: to store values of a limited type. For me it does not make sense
: to put constants in a container. So my advice can only be: rethink
: your program.

I tried, limitedness is only an implication of having access
discriminants in tagged types, which fulfil the requirements
(see type T below):
- "There are three constant links to other objects in these objects".
- "You will have to provide initial values for these links, we cannot
   have dangling pointers here.".

given

  type T
    (look_here: access D;
     look_there: access E;
     and_also_over_there: access D)
  is tagged limited
      record
	 variable_part_1: Some_Type;
	 variable_part_2: Some_Other_Type;
      end record;
   
  ...

The thing is not that I want to store constant instances of
T, I will have to have instances available with both constant
component parts and variable component parts, as above.  To me,
this type seemed natural.  Or is it not, given the requirements
from above?

Where do I store these instances? They must live somewhere...

The "solutions" I have now are using a _comment_ indicating that
clients _should_ use a constructor function, here is one of the
solutions that doesn't use pointers to T objects:

   type T is tagged private;
   --  use make!

   function make
    (look_here: D;
     look_there: E;
     and_also_over_there: D) return T;

where the full view of T contains pointer fields, and make provides
'(unchecked)_access values for them.  But "--  use make!" is not
enforcable by a compiler, while

   type T(<>) is tagged limited private;

or some such will not allow me or anyone else to declare T objects
without initialisation (for any access parameters). Which is what
I found desirable, I can then rely on the language and assume
that T instances will have been initialised, without relying on
programmers obeying a comment about a related function.


I'm stuck.
(Thinking around corners: deriving a definite T from Controlled
inside a generic wich has make(...) from above as a formal subprogram
wich is then called during Initialise of T?  Phew...)

-- Georg



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

* RE: Proposed change to BC iterator parameters [limitedness]
@ 2003-12-10 19:20 amado.alves
  2003-12-11 13:10 ` Marin David Condic
  0 siblings, 1 reply; 46+ messages in thread
From: amado.alves @ 2003-12-10 19:20 UTC (permalink / raw)
  To: comp.lang.ada

<<: I think there are (container) libraries that accept limited
element types.

Charles does (some of it).>>

So perhaps you should consider using it.

<<
: ...For me it does not make sense
: to put constants in a container. So my advice can only be: rethink
: your program.

I tried, limitedness is only an implication of having access
discriminants in tagged types...>>

I know. Big annoyance of Ada. The root of all 'unnaturalness'. Often I also end up specifying things 'above' the language like you did with "Make".




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

* RE: Proposed change to BC iterator parameters [limitedness]
@ 2003-12-10 19:33 amado.alves
  0 siblings, 0 replies; 46+ messages in thread
From: amado.alves @ 2003-12-10 19:33 UTC (permalink / raw)
  To: comp.lang.ada

<<
  type T
    (look_here: access D;
     look_there: access E;
     and_also_over_there: access D)
  is tagged limited...
>>

Since your working with a container library anyway a cleaner solution might be to create containers for types D and E and replace the access discriminants above with the corresponding pointers (iterators).




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

* Re: Proposed change to BC iterator parameters
  2003-12-10 13:36 Proposed change to BC iterator parameters amado.alves
                   ` (2 preceding siblings ...)
  2003-12-10 18:22 ` Jeffrey Carter
@ 2003-12-10 20:50 ` Simon Wright
  2003-12-10 23:12 ` Robert A Duff
  4 siblings, 0 replies; 46+ messages in thread
From: Simon Wright @ 2003-12-10 20:50 UTC (permalink / raw)


"amado.alves" <amado.alves@netcabo.pt> writes:

> <<...
>    generic
>       type Param_Type is private;
>       with procedure Apply (Elem : in Item;
>                             Param : in Param_Type;
>                             OK : out Boolean);
>    procedure Visit_With_In_Param (Using : in out Iterator'Class;
>                                   Param : in Param_Type);
> >>
> 
> I've never found a situation where the following much simpler
> signature wouldn't suffice:
> 
>    generic
>       with procedure Apply (Elem : in Item);
>    procedure Visit_With_In_Param (Using : in out Iterator'Class);

That is there as well (as you note below, without _With_In_Param!)

-- 
Simon Wright                               100% Ada, no bugs.



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

* Re: Proposed change to BC iterator parameters
  2003-12-10 18:22 ` Jeffrey Carter
@ 2003-12-10 23:00   ` Robert A Duff
  2003-12-11  1:00     ` Jeffrey Carter
  2003-12-11  8:33     ` Dmitry A. Kazakov
  0 siblings, 2 replies; 46+ messages in thread
From: Robert A Duff @ 2003-12-10 23:00 UTC (permalink / raw)


Jeffrey Carter <spam@spam.com> writes:

> amado.alves wrote:
> 
> > Strictly you don't need the limited formal for (unlimited) tagged or
> > class actuals. You need the limited formal for limited actuals,
> > whatever their class. Limitedness is completely orthogonal to
> > definiteness. I do like indefinite formals, but I pass well without
> > limited ones. Most limited formals I've seen in libraries are
> > accompanied by a formal assignment operation or some such, which
> > prety much defeats the purpose of their (formal) limitedness, i.e.
> > their logic is in clash with their definition.
> 
> The problem is that a generic formal part is a specification; it
> specifies what the generic needs, and the client must provide, for the
> generic to do its work. "Limited" implies 2 unrelated concepts: absence
> of assignment, and absence of predefined equality.

I agree with you here, but I can't get too excited about this particular
case, because similar problems exist for many Ada types.  Whenever you
declare a type, you get some predefined operations.  You can't say (for
an integer type), "I want predefined + but not predefined -".  It would
be nice to be able to express that, and as you point out, it would be
nice to be able to express "I want := but not predefined =".

You can use private types, and define + but not -, but then you can't
say "I want case_statements, integer literals, and +, but not - * /
etc".

Anyway, the key point of "limited" is that you can't copy things.  The
"=" issue is a more minor one, I think.

A much bigger problem with "limited" is that you can't have aggregates
and constructor functions, and you can't initialize objects.  As Robert
Eachus pointed out in some other thread, the ARG is actively working on
this.

> A non-limited formal type specifies that the generic needs to perform
> equality comparisons on values of the type, which is an error in
> specification. I know this seems a minor issue to many people, but
> precise specifications are essential to ensuring the correct usage of
> reusable components by their clients.

I agree, but I also want to be able to declare an integer type that can
only be incremented and not decremented or multiplied.  (And still allow
literals and case statements.)  It's a similar issue.

> This connection between assignment and equality may have made sense in
> Ada 83, where equality could only be defined for limited types, but
> seems an unnecessary restriction in Ada 95.

The Goodenough trick actually allowed declaring "=" on limited types in
Ada 83.

> In hindsight, it would have been better to eliminate the "limited"
> reserved word completely, and use instead
> 
> type T is private;
> -- Same as Ada's "limited private"
> 
> type T is private with ":=";
> -- Assignment defined; "=" not; no Ada equivalent
> 
> with the capability of defining "=" for either type.

Maybe.  How would you extend this to the integer-type issues I mentioned
above?  "Case statement" is not an operator...
Anyway, even if we restricted it to operators, it could get rather
verbose.  Saying "type T is range 1..10" is a concise way of defining
a bunch of operations, and if you don't want all of them, well, is that
good or bad?

Here, I think you're talking about regular private types in
packages (as opposed to generic formals).  One idea is to say:

    type T is private;
    function "="(X, Y: T) return Boolean is abstract;

Then clients can't call predefined "=".

(But predefined "=" reemerges in generics!  And records.)

I've also done things like this (in the visible part):

    type T is private;

    function Predefined_Equal(X, Y: T) return Boolean renames "=";
    -- For use only in the package body!

    function "="(X, Y: T) return Boolean is abstract;

Unfortunately, the Ada compiler does not understand the comment, "-- For
use only in the package body!".  You say above, ``with the capability of
defining "=" for either type.''  But it's not trivial to make that "="
be the predefined one.

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-10 13:36 Proposed change to BC iterator parameters amado.alves
                   ` (3 preceding siblings ...)
  2003-12-10 20:50 ` Simon Wright
@ 2003-12-10 23:12 ` Robert A Duff
  2003-12-11  5:07   ` Steve
  4 siblings, 1 reply; 46+ messages in thread
From: Robert A Duff @ 2003-12-10 23:12 UTC (permalink / raw)


"amado.alves" <amado.alves@netcabo.pt> writes:

> <<...
>    generic
>       type Param_Type is private;
>       with procedure Apply (Elem : in Item;
>                             Param : in Param_Type;
>                             OK : out Boolean);
>    procedure Visit_With_In_Param (Using : in out Iterator'Class;
>                                   Param : in Param_Type);
> >>
> 
> I've never found a situation where the following much simpler signature wouldn't suffice:
> 
>    generic
>       with procedure Apply (Elem : in Item);
>    procedure Visit_With_In_Param (Using : in out Iterator'Class);
> 
> with premature termination of the iteration done by raising inside
> Apply an exception which Visit_With_In_Param propagates by
> definition. 

Yeah, that works.  It's not very efficient (in most implementations).
If you want to stop the loop as soon as you found the thing you're
looking for, it's quite likely that the exception-handling overhead is
more than the cost of letting the loop keep going to the end.

Ada really doesn't have very good support for iterators.  This is one
example.  The iterator abstraction should not have to worry about
premature exits -- the loop code should just jump out of the loop.
A goto statement would be better than an exception here, because you're
going to a specific place (as opposed to raising an exception that could
be handled who-knows-where).  You can do that in Pascal, but Ada doesn't
allow gotos out of procedures (for good reason -- consider a procedure
called by a nested task).

(Goto haters should consider that exceptions are just like gotos, except
you don't know statically where they're going to -- i.e., exceptions are
*worse* than gotos, from a structured programming point of view.)

I don't understand the point of Param_Type and Param above.  If you want
to pass extra information to Apply, nest the instantiation in a place
where it can see that data.

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-10 23:00   ` Robert A Duff
@ 2003-12-11  1:00     ` Jeffrey Carter
  2003-12-11 15:09       ` Robert A Duff
  2003-12-11  8:33     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 46+ messages in thread
From: Jeffrey Carter @ 2003-12-11  1:00 UTC (permalink / raw)


Robert A Duff wrote:

> Anyway, the key point of "limited" is that you can't copy things.  The
> "=" issue is a more minor one, I think.

My point exactly.

> Jeffrey Carter <spam@spam.com> writes:

>>In hindsight, it would have been better to eliminate the "limited"
>>reserved word completely, and use instead
>>
>>type T is private;
>>-- Same as Ada's "limited private"
>>
>>type T is private with ":=";
>>-- Assignment defined; "=" not; no Ada equivalent
>>
>>with the capability of defining "=" for either type.
 >
> Here, I think you're talking about regular private types in
> packages (as opposed to generic formals).  One idea is to say:

I was thinking about both.

> Unfortunately, the Ada compiler does not understand the comment, "-- For
> use only in the package body!".  You say above, ``with the capability of
> defining "=" for either type.''  But it's not trivial to make that "="
> be the predefined one.

If we had a syntax like that I described, there would be no predefined 
"=" for either kind of type.

One can think about all kinds of constraints on types, such as the 
integer types you mentioned. It would be nice to have unconstrained 
arrays with a fixed lower bound*:

type String_From_1 is array (Positive range 1 .. <>) of Character;

I don't expect to see major changes of this sort. Where do you stop? 
Should you allow arrays with a fixed upper bound?

* Ada sort of has this:

type String_From_1 (Length : Natural) is record
    Value : String (1 .. Length);
end record;

-- 
Jeff Carter
"Perfidious English mouse-dropping hoarders."
Monty Python & the Holy Grail
10




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

* Re: Proposed change to BC iterator parameters
  2003-12-10 23:12 ` Robert A Duff
@ 2003-12-11  5:07   ` Steve
  2003-12-11 15:24     ` Robert A Duff
  2003-12-12  5:29     ` Simon Wright
  0 siblings, 2 replies; 46+ messages in thread
From: Steve @ 2003-12-11  5:07 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wccekvc2rol.fsf@shell01.TheWorld.com...
[snip]
>
> I don't understand the point of Param_Type and Param above.  If you want
> to pass extra information to Apply, nest the instantiation in a place
> where it can see that data.

The reason for Param_Type and Param is to avoid using data outside of the
scope of the Apply routine except for the arguments to the Apply machine.
It comes from that old school of thought:
  Avoid global data
  All inputs and outputs of a procedure should appear in their parameter
lists

Following these simple guidelines usually makes code a lot easier to follow.

Steve
(The Duck)

>
> - Bob





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

* Re: Proposed change to BC iterator parameters
  2003-12-10 23:00   ` Robert A Duff
  2003-12-11  1:00     ` Jeffrey Carter
@ 2003-12-11  8:33     ` Dmitry A. Kazakov
  1 sibling, 0 replies; 46+ messages in thread
From: Dmitry A. Kazakov @ 2003-12-11  8:33 UTC (permalink / raw)


On 10 Dec 2003 18:00:31 -0500, Robert A Duff
<bobduff@shell01.TheWorld.com> wrote:

>Here, I think you're talking about regular private types in
>packages (as opposed to generic formals).  One idea is to say:
>
>    type T is private;
>    function "="(X, Y: T) return Boolean is abstract;
>
>Then clients can't call predefined "=".
>
>(But predefined "=" reemerges in generics!  And records.)
>
>I've also done things like this (in the visible part):
>
>    type T is private;
>
>    function Predefined_Equal(X, Y: T) return Boolean renames "=";
>    -- For use only in the package body!
>
>    function "="(X, Y: T) return Boolean is abstract;
>
>Unfortunately, the Ada compiler does not understand the comment, "-- For
>use only in the package body!".  You say above, ``with the capability of
>defining "=" for either type.''  But it's not trivial to make that "="
>be the predefined one.

Sticking to implemetation inheritance is the actual problem. Why do
not we have true abstract interfaces? For example:

type Can_Do_Nothing is <interface-keyword>;

type Can_Only_Compare is <interface-keyword>;
function "=" (X, Y : Can_Only_Compare) return Boolean is abstract;

type Can_Copy_Assign_Compare is <interface-keyword>;
<some-syntactic-sugar-defining-abstract-copy-constructor>
<some-syntactic-sugar-defining-abstract-assignment>
function "=" (X, Y : Can_Copy_Assign_Compare)
   return Boolean is abstract;
...

Then an integer without predefined arithmetic could be an
implementation of Can_Copy_Assign_Compare via private inheritance from
Integer :

   type My_Number is new private Can_Copy_Assign_Compare;
private
   type My_Number is new Integer;
   
--
Regards,
Dmitry Kazakov
http://www.dmitry-kazakov.de



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

* Re: Proposed change to BC iterator parameters [limitedness]
  2003-12-10 19:20 amado.alves
@ 2003-12-11 13:10 ` Marin David Condic
  2003-12-11 17:59   ` Jeffrey Carter
  2003-12-12  5:58   ` Simon Wright
  0 siblings, 2 replies; 46+ messages in thread
From: Marin David Condic @ 2003-12-11 13:10 UTC (permalink / raw)


Here's a question because I have not looked at either of these libraries 
  in any detail: Does either Charles or Booch support some kind of 
persistance of objects? By which I mean do they store/retrieve from a 
file or serialize to/from a stream such that they could be put into a 
file readily?

MDC

amado.alves wrote:

> 
> Charles does (some of it).>>
> 
> So perhaps you should consider using it.
> 


-- 
======================================================================
Marin David Condic
I work for: http://www.belcan.com/
My project is: http://www.jsf.mil/NSFrames.htm

Send Replies To: m   o   d   c @ a   m   o   g
                    c   n   i       c   .   r

     "Trying is the first step towards failure."
         --  Homer Simpson

======================================================================




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

* Re: Proposed change to BC iterator parameters
  2003-12-11  1:00     ` Jeffrey Carter
@ 2003-12-11 15:09       ` Robert A Duff
  0 siblings, 0 replies; 46+ messages in thread
From: Robert A Duff @ 2003-12-11 15:09 UTC (permalink / raw)


Jeffrey Carter <spam@spam.com> writes:

> If we had a syntax like that I described, there would be no predefined
> "=" for either kind of type.

Then how do you write the body of the user-defined "="?

> One can think about all kinds of constraints on types, such as the
> integer types you mentioned. It would be nice to have unconstrained
> arrays with a fixed lower bound*:
> 
> type String_From_1 is array (Positive range 1 .. <>) of Character;

Indeed.  I think the way to do that would be to eliminate the "range <>"
syntax, and allow arrays types to have discriminants.  So the index
subtype would be given as a name, or a "name range
expression..expression", where either expression can refer to a
discrimant.  Like this:

  type String(Last: Natural) is array (Positive range 1 .. Last) of Character;

Instead of X'Last, one would say X.Last.  This seems simpler than having
special syntax "range <>", and then extending that to "range 1..<>"
and "range <>..10".

Something like that was proposed during the Ada 9X project.

> I don't expect to see major changes of this sort.

No, I don't expect that particular change in the next Ada.

>... Where do you stop?

You don't, I suppose.  Fortran is much older than Ada, and they keep
coming out with major revisions of Fortran.

> Should you allow arrays with a fixed upper bound?

Of course.  To disallow that would be an arbitrary restriction,
not a simplification (presuming you're going to allow fixed
lower bounds).

> * Ada sort of has this:
> 
> type String_From_1 (Length : Natural) is record
>     Value : String (1 .. Length);
> end record;

Sort of.  The syntax for string literals and slices becomes pretty awful.

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-11  5:07   ` Steve
@ 2003-12-11 15:24     ` Robert A Duff
  2003-12-11 17:39       ` Jeffrey Carter
  2003-12-12  5:29     ` Simon Wright
  1 sibling, 1 reply; 46+ messages in thread
From: Robert A Duff @ 2003-12-11 15:24 UTC (permalink / raw)


"Steve" <nospam_steved94@comcast.net> writes:

> "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
> news:wccekvc2rol.fsf@shell01.TheWorld.com...
> [snip]
> >
> > I don't understand the point of Param_Type and Param above.  If you want
> > to pass extra information to Apply, nest the instantiation in a place
> > where it can see that data.
> 
> The reason for Param_Type and Param is to avoid using data outside of the
> scope of the Apply routine except for the arguments to the Apply machine.
> It comes from that old school of thought:
>   Avoid global data
>   All inputs and outputs of a procedure should appear in their parameter
> lists
> 
> Following these simple guidelines usually makes code a lot easier to follow.

The data we're talking about is not *very* global.  It's local to the
procedure containing the instantiation.  Yes, it's global to the actual
procedure passed to Apply, but that's probably a pretty small region of
code.

This seems like a lot of mechanism for little if any gain.  Consider
what you have to do if you want to pass *two* parameters.  You have to
wrap them in a record type, fill in the record fields, extract them out.
Seems verbose and error prone, to me.

Do you really follow the above guideline *strictly*?  It seems to me a
useful guideline in many cases, but there are many cases where it would
be damaging.  For example, consider a package that behaves like what
Lisp calls "symbols".  The Intern routine puts a string in a hash table,
and returns a unique identifier of that string (so if you Intern the
same thing twice, you get back the same identifier).  Then "=" can be
extremely efficient.  But it doesn't work if you have more than one hash
table.  So the right thing is to put the hash table in the package body
-- not allow clients to choose which table to pass to Intern.

- Bob



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

* Re: Proposed change to BC iterator parameters [limitedness]
  2003-12-10 17:53 Proposed change to BC iterator parameters [limitedness] amado.alves
  2003-12-10 18:47 ` Georg Bauhaus
@ 2003-12-11 15:48 ` Robert A Duff
  1 sibling, 0 replies; 46+ messages in thread
From: Robert A Duff @ 2003-12-11 15:48 UTC (permalink / raw)


"amado.alves" <amado.alves@netcabo.pt> writes:

> I think there are (container) libraries that accept limited element
> types. And some libs that dont can easily (?) be changed in that
> direction. But as I indicated I think it is 'unatural' to store values
> of a limited type. For me it does not make sense to put constants in a
> container. So my advice can only be: rethink your program.

Heh?  Limited is not the same thing as constant.  It makes perfect sense
to store limited objects in containers.  *Some* containers require
copying to get the data in and out of the container; limited components
do not make sense in *that* case.  But other containers can deal with
limited types just fine.

Why do you think Ada allows arrays of tasks?  An array is a container,
and tasks are about as limited as you can get!

- Bob



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

* RE: Proposed change to BC iterator parameters [limitedness]
@ 2003-12-11 16:24 amado.alves
  2003-12-11 16:53 ` Robert A Duff
  0 siblings, 1 reply; 46+ messages in thread
From: amado.alves @ 2003-12-11 16:24 UTC (permalink / raw)
  To: comp.lang.ada

<<
> I think there are (container) libraries that accept limited element
> types. And some libs that dont can easily (?) be changed in that
> direction. But as I indicated I think it is 'unatural' to store values
> of a limited type. For me it does not make sense to put constants in a
> container. So my advice can only be: rethink your program.

Heh?  Limited is not the same thing as constant.>>

I think the original poster wanted limited for logical constants.

<<It makes perfect sense to store limited objects in containers.>>

Not "perfect" to me ;-)

<<*Some* containers require
copying to get the data in and out of the container;>>

Strictly all containers do. The difference is when. At declaration, at elaboration, at run time...

<<... limited components
do not make sense in *that* case.  But other containers can deal with
limited types just fine.

Why do you think Ada allows arrays of tasks?>>

I don't know. I would be happy with pointers to tasks or some such. For uniformity. You can have an array of exceptions ids, but not of exceptions.

<<An array is a container,>>

I can say any object is a container. An uni-elementary one.

<<...and tasks are about as limited as you can get!>>

Yes, unfortunately.




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

* Re: Proposed change to BC iterator parameters [limitedness]
  2003-12-11 16:24 amado.alves
@ 2003-12-11 16:53 ` Robert A Duff
  0 siblings, 0 replies; 46+ messages in thread
From: Robert A Duff @ 2003-12-11 16:53 UTC (permalink / raw)


"amado.alves" <amado.alves@netcabo.pt> writes:

>... You can have an array of exceptions ids, but not of exceptions.

Yes, and that's a horrible kludge.  The language would be much simpler,
and also more powerful, if exceptions were first-class objects (of type
Exception'Class or some such).

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-11 15:24     ` Robert A Duff
@ 2003-12-11 17:39       ` Jeffrey Carter
  2003-12-12 22:22         ` Robert A Duff
       [not found]         ` <916oa1-c93.ln1@beastie.ix.netcom.com>
  0 siblings, 2 replies; 46+ messages in thread
From: Jeffrey Carter @ 2003-12-11 17:39 UTC (permalink / raw)


Robert A Duff wrote:

> The data we're talking about is not *very* global.  It's local to the
> procedure containing the instantiation.  Yes, it's global to the actual
> procedure passed to Apply, but that's probably a pretty small region of
> code.

In simple languages such as FORTRAN 66, data are either local or global. 
In Ada, there are a number of shadings to the locality of data. This 
kind of data is essentially "state data", and should be considered an 
acceptable use. It is similar to the components of a protected unit: 
global to, but accessible only by a small, well defined set of operations.

I agree with Duff in general, but in the case of providing iteration 
over a protected structure, one must use an access-to-subprogram 
parameter. The actual subprogram will often need to be defined at the 
library level to pass accessibility checks. To allow various iterators 
to access local data, you have to use the Context parameter approach. If 
the protected structure is implemented with an unprotected structure 
component, and the protected iterator is implemented by instantiating an 
iterator from the unprotected structure, then the unprotected iterator 
has to have a Context parameter as well.

Protected structures, especially protected queues, are quite useful. It 
is because the PragmAda Reusable Components provide protected structures 
that they have Context parameters for their iterators, not because of a 
concern about global data. Since AI-302-01 is based on the PragmARCs, 
its iterators also have Context parameters.

-- 
Jeff Carter
"Sir Lancelot saves Sir Gallahad from almost certain temptation."
Monty Python & the Holy Grail
69




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

* Re: Proposed change to BC iterator parameters [limitedness]
  2003-12-11 13:10 ` Marin David Condic
@ 2003-12-11 17:59   ` Jeffrey Carter
  2003-12-12  5:58   ` Simon Wright
  1 sibling, 0 replies; 46+ messages in thread
From: Jeffrey Carter @ 2003-12-11 17:59 UTC (permalink / raw)


Marin David Condic wrote:

> Here's a question because I have not looked at either of these libraries 
>  in any detail: Does either Charles or Booch support some kind of 
> persistance of objects? By which I mean do they store/retrieve from a 
> file or serialize to/from a stream such that they could be put into a 
> file readily?

The PragmAda Reusable Components allow structures of limited definite 
types. They do not support persistence directly, because that can easily 
be implemented with an iterator.

-- 
Jeff Carter
"Sir Lancelot saves Sir Gallahad from almost certain temptation."
Monty Python & the Holy Grail
69




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

* Re: Proposed change to BC iterator parameters
  2003-12-11  5:07   ` Steve
  2003-12-11 15:24     ` Robert A Duff
@ 2003-12-12  5:29     ` Simon Wright
  2003-12-12 22:26       ` Robert A Duff
  2003-12-13  2:44       ` Steve
  1 sibling, 2 replies; 46+ messages in thread
From: Simon Wright @ 2003-12-12  5:29 UTC (permalink / raw)


"Steve" <nospam_steved94@comcast.net> writes:

> "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
> news:wccekvc2rol.fsf@shell01.TheWorld.com...
> [snip]
> >
> > I don't understand the point of Param_Type and Param above.  If you want
> > to pass extra information to Apply, nest the instantiation in a place
> > where it can see that data.
> 
> The reason for Param_Type and Param is to avoid using data outside of the
> scope of the Apply routine except for the arguments to the Apply machine.
> It comes from that old school of thought:
>   Avoid global data
>   All inputs and outputs of a procedure should appear in their parameter
> lists
> 
> Following these simple guidelines usually makes code a lot easier to follow.

I see these extensions were added to the BCs on 1 Dec 1999, in
response to a request from a user (also called Steve!)

-- 
Simon Wright                               100% Ada, no bugs.



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

* Re: Proposed change to BC iterator parameters [limitedness]
  2003-12-11 13:10 ` Marin David Condic
  2003-12-11 17:59   ` Jeffrey Carter
@ 2003-12-12  5:58   ` Simon Wright
  1 sibling, 0 replies; 46+ messages in thread
From: Simon Wright @ 2003-12-12  5:58 UTC (permalink / raw)


Marin David Condic <nobody@noplace.com> writes:

> Here's a question because I have not looked at either of these
> libraries in any detail: Does either Charles or Booch support some
> kind of persistance of objects? By which I mean do they store/retrieve
> from a file or serialize to/from a stream such that they could be put
> into a file readily?

The BCs support streams.

Mark Bond worked on extending the BCs to provide persistence, I
haven't rolled the work into the mainstream ..
http://www.pushface.org/components/bc/contrib/bond/

-- 
Simon Wright                               100% Ada, no bugs.



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

* Re: Proposed change to BC iterator parameters
  2003-12-11 17:39       ` Jeffrey Carter
@ 2003-12-12 22:22         ` Robert A Duff
  2003-12-13  0:57           ` Jeffrey Carter
       [not found]         ` <916oa1-c93.ln1@beastie.ix.netcom.com>
  1 sibling, 1 reply; 46+ messages in thread
From: Robert A Duff @ 2003-12-12 22:22 UTC (permalink / raw)


Jeffrey Carter <spam@spam.com> writes:

> I agree with Duff in general, but in the case of providing iteration
> over a protected structure, one must use an access-to-subprogram
> parameter. 

I don't understand.  Why can't one use the usual generic-iterator idea
in that case?  Maybe I don't understand what you mean by "protected
structure"...

Maybe you could give an example?

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-12  5:29     ` Simon Wright
@ 2003-12-12 22:26       ` Robert A Duff
  2003-12-13 16:55         ` Simon Wright
  2003-12-13  2:44       ` Steve
  1 sibling, 1 reply; 46+ messages in thread
From: Robert A Duff @ 2003-12-12 22:26 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Simon Wright                               100% Ada, no bugs.
                                             ^^^^^^^^^^^^^^^^^

What is this "no bugs" business?  Does someone claim that Ada code has
no bugs?!

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-12 22:22         ` Robert A Duff
@ 2003-12-13  0:57           ` Jeffrey Carter
  2003-12-17 20:59             ` Robert A Duff
  0 siblings, 1 reply; 46+ messages in thread
From: Jeffrey Carter @ 2003-12-13  0:57 UTC (permalink / raw)


Robert A Duff wrote:

> Jeffrey Carter <spam@spam.com> writes:
> 
>>I agree with Duff in general, but in the case of providing iteration
>>over a protected structure, one must use an access-to-subprogram
>>parameter. 
> 
> I don't understand.  Why can't one use the usual generic-iterator idea
> in that case?  Maybe I don't understand what you mean by "protected
> structure"...
> 
> Maybe you could give an example?

See, for example, the Queue_Bounded structure in AI-302-01, in which the 
queue is a protected type (section A.X.6).

-- 
Jeff Carter
"C++ is like giving an AK-47 to a monk, shooting him
full of crack and letting him loose in a mall and
expecting him to balance your checking account
'when he has the time.'"
Drew Olbrich
52




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

* Re: Proposed change to BC iterator parameters
  2003-12-12  5:29     ` Simon Wright
  2003-12-12 22:26       ` Robert A Duff
@ 2003-12-13  2:44       ` Steve
  1 sibling, 0 replies; 46+ messages in thread
From: Steve @ 2003-12-13  2:44 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message
news:x7vwu921u54.fsf@smaug.pushface.org...
> "Steve" <nospam_steved94@comcast.net> writes:
>
> > "Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
> > news:wccekvc2rol.fsf@shell01.TheWorld.com...
> > [snip]
> > >
> > > I don't understand the point of Param_Type and Param above.  If you
want
> > > to pass extra information to Apply, nest the instantiation in a place
> > > where it can see that data.
> >
> > The reason for Param_Type and Param is to avoid using data outside of
the
> > scope of the Apply routine except for the arguments to the Apply
machine.
> > It comes from that old school of thought:
> >   Avoid global data
> >   All inputs and outputs of a procedure should appear in their parameter
> > lists
> >
> > Following these simple guidelines usually makes code a lot easier to
follow.
>
> I see these extensions were added to the BCs on 1 Dec 1999, in
> response to a request from a user (also called Steve!)
>
That is why I felt compelled to explain my reasoning in this thread.

Steve
(The Duck)
(The Same Steve)

> -- 
> Simon Wright                               100% Ada, no bugs.





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

* Re: Proposed change to BC iterator parameters
  2003-12-12 22:26       ` Robert A Duff
@ 2003-12-13 16:55         ` Simon Wright
  2003-12-13 17:27           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 46+ messages in thread
From: Simon Wright @ 2003-12-13 16:55 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> Simon Wright <simon@pushface.org> writes:
> 
> > Simon Wright                               100% Ada, no bugs.
>                                              ^^^^^^^^^^^^^^^^^
> 
> What is this "no bugs" business?  Does someone claim that Ada code has
> no bugs?!

I regard it as marketing ..

-- 
Simon Wright                               100% Ada, no bugs.



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

* Re: Proposed change to BC iterator parameters
       [not found]         ` <916oa1-c93.ln1@beastie.ix.netcom.com>
@ 2003-12-13 16:57           ` Simon Wright
  0 siblings, 0 replies; 46+ messages in thread
From: Simon Wright @ 2003-12-13 16:57 UTC (permalink / raw)


Dennis Lee Bieber <wlfraed@ix.netcom.com> writes:

>         FORTRAN is a bit worse than that -- since a COMMON block only defines 
> a (named) block of memory containing variables, and other files naming 
> the same COMMON don't even have to use the same type of variables in 
> the same order... Think Unchecked_Conversion between n-Record types <G>

When I wrote (VAX/VMS) Fortran 77 I used to put common blocks in
include files -- is there any other way to do it?!

-- 
Simon Wright                               100% Ada, no bugs.



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

* Re: Proposed change to BC iterator parameters
  2003-12-13 16:55         ` Simon Wright
@ 2003-12-13 17:27           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 46+ messages in thread
From: Dmitry A. Kazakov @ 2003-12-13 17:27 UTC (permalink / raw)


Simon Wright wrote:

> Robert A Duff <bobduff@shell01.TheWorld.com> writes:
> 
>> Simon Wright <simon@pushface.org> writes:
>> 
>> > Simon Wright                               100% Ada, no bugs.
>>                                              ^^^^^^^^^^^^^^^^^
>> 
>> What is this "no bugs" business?  Does someone claim that Ada code has
>> no bugs?!
> 
> I regard it as marketing ..

Bugs can be very profitable ...

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Proposed change to BC iterator parameters
  2003-12-13  0:57           ` Jeffrey Carter
@ 2003-12-17 20:59             ` Robert A Duff
  2003-12-18 10:05               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 46+ messages in thread
From: Robert A Duff @ 2003-12-17 20:59 UTC (permalink / raw)


Jeffrey Carter <spam@spam.com> writes:

> Robert A Duff wrote:
> 
> > Jeffrey Carter <spam@spam.com> writes:
> >
> >>I agree with Duff in general, but in the case of providing iteration
> >>over a protected structure, one must use an access-to-subprogram
> >> parameter.
> > I don't understand.  Why can't one use the usual generic-iterator idea
> > in that case?  Maybe I don't understand what you mean by "protected
> > structure"...
> > Maybe you could give an example?
> 
> See, for example, the Queue_Bounded structure in AI-302-01, in which the
> queue is a protected type (section A.X.6).

Ah, now I get it.  Thanks.

You want to pass a procedure to a protected procedure.  You can't make
the protected procedure generic, which would be the normal thing to do
in the non-protected case.  So you have to pass an extra context
parameter.  That technique works, but it gets pretty ugly at the call
site.  (I'm not blaming you -- the language is forcing you into a
corner!)  Also, you lose compile-time type checking -- the caller passes
in an object of a specific type derived from Context_Data, and the
loop-body procedure must downcast that, causing a run-time check.

I wonder if it might not be a good idea to add a generic wrapper for all
that?

Then you probably wouldn't want the nonprotected versions to use this
same interface.

I'm still pushing for downward closures to be added to the language,
which would add at least a minimal amount of support for iterators,
and greatly simplify this and other data-structure proposals.

An unrelated question about that AI: Why not combine the protected and
blocking versions?

(I really should review this AI carefully sometime...  It would be very
nice to get a data structure library into some future version of the
language.)

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-17 20:59             ` Robert A Duff
@ 2003-12-18 10:05               ` Dmitry A. Kazakov
  2003-12-18 18:14                 ` Robert A Duff
  0 siblings, 1 reply; 46+ messages in thread
From: Dmitry A. Kazakov @ 2003-12-18 10:05 UTC (permalink / raw)


Robert A Duff wrote:

> I'm still pushing for downward closures to be added to the language,
> which would add at least a minimal amount of support for iterators,
> and greatly simplify this and other data-structure proposals.

Wouldn't subroutine types do the trick? I wonder why Ada does not have them.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Proposed change to BC iterator parameters
  2003-12-18 10:05               ` Dmitry A. Kazakov
@ 2003-12-18 18:14                 ` Robert A Duff
  2003-12-19 10:53                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 46+ messages in thread
From: Robert A Duff @ 2003-12-18 18:14 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> Robert A Duff wrote:
> 
> > I'm still pushing for downward closures to be added to the language,
> > which would add at least a minimal amount of support for iterators,
> > and greatly simplify this and other data-structure proposals.
> 
> Wouldn't subroutine types do the trick? I wonder why Ada does not have them.

By "downward closures", I mean the ability to pass more-nested
procedures as parameters to less-nested procedures.  If that's what
you mean by "subroutine types", then yes.

Access-to-subprogram types don't do the trick because of the
accessibility rules.  Hence the extra "context" parameters in
Jeff Carter's iterators.

I also would like the ability to have anonymous procedures, like lambda
in Lisp, or blocks in Smalltalk.  The idea is to pass the body of a loop
as a parameter to the iterator, and I don't want to have to give a
*name* to every loop body, and I want to write it *inside* the loop
(i.e. inside the call to the iterator).

I also want the ability to jump out of those anonymous procedures, to
exit the loop, without passing extra parameters around.  The extra
parameter is bad because it forces loops that *don't* want to exit
prematurely to worry about whether they might want to exit prematurely.

I don't expect to see any of this in Ada, ever, except perhaps for
downward closures.  There is an AI on downward closures, but I don't
remember it's status.  I hope it gets in.  It's the only case where Ada
is inferior in power to Pascal.

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-18 18:14                 ` Robert A Duff
@ 2003-12-19 10:53                   ` Dmitry A. Kazakov
  2003-12-19 16:17                     ` Georg Bauhaus
  0 siblings, 1 reply; 46+ messages in thread
From: Dmitry A. Kazakov @ 2003-12-19 10:53 UTC (permalink / raw)


Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> Robert A Duff wrote:
>> 
>> > I'm still pushing for downward closures to be added to the language,
>> > which would add at least a minimal amount of support for iterators,
>> > and greatly simplify this and other data-structure proposals.
>> 
>> Wouldn't subroutine types do the trick? I wonder why Ada does not have
>> them.
> 
> By "downward closures", I mean the ability to pass more-nested
> procedures as parameters to less-nested procedures.  If that's what
> you mean by "subroutine types", then yes.

Yes. A subroutine object will be of course passed in "IN" mode, so there
will be no way to get an access object from it and store that non-locally,
which was the main concern caused the accessibility rules.

type Func is function (X : Float) return Float;
procedure Integrate (F : Func; X1, X2 : Float) return Float;

> Access-to-subprogram types don't do the trick because of the
> accessibility rules.

Right. However, there was an idea to have limited access types, which would
probably do it. But I think that to have subroutine types is more cleaner
and in Ada spirit.

> Hence the extra "context" parameters in
> Jeff Carter's iterators.
> 
> I also would like the ability to have anonymous procedures, like lambda
> in Lisp, or blocks in Smalltalk.  The idea is to pass the body of a loop
> as a parameter to the iterator, and I don't want to have to give a
> *name* to every loop body, and I want to write it *inside* the loop
> (i.e. inside the call to the iterator).

This should work with subroutine types. We only need to invent some syntax
sugar for "subroutine literals".

type Item is ...;
type Container is ...;
type Action is procedure (I : Item);
procedure Enumerate (X : Container; For_All : Action);
procedure Print (I : Item; Output : in out Device);
...
procedure Print (X : Container; Output : in out Device) is
begin
   Enumerate (X, Action'(Print (I, Device);));
-- or maybe
   Enumerate (X, procedure (I : Item) is begin Print (I, Device); end;);
end Print;

However mixing statements and expressions looks awful to my taste.

> I also want the ability to jump out of those anonymous procedures, to
> exit the loop, without passing extra parameters around.  The extra
> parameter is bad because it forces loops that *don't* want to exit
> prematurely to worry about whether they might want to exit prematurely.

If you have an ability to put a subroutine body in an expression then gotos
out of it are for free:

procedure Print
          (  X : Container;
             Output : in out Device;
             Count : Natural
          )  is
   To_Print : Natural := Count;
begin
   Enumerate
   (  X,
      procedure (I : Item) is
      begin
         if To_Print > 0 then
            Print (I, Device);
            To_Print := To_Print - 1;
         else
            goto Done; -- Done is visible here
         end if;
      end;
   );
<<Done>> null;
end Print;

But you will probably need a return-from-nested-subprogram statement (like
we have for exit):

function Search (X : Container; Key : Item_Key) return Item is
begin
   Enumerate
   (  X,
      procedure (I : Item) is
      begin
         if Get_Key (I) = Key then
            return I out Search; -- Return through all nested contexts
         end if;
      end;
   );
   raise Nothing_Found;
end Search;

> I don't expect to see any of this in Ada, ever, except perhaps for
> downward closures.  There is an AI on downward closures, but I don't
> remember it's status.  I hope it gets in.  It's the only case where Ada
> is inferior in power to Pascal.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Proposed change to BC iterator parameters
  2003-12-19 10:53                   ` Dmitry A. Kazakov
@ 2003-12-19 16:17                     ` Georg Bauhaus
  2003-12-19 17:19                       ` Dmitry A. Kazakov
  2003-12-19 22:47                       ` Robert A Duff
  0 siblings, 2 replies; 46+ messages in thread
From: Georg Bauhaus @ 2003-12-19 16:17 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
 
: function Search (X : Container; Key : Item_Key) return Item is
: begin
:   Enumerate
:   (  X,
:      procedure (I : Item) is
:      begin
:         if Get_Key (I) = Key then
:            return I out Search; -- Return through all nested contexts
:         end if;
:      end;
:   );
:   raise Nothing_Found;
: end Search;

wouldn't an active(?) iteration do the job in a satisfying way,
using is_done, element, and next, in a loop?





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

* Re: Proposed change to BC iterator parameters
  2003-12-19 16:17                     ` Georg Bauhaus
@ 2003-12-19 17:19                       ` Dmitry A. Kazakov
  2003-12-19 22:51                         ` Robert A Duff
  2003-12-19 22:47                       ` Robert A Duff
  1 sibling, 1 reply; 46+ messages in thread
From: Dmitry A. Kazakov @ 2003-12-19 17:19 UTC (permalink / raw)


Georg Bauhaus wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>  
> : function Search (X : Container; Key : Item_Key) return Item is
> : begin
> :   Enumerate
> :   (  X,
> :      procedure (I : Item) is
> :      begin
> :         if Get_Key (I) = Key then
> :            return I out Search; -- Return through all nested contexts
> :         end if;
> :      end;
> :   );
> :   raise Nothing_Found;
> : end Search;
> 
> wouldn't an active(?) iteration do the job in a satisfying way,
> using is_done, element, and next, in a loop?

But Robert wants it in a non-OO way! I think that he's right. The language
should support both procedural and OO approaches, for they are
complimentary.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Proposed change to BC iterator parameters
  2003-12-19 16:17                     ` Georg Bauhaus
  2003-12-19 17:19                       ` Dmitry A. Kazakov
@ 2003-12-19 22:47                       ` Robert A Duff
  2003-12-20  2:11                         ` Stephen Leake
  2003-12-20 19:08                         ` Robert I. Eachus
  1 sibling, 2 replies; 46+ messages in thread
From: Robert A Duff @ 2003-12-19 22:47 UTC (permalink / raw)


Georg Bauhaus <sb463ba@l1-hrz.uni-duisburg.de> writes:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>  
> : function Search (X : Container; Key : Item_Key) return Item is
> : begin
> :   Enumerate
> :   (  X,
> :      procedure (I : Item) is
> :      begin
> :         if Get_Key (I) = Key then
> :            return I out Search; -- Return through all nested contexts
> :         end if;
> :      end;
> :   );
> :   raise Nothing_Found;
> : end Search;

I agree with Mr. Kazakov that the above syntax is not pretty.
I admit I haven't come up with any better syntax.

> wouldn't an active(?) iteration do the job in a satisfying way,
> using is_done, element, and next, in a loop?

That's the style I like to call "cursors".  The C++ Standard Template
Library calls them iterators.  The same with Matt Heaney's Charles
library, which is based on the STL.  I don't call like to call it an
iterator, because it doesn't iterate.  A cursor is just a pointer to
some "place" in the data structure, and the client can move to the next
place, test whether we're at the end, etc.  (Some cursors can go
backward, as well.  Etc.)

Cursors are fine when you need that power, but if all you want to do is
loop through the elements of a data structure, it's too low level.  The
client shouldn't have to worry about getting the next thing, and testing
for done.  The client should just say "for each item X, perform
so-and-so operations on X".  That's pretty much what the generic style
does, but the syntax is horrible, and it doesn't work in all cases.  For
example, as Jeff Carter pointed out, if the iterator wants to be a
protected operation.

Also, if you use the cursor style for iteration, it can get pretty
unreadable in complicated cases.  For example, try writing in that style
for walking a tree-structured data structure.  The generic style can use
simple recursion.  The cursor style needs to mess around with explicit
stacks and whatnot.  Similarly, layering one iterator on top of another
(like "skip all the items that match a certain condition"), is much
easier to write in the generic style.

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-19 17:19                       ` Dmitry A. Kazakov
@ 2003-12-19 22:51                         ` Robert A Duff
  2003-12-20 12:20                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 46+ messages in thread
From: Robert A Duff @ 2003-12-19 22:51 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> But Robert wants it in a non-OO way! I think that he's right. The language
> should support both procedural and OO approaches, for they are
> complimentary.

I'm not sure why you call the cursor style "OO".  But yes, both styles
are useful.

What I *really* want is that the iterator can be written in whichever
style is appropriate, and easily *used* in either style.  Converting the
downward closure style to what you call the OO style (which I call the
cursor style) requires language support for coroutines, or something
very much like coroutines.

You can simulate coroutines using tasks and protected objects, but the
syntax is over-the-top heavy.  Not to mention the inefficiency.

- Bob



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

* Re: Proposed change to BC iterator parameters
  2003-12-19 22:47                       ` Robert A Duff
@ 2003-12-20  2:11                         ` Stephen Leake
  2003-12-20 19:08                         ` Robert I. Eachus
  1 sibling, 0 replies; 46+ messages in thread
From: Stephen Leake @ 2003-12-20  2:11 UTC (permalink / raw)
  To: Robert A Duff; +Cc: comp.lang.ada

Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> Also, if you use the cursor style for iteration, it can get pretty
> unreadable in complicated cases. For example, try writing in that
> style for walking a tree-structured data structure. The generic
> style can use simple recursion. The cursor style needs to mess
> around with explicit stacks and whatnot.

Hmm. You can wrap that in a package, and provide a simple "next,
is_done" interface. See
http://www.toadmail.com/~ada_wizard/ada/sal_packages/sal-poly-binary_trees-sorted-iterators__ads.htm 

-- 
-- Stephe




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

* Re: Proposed change to BC iterator parameters
  2003-12-19 22:51                         ` Robert A Duff
@ 2003-12-20 12:20                           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 46+ messages in thread
From: Dmitry A. Kazakov @ 2003-12-20 12:20 UTC (permalink / raw)


Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> But Robert wants it in a non-OO way! I think that he's right. The
>> language should support both procedural and OO approaches, for they are
>> complimentary.
> 
> I'm not sure why you call the cursor style "OO".

Cursor is an object! (:-))

> But yes, both styles
> are useful.
> 
> What I *really* want is that the iterator can be written in whichever
> style is appropriate, and easily *used* in either style.  Converting the
> downward closure style to what you call the OO style (which I call the
> cursor style) requires language support for coroutines, or something
> very much like coroutines.

Mmm, I am not sure what you mean. Technically either you pass a callback
subroutine (+ its context) or you do an object (having a dispatching
subroutine), both should be equivalent. The only difference is in syntactic
sugar, i.e. (for cursor/OO approach) how easily one can derive a new type,
override a subprogram, pack the necessary context stuff in a cursor
instance. There should be a lot of sugar (and you have to do it at the
library level, oops!) However, if we could put a subprogram body in an
expression for the closure style, then we could also do it with the body of
a cursor's override. Why not? So in both cases one could jump out of an
iteration/recursion loop. But my concern is that non-local gotos and ad-hoc
exceptions violate contract. Actually there is no any contract of an
anonymous body. It is fine when the program is 50 lines long, but in a
medium-sized project it might become a nightmare. What would your debugger
show in the call-stack window for an anonymous body, after all? (:-))

> You can simulate coroutines using tasks and protected objects, but the
> syntax is over-the-top heavy.  Not to mention the inefficiency.

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Proposed change to BC iterator parameters
  2003-12-19 22:47                       ` Robert A Duff
  2003-12-20  2:11                         ` Stephen Leake
@ 2003-12-20 19:08                         ` Robert I. Eachus
  2003-12-21 11:39                           ` Simon Wright
  2003-12-21 13:58                           ` Dmitry A. Kazakov
  1 sibling, 2 replies; 46+ messages in thread
From: Robert I. Eachus @ 2003-12-20 19:08 UTC (permalink / raw)


Robert A Duff wrote:

> Cursors are fine when you need that power, but if all you want to do is
> loop through the elements of a data structure, it's too low level.  The
> client shouldn't have to worry about getting the next thing, and testing
> for done.  The client should just say "for each item X, perform
> so-and-so operations on X".  That's pretty much what the generic style
> does, but the syntax is horrible, and it doesn't work in all cases.  For
> example, as Jeff Carter pointed out, if the iterator wants to be a
> protected operation.

I'm a big fan of asking for what you want, then seeing if what you get 
satisfies your need.

Right now I can say:

for I in A'Range loop
   Do_Something(A(I));
end loop;

or

while List.Next /= null loop;
   List := List.Next;
   Do_Something(List.Data);
end loop;

What Bob seems to be asking for is a way to do that for general data 
structures:

package My_Structures is new Some_Structure(Element);

type My_Structure renames My_Structures.Structure;

for E in My_Structures.Ordered_List_of_Elements loop
   Do_Something(E);
end loop;

Currently I often provide tools in my data structures packages to 
provide everything viewed as an array.  This allows me to do what Bob 
wants, but it would be really nice to extend the language so that 
iterators are first class objects known to the language so that the 
above pseudo code (for E in ...) would be supported if the 
Some_Structure package provided an iterator.  You should also be able to say

if E in My_Structures.Some_Iterator then ...

(This would require another signature in the template for iterators to 
make it efficient.)

Do I think this will make it into Ada 0Y?  No.  Ada 1Z? Possibly.

But the trick of having data structure packages return an array view of 
a collection, or actually an array of access values, is very, very 
useful.  (Notice that the difference between such an iterator and normal 
iterators is that it provides a snapshot.  Changes to the actual data 
structure while iterating through the array won't be visible in the 
loop.  Often this is what you want.  Sometimes it isn't, then it gets 
painful...)

-- 
                                           Robert I. Eachus

"The war on terror is a different kind of war, waged capture by capture, 
cell by cell, and victory by victory. Our security is assured by our 
perseverance and by our sure belief in the success of liberty." -- 
George W. Bush




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

* Re: Proposed change to BC iterator parameters
  2003-12-20 19:08                         ` Robert I. Eachus
@ 2003-12-21 11:39                           ` Simon Wright
  2003-12-21 18:13                             ` Robert I. Eachus
  2003-12-21 13:58                           ` Dmitry A. Kazakov
  1 sibling, 1 reply; 46+ messages in thread
From: Simon Wright @ 2003-12-21 11:39 UTC (permalink / raw)


"Robert I. Eachus" <rieachus@comcast.net> writes:

> Currently I often provide tools in my data structures packages to
> provide everything viewed as an array.

Brilliant! now why didn't I think of that!

-- 
Simon Wright                               100% Ada, no bugs.



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

* Re: Proposed change to BC iterator parameters
  2003-12-20 19:08                         ` Robert I. Eachus
  2003-12-21 11:39                           ` Simon Wright
@ 2003-12-21 13:58                           ` Dmitry A. Kazakov
  2003-12-22  1:25                             ` Robert I. Eachus
  1 sibling, 1 reply; 46+ messages in thread
From: Dmitry A. Kazakov @ 2003-12-21 13:58 UTC (permalink / raw)


Robert I. Eachus wrote:

> Currently I often provide tools in my data structures packages to
> provide everything viewed as an array.  This allows me to do what Bob
> wants, but it would be really nice to extend the language so that
> iterators are first class objects known to the language so that the
> above pseudo code (for E in ...) would be supported if the
> Some_Structure package provided an iterator.  You should also be able to
> say
> 
> if E in My_Structures.Some_Iterator then ...
> 
> (This would require another signature in the template for iterators to
> make it efficient.)
> 
> Do I think this will make it into Ada 0Y?  No.  Ada 1Z? Possibly.
> 
> But the trick of having data structure packages return an array view of
> a collection, or actually an array of access values, is very, very
> useful.  (Notice that the difference between such an iterator and normal
> iterators is that it provides a snapshot.  Changes to the actual data
> structure while iterating through the array won't be visible in the
> loop.  Often this is what you want.  Sometimes it isn't, then it gets
> painful...)

But if interfaces are being added to Ada, why not to allow abstract array
interface? Then just make My_Structure an implementation of the abstract
array and here you are! 

-- 
Regards,
Dmitry A. Kazakov
www.dmitry-kazakov.de



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

* Re: Proposed change to BC iterator parameters
  2003-12-21 11:39                           ` Simon Wright
@ 2003-12-21 18:13                             ` Robert I. Eachus
  0 siblings, 0 replies; 46+ messages in thread
From: Robert I. Eachus @ 2003-12-21 18:13 UTC (permalink / raw)


Simon Wright wrote:

> "Robert I. Eachus" <rieachus@comcast.net> writes:
> 
> 
>>Currently I often provide tools in my data structures packages to
>>provide everything viewed as an array.
> 
> 
> Brilliant! now why didn't I think of that!

Because you don't think like I do?  "The reasonable man adapts himself 
to the world; the unreasonable one persists in trying to adapt the world 
to himself. Therefore all progress depends on  the unreasonable man."
-George Bernard Shaw   Also: "Some men see things as they are and say 
why? I dream things that never were and say 'Why not?'" -George Bernard 
Shaw  and "To achieve the impossible, one must think the absurd; to look 
where everyone else has looked, but to see what no one else has seen." 
-Anon?

I've been told since I was about 3 or 4 years old that I was a genius. 
But I have never felt like I was smart.  I just wasn't quite as stupid 
as most people.  But in this case, and in many similar cases, what 
happened was I approached the problem as a language designer rather than 
as a language user.  I knew what I wanted to say, and if the language 
wouldn't let me say it, I would have argued for a change in the language.

But for years I tried to figure out why people thought iterators were so 
important.  At first I thought they were needed in tasking situations 
where a definite loop was not the right solution.  But then I realized 
that for most tasking situations what you want is to view things as a 
linked list--even if the actual data structure is say a priority queue:

loop
   declare
     Temp: Foo_Element_Type := Next(Foo);
   begin
     Process(Temp);
   exception
     when others => ...;
   end;
end loop;

Is a very common data structure.  But when you use the idiom, the AST 
can be a queue, a list, a bag, a stack, or a heap.  All you need is a 
next operation that removes the appropriate object from the structure 
and returns it.  (For some element types you don't need the declare 
portion of the block, and for others you don't need the handler part, 
but this is the full pattern.)  So I started putting Next operations in 
my data structure packages as well, and I still have never found a need 
for all the overhead of an iterator.  If anyone knows of a pattern that 
requires all the overhead of an iterator instead of the array snapshot 
or the Next function, I'd like to know about it.  (Of course, you also 
need the standard operations for the data structure, but these two 
patterns seem to be independent of the actual data structure.)

Incidently, I probably need to include this information in the 
discussion of functions returning limited types...

-- 
                                           Robert I. Eachus

"The war on terror is a different kind of war, waged capture by capture, 
cell by cell, and victory by victory. Our security is assured by our 
perseverance and by our sure belief in the success of liberty." -- 
George W. Bush




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

* Re: Proposed change to BC iterator parameters
  2003-12-21 13:58                           ` Dmitry A. Kazakov
@ 2003-12-22  1:25                             ` Robert I. Eachus
  0 siblings, 0 replies; 46+ messages in thread
From: Robert I. Eachus @ 2003-12-22  1:25 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> But if interfaces are being added to Ada, why not to allow abstract array
> interface? Then just make My_Structure an implementation of the abstract
> array and here you are! 

Actually I am starting to something similar.  I am thinking out a set of 
data structures packages with a common interface plus extensions.  User 
can then do exactly that--use the abstract interface, and choose the 
actual data structure to use separately.

Of course, the reality is that you have many potential abstract 
templates with many templates being subsets of other templates.  The 
trick is to choose a useful set of standard templates.  (Users can 
materialize others if necessary.  But by designing to a standard 
template set, you can get a better fit to the standard 
templates/interfaces.

-- 
                                           Robert I. Eachus

"The war on terror is a different kind of war, waged capture by capture, 
cell by cell, and victory by victory. Our security is assured by our 
perseverance and by our sure belief in the success of liberty." -- 
George W. Bush




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

end of thread, other threads:[~2003-12-22  1:25 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-12-10 13:36 Proposed change to BC iterator parameters amado.alves
2003-12-10 16:47 ` Proposed change to BC iterator parameters [limitedness] Georg Bauhaus
2003-12-10 17:39 ` Proposed change to BC iterator parameters Martin Krischik
2003-12-10 18:22 ` Jeffrey Carter
2003-12-10 23:00   ` Robert A Duff
2003-12-11  1:00     ` Jeffrey Carter
2003-12-11 15:09       ` Robert A Duff
2003-12-11  8:33     ` Dmitry A. Kazakov
2003-12-10 20:50 ` Simon Wright
2003-12-10 23:12 ` Robert A Duff
2003-12-11  5:07   ` Steve
2003-12-11 15:24     ` Robert A Duff
2003-12-11 17:39       ` Jeffrey Carter
2003-12-12 22:22         ` Robert A Duff
2003-12-13  0:57           ` Jeffrey Carter
2003-12-17 20:59             ` Robert A Duff
2003-12-18 10:05               ` Dmitry A. Kazakov
2003-12-18 18:14                 ` Robert A Duff
2003-12-19 10:53                   ` Dmitry A. Kazakov
2003-12-19 16:17                     ` Georg Bauhaus
2003-12-19 17:19                       ` Dmitry A. Kazakov
2003-12-19 22:51                         ` Robert A Duff
2003-12-20 12:20                           ` Dmitry A. Kazakov
2003-12-19 22:47                       ` Robert A Duff
2003-12-20  2:11                         ` Stephen Leake
2003-12-20 19:08                         ` Robert I. Eachus
2003-12-21 11:39                           ` Simon Wright
2003-12-21 18:13                             ` Robert I. Eachus
2003-12-21 13:58                           ` Dmitry A. Kazakov
2003-12-22  1:25                             ` Robert I. Eachus
     [not found]         ` <916oa1-c93.ln1@beastie.ix.netcom.com>
2003-12-13 16:57           ` Simon Wright
2003-12-12  5:29     ` Simon Wright
2003-12-12 22:26       ` Robert A Duff
2003-12-13 16:55         ` Simon Wright
2003-12-13 17:27           ` Dmitry A. Kazakov
2003-12-13  2:44       ` Steve
  -- strict thread matches above, loose matches on Subject: below --
2003-12-10 17:53 Proposed change to BC iterator parameters [limitedness] amado.alves
2003-12-10 18:47 ` Georg Bauhaus
2003-12-11 15:48 ` Robert A Duff
2003-12-10 19:20 amado.alves
2003-12-11 13:10 ` Marin David Condic
2003-12-11 17:59   ` Jeffrey Carter
2003-12-12  5:58   ` Simon Wright
2003-12-10 19:33 amado.alves
2003-12-11 16:24 amado.alves
2003-12-11 16:53 ` Robert A Duff

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