comp.lang.ada
 help / color / mirror / Atom feed
* List Container Straw Man
@ 2001-11-06 16:45 Nick Roberts
  2001-11-06 17:29 ` Stephen Leake
  0 siblings, 1 reply; 34+ messages in thread
From: Nick Roberts @ 2001-11-06 16:45 UTC (permalink / raw)


I'm sorry but I have to beat a drum here!

Please, oh please, consider my design of basing all containers on a set of
very general-purpose abstract iterator types.

If there's some reason why this idea is wrong, then say so. Otherwise, use
it!

--
Nick Roberts






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

* Re: List Container Straw Man
  2001-11-06 16:45 List Container Straw Man Nick Roberts
@ 2001-11-06 17:29 ` Stephen Leake
  2001-11-06 18:25   ` Marin David Condic
  2001-11-06 23:52   ` Nick Roberts
  0 siblings, 2 replies; 34+ messages in thread
From: Stephen Leake @ 2001-11-06 17:29 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> I'm sorry but I have to beat a drum here!
> 
> Please, oh please, consider my design of basing all containers on a set of
> very general-purpose abstract iterator types.
> 
> If there's some reason why this idea is wrong, then say so. Otherwise, use
> it!

I think it's wrong, because most "general-purpose" things are.

But to give a more detailed response, I need to see an actual
proposal. By which I mean code, including the "general-purpose" part,
and the re-worked list package.

You can't expect volunteers to champion your ideas for you!

If you posted a pointer to an example, I missed it; please repost.

-- 
-- Stephe



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

* Re: List Container Straw Man
  2001-11-06 17:29 ` Stephen Leake
@ 2001-11-06 18:25   ` Marin David Condic
  2001-11-06 23:02     ` Nick Roberts
  2001-11-06 23:52   ` Nick Roberts
  1 sibling, 1 reply; 34+ messages in thread
From: Marin David Condic @ 2001-11-06 18:25 UTC (permalink / raw)


Doing what Ted did and throwing out a package spec (or two or three...)
would be a good idea. Its hard to see the merits of something like this
without some actual code to criticise. It need not include all details or
all possible operations - just enough of the basics to indicate how the idea
would be realized.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Stephen Leake" <stephen.a.leake.1@gsfc.nasa.gov> wrote in message
news:uwv13dcz0.fsf@gsfc.nasa.gov...
>
> But to give a more detailed response, I need to see an actual
> proposal. By which I mean code, including the "general-purpose" part,
> and the re-worked list package.
>






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

* Re: List Container Straw Man
  2001-11-06 18:25   ` Marin David Condic
@ 2001-11-06 23:02     ` Nick Roberts
  2001-11-07 19:49       ` Stephen Leake
  0 siblings, 1 reply; 34+ messages in thread
From: Nick Roberts @ 2001-11-06 23:02 UTC (permalink / raw)


"Marin David Condic" <dont.bother.mcondic.auntie.spam@[acm.org> wrote in
message news:9s99tt$pdb$1@nh.pace.co.uk...
> Doing what Ted did and throwing out a package spec (or two or three...)
> would be a good idea. Its hard to see the merits of something like this
> without some actual code to criticise. It need not include all details or
> all possible operations - just enough of the basics to indicate how the
idea
> would be realized.

Actually I did precisely that 3 days ago, but I think must have missed
again, so here's a repeat.

-----

May I make a suggestion, which, though I say it myself, I feel is rather
important!

Please make the type List derived from an abstract 'iterator' type. List
would then inherit the iteration operations of this type. An alternative is
for List to provide a function that generates or gives access to an object
derived from this iterator type.

For example:


generic
   type Element_Type is private;

package Containers is

   ...

   type Terminating_Producer is abstract tagged limited private;

   procedure Read (Producer: in out Terminating_Producer; Item: out
Element_Type) is abstract;

   function End_of_Data (Producer: in Terminating_Producer) return Boolean
is abstract;

   ...

   type Sequence_Reproducer is abstract new Terminating_Producer with
private;

   procedure Restart (Reproducer: in out Sequence_Reproducer) is abstract;

   type Sequence_Recorder is abstract new Sequence_Reproducer with private;

   procedure Rewrite (Reproducer: in out Sequence_Reproducer) is abstract;

   procedure Write (Recorder: in out Sequence_Recorder; Item: in
Element_Type) is abstract;

   function Count (Recorder: in Sequence_Recorder) return Natural is
abstract;

   function Is_Recording (Recorder: in Sequence_Recorder) return Boolean is
abstract;

   ...

end Containers;


The Restart procedure tells a sequence reproducer to start producing its
data over again. The Rewrite procedure tells a sequence recorder to start
recording data (at which point Write can be used and Read cannot;
Is_Recording returns True). Restart than tells it to start reading again (at
which point Write cannot be used; Is_Recording returns False). Count returns
the number of items currently recorded.


package Containers.Lists.Unbounded is

   type Linked_List is new Sequence_Recorder with private;

   -- Representing a singly-linked (forward) list type, with typical
operations.

   function "&" (Left, Right: in Linked_List) return Linked_List is
abstract;
   ...

   procedure Push (List: in out Linked_List; Item: in  Element_Type);
   procedure Pop  (List: in out Linked_List; Item: out Element_Type);

   ... -- etc

   type Doubly_Linked_List is new Sequence_Recorder with private;

   function "&" (Left, Right: in Linked_List) return Abstract_List is
abstract;
   ...

   procedure Push (List: in out Linked_List; Item: in  Element_Type);
   procedure Pop  (List: in out Linked_List; Item: out Element_Type);

   procedure Reverse_Push (List: in out Linked_List; Item: in
Element_Type);
   procedure Reverse_Pop  (List: in out Linked_List; Item: out
Element_Type);

   ... -- etc

end Containers.Utility.Lists;


In this way, a piece of software which only needs to iterate over a
container can be passed any of the list types, or other container types.
E.g.:


generic
   with package Specific_Containers is new Containers(<>);

procedure Print_a_List (List: in out
Specific_Containers.Sequence_Producer'Class);

...

   package Thingy_Containers is new Containers(Thingy_Type);

   Thingies_1: Thingy_Containers.Lists.Unbounded.Linked_List;
   Thingies_2: Thingy_Containers.Lists.Unbounded.Doubly_Linked_List;

   ...

   package Print_Thingies is new Print_a_List(Thingy_Containers);

   ...

   Print_Thingies(Thingies_1);
   Print_Thingies(Thingies_2);


We can call instantiations of Print_a_List with objects of type Linked_List,
or Doubly_Linked_List, or anything else (i.e. other containers) derived from
Sequence_Producer.

My choice of identifiers, and the details of my design may not be ideal, but
the basic idea is right.

Please don't get this elementary aspect of the design wrong!

-----

This is all based on a detailed (if only fundamental) proposal I put to the
ASCL (Ada Standard Component Library) group in 1999. I was puzzled by the
stunned silence it seemed to be met with. I would be happy to e-mail that
proposal to anyone who would like to see it.

nickroberts@adaos.worldonline.co.uk

And then I'd be happy to field any and all questions, suggestions, etc.

--
Nick Roberts






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

* Re: List Container Straw Man
  2001-11-06 17:29 ` Stephen Leake
  2001-11-06 18:25   ` Marin David Condic
@ 2001-11-06 23:52   ` Nick Roberts
  2001-11-07  4:44     ` A question and a request Eric Merritt
  1 sibling, 1 reply; 34+ messages in thread
From: Nick Roberts @ 2001-11-06 23:52 UTC (permalink / raw)


Stephe, how do I e-mail you?

--
Nick Roberts






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

* A question and a request
  2001-11-06 23:52   ` Nick Roberts
@ 2001-11-07  4:44     ` Eric Merritt
  2001-11-07 11:00       ` Preben Randhol
                         ` (3 more replies)
  0 siblings, 4 replies; 34+ messages in thread
From: Eric Merritt @ 2001-11-07  4:44 UTC (permalink / raw)
  To: comp.lang.ada

As some of you may know I am fairly new to Ada and I
just found out something that surprised me. I declared
two subtypes of an integer. I was then able to add
these two types together and assign the result to an
instance of one of the above subtypes. or

 subtype type_1 is Integer;
 subtype type_2 is Integer;
  
 type_1_instance   : type_1;
 type_2_instance   : type_2;
 type_1_instance_2 : type_1;

 type_1_instance   := 1;
 type_2_instance   := 2;
 type_1_instance_2 := type_1_instance +
type_2_instance;

The addition operator is taking two disparate but
related types and adding them. This is fine,
up-casting is a normal thing. However, when the result
is returned it is not (should not be?) an instance of
the subtype. It seems that the compiler is
down-casting automatically. This bothers me and it
seams that is violates Ada's strong typing. What am I
missing here?


My request is a bit simpler, is there any one out
there willing to serve as kind of a quasi-mentor.
Basically look at some simple code occasionally and
tell me when I am getting bad habits. I have found
when learning other languages without experienced
input that I am able to pick up the language in a few
weeks or months and then it takes me a couple of years
to realize I have bad habits and attempt to rectify
them. This shouldn't be too time consuming for the
volunteer. I have been programming in other languages
professionally (C/C++, Java, Perl and Python) and I
have a good understanding of the theory. I just need
someone to occasionally look and say "hey this is
stupid, in Ada do it this way" or "In Ada its better
to take this approach". I could post stuff to the list
but this seams to be poor etiquette. 

In any case, if I get an answer to my first question I
will be happy. Thanks



__________________________________________________
Do You Yahoo!?
Find a job, post your resume.
http://careers.yahoo.com



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

* Re: A question and a request
  2001-11-07  4:44     ` A question and a request Eric Merritt
@ 2001-11-07 11:00       ` Preben Randhol
  2001-11-07 12:54         ` David C. Hoos, Sr.
  2001-11-07 13:24         ` Eric Merritt
  2001-11-07 13:58       ` James Rogers
                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 34+ messages in thread
From: Preben Randhol @ 2001-11-07 11:00 UTC (permalink / raw)


On Tue, 6 Nov 2001 20:44:19 -0800 (PST), Eric Merritt wrote:
> As some of you may know I am fairly new to Ada and I
> just found out something that surprised me. I declared
> two subtypes of an integer. I was then able to add
> these two types together and assign the result to an
> instance of one of the above subtypes. or
> 
>  subtype type_1 is Integer;
>  subtype type_2 is Integer;
>   
>  type_1_instance   : type_1;
>  type_2_instance   : type_2;
>  type_1_instance_2 : type_1;
> 
>  type_1_instance   := 1;
>  type_2_instance   := 2;
>  type_1_instance_2 := type_1_instance +
> type_2_instance;
> 
> The addition operator is taking two disparate but
> related types and adding them. This is fine,
> up-casting is a normal thing. However, when the result
> is returned it is not (should not be?) an instance of
> the subtype. It seems that the compiler is
> down-casting automatically. This bothers me and it
> seams that is violates Ada's strong typing. What am I
> missing here?

Use type not subtype if you do not want the above behavior. Read
below (taken from:
http://goanna.cs.rmit.edu.au/~dale/ada/aln/4_basic_types.htmli )

Subtypes

We can restrict the range of values a variable can take by declaring a
subtype with a restricted range of values (this corresponds to Pascal's
user defined types). Any attempt to place an out-of-range value into a
variable of a subtype results in an exception (program error). In this
way program errors can be discovered. The syntax for a subtype
declaration is

subtype Name is Base_Type;
subtype Name is Base_Type range lowerbound . . upperbound;

Examples of declaring subtypes are given below.

type Processors is (M68000,  i8086, i80386, M68030, Pentium, PowerPC);
subtype Old_Processors is Processors range M68000..i8086;
subtype New_Processors is Processors range Pentium..PowerPC;

subtype Data is Integer;
subtype Age is Data range 0 . . 140;
subtype Temperatures is Float range -50.0 .. 200.0;
subtype Upper_Chars is Character range 'A' .. 'Z';

Subtypes are compatable with their base types . They can be placed in
the same place as any variable of the base type can. Also variables of
different subtypes that are derived from the same base type are
compatable.

My_Age	: Age;
Height	: Integer;

Height := My_Age;	-- silly, but never causes a problem.

My_Age := Height;	-- will cause a problem if height's
			-- value is outside the range of 
			-- my_age (0..140), but still 
			-- compilable.


Preben
-- 
Please, stop bombing civilians in Afghanistan. One cannot write off
killing innocent children and other civilians as "collateral damage".
A civilian is a civilian whether he or she is American or from another
country in the world.           http://web.amnesty.org/11september.htm



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

* Re: A question and a request
  2001-11-07 11:00       ` Preben Randhol
@ 2001-11-07 12:54         ` David C. Hoos, Sr.
  2001-11-08  2:35           ` dale
  2001-11-07 13:24         ` Eric Merritt
  1 sibling, 1 reply; 34+ messages in thread
From: David C. Hoos, Sr. @ 2001-11-07 12:54 UTC (permalink / raw)
  To: comp.lang.ada; +Cc: Dale Stanbrough, randhol, cyberlync


----- Original Message ----- 
From: "Preben Randhol" <randhol+abuse@pvv.org>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada.eu.org>
Sent: November 07, 2001 5:00 AM
Subject: Re: A question and a request


<snip>
> Use type not subtype if you do not want the above behavior. Read
> below (taken from:
> http://goanna.cs.rmit.edu.au/~dale/ada/aln/4_basic_types.htmli )
> 
> Subtypes
> 
> We can restrict the range of values a variable can take by declaring a
> subtype with a restricted range of values (this corresponds to Pascal's
> user defined types). Any attempt to place an out-of-range value into a
> variable of a subtype results in an exception (program error). In this
> way program errors can be discovered. The syntax for a subtype
> declaration is
> 
The above paragraph is simply wrong.  The excetpion which will be
raised is not Program_Error, but Constraint_Error.

As a further note to Dale (the prsumed author of the linked website),
there are spelling errors in the commentary on those pages.

<snip>




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

* Re: A question and a request
  2001-11-07 11:00       ` Preben Randhol
  2001-11-07 12:54         ` David C. Hoos, Sr.
@ 2001-11-07 13:24         ` Eric Merritt
  1 sibling, 0 replies; 34+ messages in thread
From: Eric Merritt @ 2001-11-07 13:24 UTC (permalink / raw)
  To: comp.lang.ada

I knew I was missing something. That actaully make
sense, I guess I was getting this typeing behavior
mixed up with the OO inheritence model. 

Thank You,
Eric Merritt

--- Preben Randhol <randhol+abuse@pvv.org> wrote:
> On Tue, 6 Nov 2001 20:44:19 -0800 (PST), Eric
> Merritt wrote:
> > As some of you may know I am fairly new to Ada and
> I
> > just found out something that surprised me. I
> declared
> > two subtypes of an integer. I was then able to add
> > these two types together and assign the result to
> an
> > instance of one of the above subtypes. or
> > 
> >  subtype type_1 is Integer;
> >  subtype type_2 is Integer;
> >   
> >  type_1_instance   : type_1;
> >  type_2_instance   : type_2;
> >  type_1_instance_2 : type_1;
> > 
> >  type_1_instance   := 1;
> >  type_2_instance   := 2;
> >  type_1_instance_2 := type_1_instance +
> > type_2_instance;
> > 
> > The addition operator is taking two disparate but
> > related types and adding them. This is fine,
> > up-casting is a normal thing. However, when the
> result
> > is returned it is not (should not be?) an instance
> of
> > the subtype. It seems that the compiler is
> > down-casting automatically. This bothers me and it
> > seams that is violates Ada's strong typing. What
> am I
> > missing here?
> 
> Use type not subtype if you do not want the above
> behavior. Read
> below (taken from:
>
http://goanna.cs.rmit.edu.au/~dale/ada/aln/4_basic_types.htmli
> )
> 
> Subtypes
> 
> We can restrict the range of values a variable can
> take by declaring a
> subtype with a restricted range of values (this
> corresponds to Pascal's
> user defined types). Any attempt to place an
> out-of-range value into a
> variable of a subtype results in an exception
> (program error). In this
> way program errors can be discovered. The syntax for
> a subtype
> declaration is
> 
> subtype Name is Base_Type;
> subtype Name is Base_Type range lowerbound . .
> upperbound;
> 
> Examples of declaring subtypes are given below.
> 
> type Processors is (M68000,  i8086, i80386, M68030,
> Pentium, PowerPC);
> subtype Old_Processors is Processors range
> M68000..i8086;
> subtype New_Processors is Processors range
> Pentium..PowerPC;
> 
> subtype Data is Integer;
> subtype Age is Data range 0 . . 140;
> subtype Temperatures is Float range -50.0 .. 200.0;
> subtype Upper_Chars is Character range 'A' .. 'Z';
> 
> Subtypes are compatable with their base types . They
> can be placed in
> the same place as any variable of the base type can.
> Also variables of
> different subtypes that are derived from the same
> base type are
> compatable.
> 
> My_Age	: Age;
> Height	: Integer;
> 
> Height := My_Age;	-- silly, but never causes a
> problem.
> 
> My_Age := Height;	-- will cause a problem if
> height's
> 			-- value is outside the range of 
> 			-- my_age (0..140), but still 
> 			-- compilable.
> 
> 
> Preben
> -- 
> Please, stop bombing civilians in Afghanistan. One
> cannot write off
> killing innocent children and other civilians as
> "collateral damage".
> A civilian is a civilian whether he or she is
> American or from another
> country in the world.          
> http://web.amnesty.org/11september.htm
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada


__________________________________________________
Do You Yahoo!?
Find a job, post your resume.
http://careers.yahoo.com



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

* Re: A question and a request
  2001-11-07  4:44     ` A question and a request Eric Merritt
  2001-11-07 11:00       ` Preben Randhol
@ 2001-11-07 13:58       ` James Rogers
  2001-11-07 16:32       ` Jeffrey Carter
  2001-11-09 23:32       ` Matthew Heaney
  3 siblings, 0 replies; 34+ messages in thread
From: James Rogers @ 2001-11-07 13:58 UTC (permalink / raw)
  To: comp.lang.ada

Eric,

I see you have already gotten an explanation of how subtypes work.

I am willing to act as a quasi-mentor for your Ada st;udies. I have
been studying and programming in Ada since 1994. That does not make
me the most qualified from comp.lang.ada, but I do think I can help.

I have been programming in C since 1981. I also know Java, and have
some familiarity with Perl. 

Jim Rogers
Colorado Springs, Colorado USA

Eric Merritt wrote:
> 
>
> My request is a bit simpler, is there any one out
> there willing to serve as kind of a quasi-mentor.
> Basically look at some simple code occasionally and
> tell me when I am getting bad habits. I have found
> when learning other languages without experienced
> input that I am able to pick up the language in a few
> weeks or months and then it takes me a couple of years
> to realize I have bad habits and attempt to rectify
> them. This shouldn't be too time consuming for the
> volunteer. I have been programming in other languages
> professionally (C/C++, Java, Perl and Python) and I
> have a good understanding of the theory. I just need
> someone to occasionally look and say "hey this is
> stupid, in Ada do it this way" or "In Ada its better
> to take this approach". I could post stuff to the list
> but this seams to be poor etiquette.
> 
> In any case, if I get an answer to my first question I
> will be happy. Thanks
> 
> __________________________________________________
> Do You Yahoo!?
> Find a job, post your resume.
> http://careers.yahoo.com



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

* Re: A question and a request
  2001-11-07  4:44     ` A question and a request Eric Merritt
  2001-11-07 11:00       ` Preben Randhol
  2001-11-07 13:58       ` James Rogers
@ 2001-11-07 16:32       ` Jeffrey Carter
  2001-11-09 23:32       ` Matthew Heaney
  3 siblings, 0 replies; 34+ messages in thread
From: Jeffrey Carter @ 2001-11-07 16:32 UTC (permalink / raw)


Although you have received some responses, I think the simple answer to
your problem is that your example has only one type in it: Integer.
Subtypes do not create new types and do not create new operations. The
"+" in your example is defined as

function "+" (Left : Integer; Right : Integer) return Integer;

-- 
Jeffrey Carter



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

* Re: List Container Straw Man
  2001-11-06 23:02     ` Nick Roberts
@ 2001-11-07 19:49       ` Stephen Leake
  2001-11-07 20:30         ` Marin David Condic
  2001-11-08  0:06         ` Nick Roberts
  0 siblings, 2 replies; 34+ messages in thread
From: Stephen Leake @ 2001-11-07 19:49 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> Please make the type List derived from an abstract 'iterator' type. List
> would then inherit the iteration operations of this type. An alternative is
> for List to provide a function that generates or gives access to an object
> derived from this iterator type.
> 
> For example:
> 
> 
> generic
>    type Element_Type is private;
> 
> package Containers is
> 
>    ...
> 
>    type Terminating_Producer is abstract tagged limited private;
> 
>    procedure Read (Producer: in out Terminating_Producer; Item: out
> Element_Type) is abstract;
> 
>    function End_of_Data (Producer: in Terminating_Producer) return Boolean
> is abstract;
> 
>    ...
> 
>    type Sequence_Reproducer is abstract new Terminating_Producer with
> private;
> 
>    procedure Restart (Reproducer: in out Sequence_Reproducer) is abstract;
> 
>    type Sequence_Recorder is abstract new Sequence_Reproducer with private;
> 
>    procedure Rewrite (Reproducer: in out Sequence_Reproducer) is abstract;
> 
>    procedure Write (Recorder: in out Sequence_Recorder; Item: in
> Element_Type) is abstract;
> 
>    function Count (Recorder: in Sequence_Recorder) return Natural is
> abstract;
> 
>    function Is_Recording (Recorder: in Sequence_Recorder) return Boolean is
> abstract;
> 
>    ...
> 
> end Containers;
> 
> 
> The Restart procedure tells a sequence reproducer to start producing its
> data over again. The Rewrite procedure tells a sequence recorder to start
> recording data (at which point Write can be used and Read cannot;
> Is_Recording returns True). Restart than tells it to start reading again (at
> which point Write cannot be used; Is_Recording returns False). Count returns
> the number of items currently recorded.

Well, I find this very confusing; there is not enough documentation
for me.

First, you switched from "Sequence_Reproducer" to "Sequence_Recorder".
Or maybe you left out a type?

Why are there three (or four) independent types? How do I write to a
producer object in the first place, so there is something to read?
Conversely, how do I read from a recorder?

> package Containers.Lists.Unbounded is
> 
>    type Linked_List is new Sequence_Recorder with private;
> 
>    -- Representing a singly-linked (forward) list type, with typical
> operations.
> 
>    function "&" (Left, Right: in Linked_List) return Linked_List is
> abstract;

Why is this abstract? How many implementations of a singly-linked list
are there? Hmm, I guess we have discussed several here, including
various options for making Iterators safe. So maybe this makes sense.

>    ...
> <snip> 
> end Containers.Utility.Lists;
> 
> 
> In this way, a piece of software which only needs to iterate over a
> container can be passed any of the list types, or other container types.

This is true. But it leads to the "complex instantiation" problem that
is one requirement for the list package under discussion.

It also introduces tagged types, which some users might want to avoid
(they can have run-time overhead, or be hard to test).

Personally, I've never run across a situation where this abstract
container design really made sense; it was always more important to
optimize the implentation for real-time issues (I'm a rocket
scientist, after all :).

In a truly complete library, I think both options should be available;
abstract containers and concrete, simple lists. Perhaps the "Dennison
List" package could be used to implement the doubly-linked list
variant of the abstract container package; would that work for you?

> Please don't get this elementary aspect of the design wrong!

"Wrong" is too strong. Just because some people give different design
options different importance does not make them wrong!

-- 
-- Stephe



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

* Re: List Container Straw Man
  2001-11-07 19:49       ` Stephen Leake
@ 2001-11-07 20:30         ` Marin David Condic
  2001-11-07 23:58           ` Nick Roberts
  2001-11-08 10:41           ` Ehud Lamm
  2001-11-08  0:06         ` Nick Roberts
  1 sibling, 2 replies; 34+ messages in thread
From: Marin David Condic @ 2001-11-07 20:30 UTC (permalink / raw)


I don't mind underlying complexity if there is any way to hide it. If the
design can be such that you have the complex versions around but through
instantiations or inheritance you can get a simpler version, then great.
(Not sure how you would do that...) The important thing in my mind is that
there are going to be a bunch of potential users who just need to slap
something simple together to hold a bunch of data and they're not going to
want every conceivable option available to them to do that.

I could imagine a design of a component library that would include some kind
of plain vanilla Lists and Maps that let you do the simple things and then
extend it with variants that allow more complex things to occur, such as
inheriting from iterators or controlling storage or whatever. Get something
that covers 80% of the average usage first, then worry about the more arcane
cases later. I don't think that a first cut at a standard component library
should attempt to be the software equivalent of a Swiss Army Knife, covering
every conceivable usage. Just your basic Boy Scout Knife with two or three
blades.

Can you imagine a way to take the classes that Nick suggests and use them as
the basis on which a simple list similar to what Ted suggests is built? That
means you have the underlying power if you want to peel away the layers and
use it, but for the simple cases you've got a nice, simple, instantiation
with nice simple subprogram calls? This might be a way to utilize the BC's.
If Ted, et alia, could be clever enough to hide the complexity under some
other layer, they might be able to overcome the objections and get what they
want. Hmmmmmm..........

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Stephen Leake" <stephen.a.leake.1@gsfc.nasa.gov> wrote in message
news:u1yjacqea.fsf@gsfc.nasa.gov...
>
> In a truly complete library, I think both options should be available;
> abstract containers and concrete, simple lists. Perhaps the "Dennison
> List" package could be used to implement the doubly-linked list
> variant of the abstract container package; would that work for you?
>






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

* Re: List Container Straw Man
  2001-11-07 20:30         ` Marin David Condic
@ 2001-11-07 23:58           ` Nick Roberts
  2001-11-08  4:34             ` Jeffrey Carter
  2001-11-08 10:45             ` Ehud Lamm
  2001-11-08 10:41           ` Ehud Lamm
  1 sibling, 2 replies; 34+ messages in thread
From: Nick Roberts @ 2001-11-07 23:58 UTC (permalink / raw)


I probably haven't explained it well, but I think you may be getting hold of
the wrong end of the stick a little.

In general, according my suggested design, you would need two instantiations
to start making use of a utility container. The first would instantiate the
package (called Iteration let us say) of abstract types:

   package Widget_Iteration is new Iteration(Aerial_Widget);

The second would instantiate the package declaring the utility container,
using the first package - a 'signature' package - as its generic parameter:

   package Widget_Storage is new
Linear_Linked_List_Storage(Widget_Iteration);

You might then want to use a 'use', or more likely a subtype declaration to
give the widget container type a convenient name:

   subtype Widget_Store is Widget_Storage.Store_Type;

and then you can start using it:

   Nuts, Bolts: Widget_Store; -- initialised empty

To recap, the great advantage of this design is that Widget_Store is now a
general-purpose iterator type (derived from
Widget_Iteration.Reproducable_Sequence probably), and so any unit that takes
a widget iterator type can have Widget_Stores passed into it with no further
ado. A generic procedure:

   generic
      package Specific_Iteration is new Iteration(<>);
   procedure Print_a_List (List: in out
Specific_Iteration.Terminating_Sequence'Class);

   procedure Print_a_List (List: in out
Specific_Iteration.Terminating_Sequence'Class) is
      Item: Specific_Iteration.Element_Type;
   begin
      while not End_of_Data(List) loop -- dispatching
         Read(List,Item); -- dispatching
         Put_Line(Item);
      end loop;
   end;

can be used to print out the items in any container of any type (that
conforms to my design):

   procedure Print_Widgets is new Print_a_List(Widget_Iteration);

   ...

   Print_Widgets(Nuts);
   Print_Widgets(Bolts);

Phew! I hope this clarifies things. It's really not too difficult in actual
usage, is it? In big software, it would save a huge amount of effort, and
Ada is an industrial language.

--
Best wishes,
Nick Roberts






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

* Re: List Container Straw Man
  2001-11-07 19:49       ` Stephen Leake
  2001-11-07 20:30         ` Marin David Condic
@ 2001-11-08  0:06         ` Nick Roberts
  2001-11-09 16:16           ` Stephen Leake
  1 sibling, 1 reply; 34+ messages in thread
From: Nick Roberts @ 2001-11-08  0:06 UTC (permalink / raw)


"Stephen Leake" <stephen.a.leake.1@gsfc.nasa.gov> wrote in message
news:u1yjacqea.fsf@gsfc.nasa.gov...
> Well, I find this very confusing; there is not enough documentation
> for me.
>
> First, you switched from "Sequence_Reproducer" to "Sequence_Recorder".
> Or maybe you left out a type?

I made a mistake: in the Print_a_List procedure declaration, I used the type
Sequence_Producer when I should have used Terminating_Producer. Sorry.

> Why are there three (or four) independent types?

Each adds one extra level of functionality. This is vitally important.

> How do I write to a
> producer object in the first place, so there is something to read?
> Conversely, how do I read from a recorder?

Remember, an abstract type promises certain operations (and assumed
characteristics). The concrete types derived from it must fulfil those
promised operations (and should fulfil the characteristics), but nothing
stops them adding more operations (and characteristics) of their own!

For example, a list type might be derived from Sequence_Recorder, so that
its contents can be read using Read and End_of_Data, and then re-read using
Restart, and then rewritten using Rewrite and Write. These are the promised
operations that the list type must fulfil, but it could add many others
(insertion, deletion, whatever).

Take another example, a random number generator (RNG). An RNG type might be
derived from Sequence_Producer (the most primitive, non-terminating type).
This means you can read from it using Read, but there is no end to the data
(and no End_of_Data function). 'Read' is the sole promised operation. The
RNG type would doubtless add at least one other operation to allow seeding
of itself.

This is why it is vital to have many types, each adding a small set of extra
'promised' operations.

And because objects (values) of both the list type, the RNG type (or indeed
any other container type conforming to the design) can be passed straight
into any unit which takes one of the abstract iterator types as a parameter,
it means you get the 'write once, use anywhere' effect of good software
engineering.

> > In this way, a piece of software which only needs to iterate over a
> > container can be passed any of the list types, or other container types.
>
> This is true. But it leads to the "complex instantiation" problem that
> is one requirement for the list package under discussion.

Please see my reply to Marin in this thread. I hope it shows that the
instantiations you need (two) are not really all that onerous.

> It also introduces tagged types, which some users might want to avoid
> (they can have run-time overhead, or be hard to test).

I don't think that's true in the great majority of cases. Ada can implement
tagged types very efficiently (because it does not have to deal with
multiple inheritance). I suppose hard data on this will be hard to get.

> Personally, I've never run across a situation where this abstract
> container design really made sense; it was always more important to
> optimize the implentation for real-time issues (I'm a rocket
> scientist, after all :).

I use this scheme all the time. I don't think it's unsuitable for most
real-time software. Many actual container types will be (but that's a
different matter).

> In a truly complete library, I think both options should be available;
> abstract containers and concrete, simple lists. Perhaps the "Dennison
> List" package could be used to implement the doubly-linked list
> variant of the abstract container package; would that work for you?

For the sake of saving one instantiation? Maybe, but I doubt it.

> > Please don't get this elementary aspect of the design wrong!
>
> "Wrong" is too strong. Just because some people give different design
> options different importance does not make them wrong!

You're right, of course, but I get a little frustrated at times, Stephe!

--
Best wishes,
Nick Roberts






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

* Re: A question and a request
  2001-11-07 12:54         ` David C. Hoos, Sr.
@ 2001-11-08  2:35           ` dale
  0 siblings, 0 replies; 34+ messages in thread
From: dale @ 2001-11-08  2:35 UTC (permalink / raw)


comp.lang.ada@ada.eu.org wrote:

> The above paragraph is simply wrong.  The excetpion which will be
> raised is not Program_Error, but Constraint_Error.

:-) it says that an exception is a program error, not that the
the exception raised is called Program_Error.


Dale



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

* Re: List Container Straw Man
  2001-11-07 23:58           ` Nick Roberts
@ 2001-11-08  4:34             ` Jeffrey Carter
  2001-11-08 10:45             ` Ehud Lamm
  1 sibling, 0 replies; 34+ messages in thread
From: Jeffrey Carter @ 2001-11-08  4:34 UTC (permalink / raw)


[regarding Nick Robert's suggestion for a list package specification]

I'm afraid I don't find your suggestion very palatable. It appears to be
difficult to understand, with names and operations that seem to have
nothing to to with lists or data structures in general. It also requires
multiple instantiations to obtain a simple list structure, and it seems
that even the author is unable to keep the many types with opaque names
straight.

This impression may be because we have only seen code snippets. If this
is the technique used in an existing library that you have used, supply
a pointer to this library, much as Wright has done in proposing the
Booch components, or I have done in proposing
PragmARC.List_Unbounded_Unprotected. If not, do as Dennison has done and
provide full specifications that you have compiled. Perhaps then our
misunderstandings will clear up.

-- 
Jeff Carter
"Sons of a silly person."
Monty Python & the Holy Grail



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

* Re: List Container Straw Man
  2001-11-07 20:30         ` Marin David Condic
  2001-11-07 23:58           ` Nick Roberts
@ 2001-11-08 10:41           ` Ehud Lamm
  2001-11-08 19:20             ` Marin David Condic
  2001-11-09 16:39             ` Ted Dennison
  1 sibling, 2 replies; 34+ messages in thread
From: Ehud Lamm @ 2001-11-08 10:41 UTC (permalink / raw)


I agree with Marin's goal, but I am also unsure of the best way to achieve
them.

One specific issue, is that the working by extending tagged types naturally
leads to using child packages. Most will be generic if, like me, you prefer
Element_Type to be generic.
This leads to the nasty issues of nested instantations, which are quite hard
to hide from the programmer using the packages, unless I am missing
something.

Ehud





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

* Re: List Container Straw Man
  2001-11-07 23:58           ` Nick Roberts
  2001-11-08  4:34             ` Jeffrey Carter
@ 2001-11-08 10:45             ` Ehud Lamm
  2001-11-08 19:09               ` Nick Roberts
  1 sibling, 1 reply; 34+ messages in thread
From: Ehud Lamm @ 2001-11-08 10:45 UTC (permalink / raw)


Nick Roberts <nickroberts@adaos.worldonline.co.uk> wrote in message
news:9scke8$12jb14$3@ID-25716.news.dfncis.de...
> To recap, the great advantage of this design is that Widget_Store is now a
> general-purpose iterator type (derived from
> Widget_Iteration.Reproducable_Sequence probably), and so any unit that
takes
> a widget iterator type can have Widget_Stores passed into it with no
further
> ado.

I like that, but only if we can simplify the design.

Am I right in _comparing_ (not equating) your approach to having an ancestor
type like Object or ANY, that all element types are derived from - thus
ensuring a common interface?

Ehud





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

* Re: List Container Straw Man
  2001-11-08 10:45             ` Ehud Lamm
@ 2001-11-08 19:09               ` Nick Roberts
  2001-11-09 16:32                 ` Ted Dennison
  0 siblings, 1 reply; 34+ messages in thread
From: Nick Roberts @ 2001-11-08 19:09 UTC (permalink / raw)


"Ehud Lamm" <mslamm@mscc.huji.ac.il> wrote in message
news:9sdnva$dpk$1@news.huji.ac.il...
> ...
> Am I right in _comparing_ (not equating) your approach to having an
ancestor
> type like Object or ANY, that all element types are derived from - thus
> ensuring a common interface?

Not really. My approach (as Ted's) uses generic packages instantiated with
the element type. I use a hierarchy of tagged types to represent iterators
(of gradually increasing complexity) based on that element type: it is this
which ensures a common (iterator) interface.

Typeless (nominally typeless), and 'reflective', languages, such as
Smalltalk, can get away with having containers based on a single root
element class, because the containers are always able to adapt sufficient to
cope with any element object thrown at them. Ada is not like this.

As regards my proposal, the element type must be definite. However, nothing
stops it being an access-to-classwide type:

   type Object_Ref is access all Object'Class;

allowing stores to deal, indirectly, with objects of all sorts whose types
are derived from Object.






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

* Re: List Container Straw Man
  2001-11-08 10:41           ` Ehud Lamm
@ 2001-11-08 19:20             ` Marin David Condic
  2001-11-08 20:35               ` Ehud Lamm
  2001-11-09 16:39             ` Ted Dennison
  1 sibling, 1 reply; 34+ messages in thread
From: Marin David Condic @ 2001-11-08 19:20 UTC (permalink / raw)


Well, consider this:

If we could take Ted's List package spec and - somehow beneath it -
implement its body with the Booch Components, then you get the Booch
Components if you want them or you get a plain-vanilla simple List if that's
all you want.

The same concept might be done with Nick's ideas - but I'm leaving these
tasks as exercises for the student. :-)

Not being familiar enough with the BC's, allow me to ask: Is there some way
of getting from Ted's List package spec to a body implemented as some kind
of BC instantiation plus glue logic? A sort of "Thick Binding" to the BC's?
Would it hurt too much to even attempt to get there?

Could the same be done with any of the other potential players?

I find this an intriguing possibility since it would allow for a fairly
sophisticated component library underneath, utilize existing code for
maximum leverage, *and* give the
newbie/student/casual-user/simple-case-implementor something not too painful
to use.

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Ehud Lamm" <mslamm@mscc.huji.ac.il> wrote in message
news:9sdnng$djs$1@news.huji.ac.il...
> I agree with Marin's goal, but I am also unsure of the best way to achieve
> them.
>






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

* Re: List Container Straw Man
  2001-11-08 19:20             ` Marin David Condic
@ 2001-11-08 20:35               ` Ehud Lamm
  0 siblings, 0 replies; 34+ messages in thread
From: Ehud Lamm @ 2001-11-08 20:35 UTC (permalink / raw)


Well, essentially you are porposing a layered design.
This approach has merits. In fact, my original suggestions were along these
lines. I didn't think specifically about the BC, but I did think about
providing some sort of usability layer.

Howerver, I think that this can lead to code bloat and make the library
harder to use.
My current view is that it may be possible to design bottom up, and only use
this sort of layering in some specific problematic areas (perhaps memory
mangement or concurrency).

Ehud





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

* Re: List Container Straw Man
  2001-11-08  0:06         ` Nick Roberts
@ 2001-11-09 16:16           ` Stephen Leake
  2001-11-09 16:24             ` Ehud Lamm
                               ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: Stephen Leake @ 2001-11-09 16:16 UTC (permalink / raw)


"Nick Roberts" <nickroberts@adaos.worldonline.co.uk> writes:

> "Stephen Leake" <stephen.a.leake.1@gsfc.nasa.gov> wrote in message
> news:u1yjacqea.fsf@gsfc.nasa.gov...
> > Well, I find this very confusing; there is not enough documentation
> > for me.
> >
> > First, you switched from "Sequence_Reproducer" to "Sequence_Recorder".
> > Or maybe you left out a type?
> 
> I made a mistake: in the Print_a_List procedure declaration, I used the type
> Sequence_Producer when I should have used Terminating_Producer. Sorry.

Well, ok. But that doesn't respond to my point.

> > Why are there three (or four) independent types?
> 
> Each adds one extra level of functionality. This is vitally important.

They are not "levels"; they are independent! They could easily be in
separate packages, and have nothing to do with each other. At least,
that's what the package you presented says.

> > How do I write to a producer object in the first place, so there
> > is something to read? Conversely, how do I read from a recorder?
> 
> Remember, an abstract type promises certain operations (and assumed
> characteristics). The concrete types derived from it must fulfil those
> promised operations (and should fulfil the characteristics), but nothing
> stops them adding more operations (and characteristics) of their own!

Ok, but once again, you miss my point. The package you presented does
not allow writing to a producer. How is that useful? If _every_
derived type must add a "write" operation, it's a bad design.

> For example, a list type might be derived from Sequence_Recorder, so
> that its contents can be read using Read and End_of_Data, and then

No, there is no "read" operation for Sequence_Recorder in your proposal.

> re-read using Restart, and then rewritten using Rewrite and Write.
> These are the promised operations that the list type must fulfil,
> but it could add many others (insertion, deletion, whatever).
> 
> Take another example, a random number generator (RNG). An RNG type might be
> derived from Sequence_Producer (the most primitive, non-terminating type).
> This means you can read from it using Read, but there is no end to the data
> (and no End_of_Data function). 'Read' is the sole promised operation. The
> RNG type would doubtless add at least one other operation to allow seeding
> of itself.

Well, that makes sense. But we are supposed to be discussing linked
lists, not RNG.

> This is why it is vital to have many types, each adding a small set
> of extra 'promised' operations.

The operations of these four types do _not_ "add" to each other; they
are totally independent.

> And because objects (values) of both the list type, the RNG type (or
> indeed any other container type conforming to the design) can be
> passed straight into any unit which takes one of the abstract
> iterator types as a parameter, it means you get the 'write once, use
> anywhere' effect of good software engineering.

Um, I would rather _not_ have to write a procedure that is expecting a
linked list, but must be prepared to deal with an RNG! There may be
some procedures for which this is appropriate (I'd _really_ like to
see an example), but it is not typical.

"Write once, use anywhere" refers to porting applications across
operating systems and CPUs, not to porting procedures across data types.

> > > In this way, a piece of software which only needs to iterate
> > > over a container can be passed any of the list types, or other
> > > container types.
> >
> > This is true. But it leads to the "complex instantiation" problem that
> > is one requirement for the list package under discussion.
> 
> Please see my reply to Marin in this thread. I hope it shows that the
> instantiations you need (two) are not really all that onerous.

Well, my library (http://users.erols.com/leakstan/Stephe/Ada/sal.html)
requires three or four instantiations to get a list, and I don't find
that 'onerous'. But others do, particularly students. So I think it is
worth making the attempt to come up with a useful list package that
only requires one instantiation.

> > It also introduces tagged types, which some users might want to
> > avoid (they can have run-time overhead, or be hard to test).
> 
> I don't think that's true in the great majority of cases. 

Well, you are entitled to your opinion, as I am to mine. But until
someone comes up with hard survey data, this point cannot be ignored.

> Ada can implement tagged types very efficiently (because it does not
> have to deal with multiple inheritance). I suppose hard data on this
> will be hard to get.

Yes.

> > Personally, I've never run across a situation where this abstract
> > container design really made sense; it was always more important
> > to optimize the implentation for real-time issues (I'm a rocket
> > scientist, after all :).
> 
> I use this scheme all the time. I don't think it's unsuitable for most
> real-time software. 

Um, it is not wise to challenge a rocket scientist on this point! How
many satellites have you launched recently? When was the last time you
had to write code that met a 0.01 millisecond time stamp accuracy
requirement, and did it continuously for a week straight? There is no
place for abstract containers in this code; I need to control
_everything_! 

> Many actual container types will be (but that's a different matter).
> 
> > In a truly complete library, I think both options should be available;
> > abstract containers and concrete, simple lists. Perhaps the "Dennison
> > List" package could be used to implement the doubly-linked list
> > variant of the abstract container package; would that work for you?
> 
> For the sake of saving one instantiation? Maybe, but I doubt it.

No, for the sake of allowing applications that don't need the abstract
container type to still get a standard list package, while also
providing a standard abstract container type.

> > > Please don't get this elementary aspect of the design wrong!
> >
> > "Wrong" is too strong. Just because some people give different design
> > options different importance does not make them wrong!
> 
> You're right, of course, but I get a little frustrated at times, Stephe!

Ok. Apology accepted.

To relieve my frustration, please post a compilable example of your
design, that instantiates a linked list package, declares an object of
the list type (named "List_Type" :), writes a sequence of integers
into it, and the reads the sequence back out. That will make many
things about your design much clearer.

-- 
-- Stephe



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

* Re: List Container Straw Man
  2001-11-09 16:16           ` Stephen Leake
@ 2001-11-09 16:24             ` Ehud Lamm
  2001-11-09 16:52               ` Brian Rogoff
  2001-11-09 18:04             ` Darren New
  2001-11-10  3:24             ` Nick Roberts
  2 siblings, 1 reply; 34+ messages in thread
From: Ehud Lamm @ 2001-11-09 16:24 UTC (permalink / raw)


Stephen Leake <stephen.a.leake.1@gsfc.nasa.gov> wrote in message
news:u3d3nrkbe.fsf@gsfc.nasa.gov...
> Well, my library (http://users.erols.com/leakstan/Stephe/Ada/sal.html)
> requires three or four instantiations to get a list, and I don't find
> that 'onerous'. But others do, particularly students. So I think it is
> worth making the attempt to come up with a useful list package that
> only requires one instantiation.
>

Since we seem to be discussing various Ada features...
I was always ready to defend Ada's lack of automatic instnatiation, but I
seem to be loosing me resovle.
Maybe some one can re-convince me ;-)

For the purposes discussed here, I would be happy with a solution allowing
me to create partial instantaions, so that only the top level would need to
be instantiated by the user.
(This is close to "template specialization", I think, but not exactly the
same thing).
Is there any elegant idiom for doing this?
(If I am not clear, I'll try to post an example).

Ehud






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

* Re: List Container Straw Man
  2001-11-08 19:09               ` Nick Roberts
@ 2001-11-09 16:32                 ` Ted Dennison
  2001-11-10  2:20                   ` Nick Roberts
  0 siblings, 1 reply; 34+ messages in thread
From: Ted Dennison @ 2001-11-09 16:32 UTC (permalink / raw)


In article <9seup4$12h0ar$3@ID-25716.news.dfncis.de>, Nick Roberts says...
>
>Not really. My approach (as Ted's) uses generic packages instantiated with
>the element type. I use a hierarchy of tagged types to represent iterators
>(of gradually increasing complexity) based on that element type: it is this
>which ensures a common (iterator) interface.

I don't really have any major problems with this approach in a component
facility in general. The main issue I have with it for the effort we are talking
about is that it requires those multiple generic instantiations. That was the
complaint with Booch that started this whole effort. If people can live with
those, then my vote is for Booch. Otherwise, I think we are forced to design
things using only independant generic packages.

My ideal component library, like yours, would be much more complex than the
strawman. Heck, it may even be the same as yours. But we aren't shooting for
ideal here. We are shooting for something *simple* that Ada newbies can figure
out w/o much trouble, but which is still usable for most serious applications.

If you can find a way to default things so that there's a way to use it w/ only
one instantiation, I'd like to see it.

(ps. I'm sorry for leaving the discussion for so long. I've been on jury duty
all week).

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html

No trees were killed in the sending of this message. 
However a large number of electrons were terribly inconvenienced.



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

* Re: List Container Straw Man
  2001-11-08 10:41           ` Ehud Lamm
  2001-11-08 19:20             ` Marin David Condic
@ 2001-11-09 16:39             ` Ted Dennison
  1 sibling, 0 replies; 34+ messages in thread
From: Ted Dennison @ 2001-11-09 16:39 UTC (permalink / raw)


In article <9sdnng$djs$1@news.huji.ac.il>, Ehud Lamm says...
>One specific issue, is that the working by extending tagged types naturally
>leads to using child packages. Most will be generic if, like me, you prefer
>Element_Type to be generic.
>This leads to the nasty issues of nested instantations, which are quite hard
>to hide from the programmer using the packages, unless I am missing
>something.

I don't see a way out of it either. The implication here is that you can have
one of:

o  Simple instantiation.
o  Tagged containers and/or container child packages.

You *cannot* have both. Therefore I'd say at this point that either we have to
admit that Booch's (and other's) implementations aren't really so unacceptable,
or we have to agree to stick with designs that don't use tagged containers and
child packages. To some this may have been obvious, but bringing issues like
this out into the open was one of the reasons for presenting the strawman.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html

No trees were killed in the sending of this message. 
However a large number of electrons were terribly inconvenienced.



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

* Re: List Container Straw Man
  2001-11-09 16:24             ` Ehud Lamm
@ 2001-11-09 16:52               ` Brian Rogoff
  0 siblings, 0 replies; 34+ messages in thread
From: Brian Rogoff @ 2001-11-09 16:52 UTC (permalink / raw)


On Fri, 9 Nov 2001, Ehud Lamm wrote:
> Since we seem to be discussing various Ada features...
> I was always ready to defend Ada's lack of automatic instnatiation, but I
> seem to be loosing me resovle.

This is kind of funny. A few years ago I tried writing an STL like library
in Ada, just expanding the original RPI version. By the end of the whole
exercise I was convinced that automatic instantiation of some kind would 
really be a big improvement. 

> Maybe some one can re-convince me ;-)

Sure, you can defend it. Hysterical raisins. You can also defend the
gruesome syntax of C++ the same way :-).

-- Brian





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

* Re: List Container Straw Man
  2001-11-09 16:16           ` Stephen Leake
  2001-11-09 16:24             ` Ehud Lamm
@ 2001-11-09 18:04             ` Darren New
  2001-11-09 20:05               ` Stephen Leake
  2001-11-10  3:24             ` Nick Roberts
  2 siblings, 1 reply; 34+ messages in thread
From: Darren New @ 2001-11-09 18:04 UTC (permalink / raw)


Stephen Leake wrote:
> Um, it is not wise to challenge a rocket scientist on this point! How
> many satellites have you launched recently? When was the last time you
> had to write code that met a 0.01 millisecond time stamp accuracy
> requirement, and did it continuously for a week straight? There is no
> place for abstract containers in this code; I need to control
> _everything_!

On the other hand, it *is* a "newbie" library. I want to know where an
Ada newbie can get a job writing real-time code to run satellites. :-)
Everything I've seen has required five years or more of embedded
programming experience.
 
Seriously, I think the complications of storage pools, real-time, etc
etc might be too much to put into a simple language. By the time you're
writing your own storage pools, having three instantiations to get to
your desired data type probably isn't a problem, right?

-- 
Darren New 
San Diego, CA, USA (PST). Cryptokeys on demand.
   You will soon read a generic fortune cookie.



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

* Re: List Container Straw Man
  2001-11-09 18:04             ` Darren New
@ 2001-11-09 20:05               ` Stephen Leake
  0 siblings, 0 replies; 34+ messages in thread
From: Stephen Leake @ 2001-11-09 20:05 UTC (permalink / raw)


Darren New <dnew@san.rr.com> writes:

> Stephen Leake wrote:
> > Um, it is not wise to challenge a rocket scientist on this point! How
> > many satellites have you launched recently? When was the last time you
> > had to write code that met a 0.01 millisecond time stamp accuracy
> > requirement, and did it continuously for a week straight? There is no
> > place for abstract containers in this code; I need to control
> > _everything_!
> 
> On the other hand, it *is* a "newbie" library. I want to know where an
> Ada newbie can get a job writing real-time code to run satellites. :-)
> Everything I've seen has required five years or more of embedded
> programming experience.

Good point. Sorry for the flames :).

> Seriously, I think the complications of storage pools, real-time,
> etc etc might be too much to put into a simple language. By the time
> you're writing your own storage pools, having three instantiations
> to get to your desired data type probably isn't a problem, right?

Yes, I was forgetting the newbie aspect. But "real-time" is not
something that can be added later; it would be helpful to at least
mention that aspect in this package.

-- 
-- Stephe



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

* Re: A question and a request
  2001-11-07  4:44     ` A question and a request Eric Merritt
                         ` (2 preceding siblings ...)
  2001-11-07 16:32       ` Jeffrey Carter
@ 2001-11-09 23:32       ` Matthew Heaney
  3 siblings, 0 replies; 34+ messages in thread
From: Matthew Heaney @ 2001-11-09 23:32 UTC (permalink / raw)



"Eric Merritt" <cyberlync@yahoo.com> wrote in message
news:mailman.1005116423.21054.comp.lang.ada@ada.eu.org...
> The addition operator is taking two disparate but
> related types and adding them.

You have to be careful about how you use the terms "type" and "subtype".
The (sub)types you defined simply name subsets of a common type.

> This is fine,
> up-casting is a normal thing. However, when the result
> is returned it is not (should not be?) an instance of
> the subtype.

The addition operator looks like this:

   function "+" (L, R : Integer'Base) return Integer'Base;

Only a "type" has operations.  Subtypes merely name a range of values within
the scalar type.

Your addition operator is returning a value in the set (whose values are
named by the type).  Then there is an assignment, which checks to make sure
the value (on the RHS) lies in the range of the subtype (of the object on
the LHS).

> It seems that the compiler is
> down-casting automatically. This bothers me and it
> seams that is violates Ada's strong typing. What am I
> missing here?

No, it does not, because there is only one type: the type whose first named
subtype is Integer.






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

* Re: List Container Straw Man
  2001-11-09 16:32                 ` Ted Dennison
@ 2001-11-10  2:20                   ` Nick Roberts
  2001-11-10 19:50                     ` Ehud Lamm
  0 siblings, 1 reply; 34+ messages in thread
From: Nick Roberts @ 2001-11-10  2:20 UTC (permalink / raw)


"Ted Dennison" <dennison@telepath.com> wrote in message
news:AyTG7.18995$xS6.30775@www.newsranger.com...
> In article <9seup4$12h0ar$3@ID-25716.news.dfncis.de>, Nick Roberts says...
> >
> >Not really. My approach (as Ted's) uses generic packages instantiated
with
> >the element type. I use a hierarchy of tagged types to represent
iterators
> >(of gradually increasing complexity) based on that element type: it is
this
> >which ensures a common (iterator) interface.
>
> I don't really have any major problems with this approach in a component
> facility in general. The main issue I have with it for the effort we are
talking
> about is that it requires those multiple generic instantiations. That was
the
> complaint with Booch that started this whole effort. If people can live
with
> those, then my vote is for Booch. Otherwise, I think we are forced to
design
> things using only independant generic packages.

But I really feel this is like someone trying to argue that an aeroplane
would be much less complex if it didn't have any wings. In real software, I
am certain, my design would save great quantities of programming (writing
the same old thing over and over again for different container types). Ada
is supposed to be about software re-use; wouldn't it be a great shame if a
common containers library for Ada failed to facilitate re-use?

> My ideal component library, like yours, would be much more complex than
the
> strawman. Heck, it may even be the same as yours. But we aren't shooting
for
> ideal here. We are shooting for something *simple* that Ada newbies can
figure
> out w/o much trouble, but which is still usable for most serious
applications.

Well, I've shown a few examples of using my design. It basically requires
two instantiations (one generic parameter each). Students could learn this
pattern by rote until they got to understanding it (just like Sequential_IO
and Direct_IO). I can't believe that it's too complicated for anyone.

> If you can find a way to default things so that there's a way to use it w/
only
> one instantiation, I'd like to see it.

There is a way (you put the abstract types package instantiation inside the
container package), but this trick is poor design in most cases, since it
doesn't decouple the software so much. (A general principle of good software
engineering is to maximise the decoupling of the modules.) The user should
just do the two instantiations and not complain! It's only a bit of typing*.

--
Nick Roberts





*and Ada is a strongly typed language (sorry ;-)






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

* Re: List Container Straw Man
  2001-11-09 16:16           ` Stephen Leake
  2001-11-09 16:24             ` Ehud Lamm
  2001-11-09 18:04             ` Darren New
@ 2001-11-10  3:24             ` Nick Roberts
  2 siblings, 0 replies; 34+ messages in thread
From: Nick Roberts @ 2001-11-10  3:24 UTC (permalink / raw)


"Stephen Leake" <stephen.a.leake.1@gsfc.nasa.gov> wrote in message
news:u3d3nrkbe.fsf@gsfc.nasa.gov...
>
> Well, ok. But that doesn't respond to my point.
>
> > > Why are there three (or four) independent types?
> >
> > Each adds one extra level of functionality. This is vitally important.
>
> They are not "levels"; they are independent! They could easily be in
> separate packages, and have nothing to do with each other. At least,
> that's what the package you presented says.

With respect, Stephe, you need to review your understanding of tagged types
(or review the code I posted). They aren't independent; each is derived from
the one before. In that way, each represents a new level of functionality,
with one or two operations added to the operations inherited from the ones
before. You need to be able to understand this.

> > > How do I write to a producer object in the first place, so there
> > > is something to read? Conversely, how do I read from a recorder?

A concrete container implementing the operations promised by a sequence
producer would probably add its own operations regarding where the data is
coming from, according to the specific characteristics of that container.

You can read data from a sequence recorder with the Read procedure that it
inherits (from the type Sequence_Producer).

> > Remember, an abstract type promises certain operations (and assumed
> > characteristics). The concrete types derived from it must fulfil those
> > promised operations (and should fulfil the characteristics), but nothing
> > stops them adding more operations (and characteristics) of their own!
>
> Ok, but once again, you miss my point. The package you presented does
> not allow writing to a producer. How is that useful?

You need to grasp the concept of abstract types. They force a derived type
to fulfil certain operations; they do not prevent derived types from adding
further operations.

> If _every_
> derived type must add a "write" operation, it's a bad design.

Every concrete type (derived from one of my abstract types) must implement
the operations promised by the abstract type it is derived from. If it is
derived from Sequence_Recorder, it must implement a write operation. If it
is derived from one of the others, then it may implement a write operation
(if it is appropriate to the concrete type). Explain, please, why this is a
bad design.

> > For example, a list type might be derived from Sequence_Recorder, so
> > that its contents can be read using Read and End_of_Data, and then
>
> No, there is no "read" operation for Sequence_Recorder in your proposal.

Yes there is, inherited from Sequence_Producer.

> > Take another example, a random number generator (RNG). An RNG type might
be
> > derived from Sequence_Producer (the most primitive, non-terminating
type).
> > This means you can read from it using Read, but there is no end to the
data
> > (and no End_of_Data function). 'Read' is the sole promised operation.
The
> > RNG type would doubtless add at least one other operation to allow
seeding
> > of itself.
>
> Well, that makes sense. But we are supposed to be discussing linked
> lists, not RNG.

But the POINT is that my proposal enables the container types to be
decoupled from most of the algorithms used to manipulate them. If I wrote a
procedure whose job was to read 100 floats and produce an average, I could
then apply this procedure to a RNG as easily as to a set of numbers read
from a list container, or any other container. Doesn't that seem a useful
idea to you?

> > This is why it is vital to have many types, each adding a small set
> > of extra 'promised' operations.
>
> The operations of these four types do _not_ "add" to each other; they
> are totally independent.

They aren't and they do. Do you not see how?

> > And because objects (values) of both the list type, the RNG type (or
> > indeed any other container type conforming to the design) can be
> > passed straight into any unit which takes one of the abstract
> > iterator types as a parameter, it means you get the 'write once, use
> > anywhere' effect of good software engineering.
>
> Um, I would rather _not_ have to write a procedure that is expecting a
> linked list, but must be prepared to deal with an RNG! There may be
> some procedures for which this is appropriate (I'd _really_ like to
> see an example), but it is not typical.

You're not being forced to do anything! You're being enabled to do things,
optionally.

An example might be:

   package Float_Iteration is new Iteration(Float);
   ...
   procedure Compute_Mean (
      Data: in Float_Iteration.Sequence_Producer'Class;
      Mean: out Float) is
      Total: Float := 0.0;
      Item: Float;
   begin
      for i in 1..100 loop
         Read(Data,Item);
         Total := Total + Item;
      end loop;
      Mean := Total / 100;
   end;

and then you could call:

   Seed(My_RNG,X);
   Compute_Mean(My_RNG,Avg);

as easily as you could call:

   Compute_Mean(Sales_Figues,Avg);

or for any other Float container. Notice the special operation Seed called
for My_RNG; nothing in my scheme prevents you from manipulating containers
according to their own special operations.

> "Write once, use anywhere" refers to porting applications across
> operating systems and CPUs, not to porting procedures across data types.

"Write once RUN anywhere" is the slogan touted by Sun (for Java). I was
paraphrasing. It was a joke. Phew. :-(

> Well, my library (http://users.erols.com/leakstan/Stephe/Ada/sal.html)
> requires three or four instantiations to get a list, and I don't find
> that 'onerous'. But others do, particularly students. So I think it is
> worth making the attempt to come up with a useful list package that
> only requires one instantiation.

Surely the most important thing to teach students is good software design
(not 'easy' software design)? Students would rather not do any programming
at all, if they could get away with it!

> Um, it is not wise to challenge a rocket scientist on this point! How
> many satellites have you launched recently? When was the last time you
> had to write code that met a 0.01 millisecond time stamp accuracy
> requirement, and did it continuously for a week straight? There is no
> place for abstract containers in this code; I need to control
> _everything_!

No challenge intended. Your application domain is unusual, even within the
field of real-time.

> No, for the sake of allowing applications that don't need the abstract
> container type to still get a standard list package, while also
> providing a standard abstract container type.

Suppose we provide two libraries: (1) one which is based on the abstract
types, and reqires one extra instantiation (per data type); (2) one where
each container type is standalone. The problem is that everyone will use
(2)!

So? Then, when they come to need algorithm A, that they have written for
container type T1, to be applied to container type T2, they've got to
rewrite it.

It sounds a bit authoritarian perhaps ;-) but if we compel people to use (1)
in the first place, then when they come to need algorithm A for container
type T2, they just call A. No rewriting. It's called software re-use, and
it's what Ada is supposed to be all about.

> To relieve my frustration, please post a compilable example of your
> design, that instantiates a linked list package, declares an object of
> the list type (named "List_Type" :), writes a sequence of integers
> into it, and the reads the sequence back out. That will make many
> things about your design much clearer.

I've tried to e-mail you twice Stephe, but your firewall won't let me.
Honest. Posting big stuff or attachments to Usenet is not
practicable/allowed/netiquette. Hopefully Big Dave will get us a spot on
AdaPower.

--
Nick Roberts






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

* Re: List Container Straw Man
  2001-11-10  2:20                   ` Nick Roberts
@ 2001-11-10 19:50                     ` Ehud Lamm
  2001-11-11  3:48                       ` Nick Roberts
  0 siblings, 1 reply; 34+ messages in thread
From: Ehud Lamm @ 2001-11-10 19:50 UTC (permalink / raw)


Nick Roberts <nickroberts@adaos.worldonline.co.uk> wrote in message
news:9sib28$13aeg3$6@ID-25716.news.dfncis.de...
> Well, I've shown a few examples of using my design. It basically requires
> two instantiations (one generic parameter each). Students could learn this
> pattern by rote until they got to understanding it (just like
Sequential_IO
> and Direct_IO). I can't believe that it's too complicated for anyone.
>

Essentialy I agree. I can live with giving an example, and saying "You'll
understand when you grow up."
My problem is on a more semantic level. To understand your approach students
must understand about inheritance (or so it seems to me). It is not like
instanating Integer_IO, which results in having "normal" procedures.

(And even this was deemed enough trouble, so Integer_Text_IO was defined).

Now perhaps my approach is all wrong - and people should start with
inheritance, only to graduate to old-fashioned procedural thinking.
I really am not sure. But as things are right now, many Ada programmers come
from Ada-83, not from Smalltalk... Many students follow a similar path from
Pascal/C to Ada/Java.

Ehud





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

* Re: List Container Straw Man
  2001-11-10 19:50                     ` Ehud Lamm
@ 2001-11-11  3:48                       ` Nick Roberts
  0 siblings, 0 replies; 34+ messages in thread
From: Nick Roberts @ 2001-11-11  3:48 UTC (permalink / raw)


"Ehud Lamm" <mslamm@mscc.huji.ac.il> wrote in message
news:9sk0mc$39j$1@news.huji.ac.il...
> ...
> My problem is on a more semantic level. To understand your approach
students
> must understand about inheritance (or so it seems to me). It is not like
> instanating Integer_IO, which results in having "normal" procedures.
> ...

Not really. Having cited the magic incantation:

   package Widget_Iteration is new SCL.Iteration(Widget_Type);
   package Widget_Lists is new SCL.Lists.Unbounded(Widget_Iteration);
   subtype Widget_List is Widget_Lists.Unbounded_List;

your students can (at first) use the type Widget_List straightforwardly
without having to touch upon anything to do with inheritance, e.g.:

   L: Widget_List;
   W: Widget_Type;
   ...
   while not End_of_File(F) loop
      Read_Widget(F,W);
      Append(L,W); -- add to end of list L
   end loop;

and so on. Later on in the course (much later), when they have done tagged
types, inheritance, abstract types, generic packages, signature packages,
etc., you can then introduce them to the idea of defining a procedure that
can work with different container types, e.g.:

   function Count (
      Widget: in Widget_Type;
      Within: in out Widget_Iteration.Sequence_Producer'Class) return
Natural;

and so on.

--
Best wishes,
Nick Roberts






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

end of thread, other threads:[~2001-11-11  3:48 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-11-06 16:45 List Container Straw Man Nick Roberts
2001-11-06 17:29 ` Stephen Leake
2001-11-06 18:25   ` Marin David Condic
2001-11-06 23:02     ` Nick Roberts
2001-11-07 19:49       ` Stephen Leake
2001-11-07 20:30         ` Marin David Condic
2001-11-07 23:58           ` Nick Roberts
2001-11-08  4:34             ` Jeffrey Carter
2001-11-08 10:45             ` Ehud Lamm
2001-11-08 19:09               ` Nick Roberts
2001-11-09 16:32                 ` Ted Dennison
2001-11-10  2:20                   ` Nick Roberts
2001-11-10 19:50                     ` Ehud Lamm
2001-11-11  3:48                       ` Nick Roberts
2001-11-08 10:41           ` Ehud Lamm
2001-11-08 19:20             ` Marin David Condic
2001-11-08 20:35               ` Ehud Lamm
2001-11-09 16:39             ` Ted Dennison
2001-11-08  0:06         ` Nick Roberts
2001-11-09 16:16           ` Stephen Leake
2001-11-09 16:24             ` Ehud Lamm
2001-11-09 16:52               ` Brian Rogoff
2001-11-09 18:04             ` Darren New
2001-11-09 20:05               ` Stephen Leake
2001-11-10  3:24             ` Nick Roberts
2001-11-06 23:52   ` Nick Roberts
2001-11-07  4:44     ` A question and a request Eric Merritt
2001-11-07 11:00       ` Preben Randhol
2001-11-07 12:54         ` David C. Hoos, Sr.
2001-11-08  2:35           ` dale
2001-11-07 13:24         ` Eric Merritt
2001-11-07 13:58       ` James Rogers
2001-11-07 16:32       ` Jeffrey Carter
2001-11-09 23:32       ` Matthew Heaney

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