From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,88093378be1184d4 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-11-06 15:38:04 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!newsmi-us.news.garr.it!newsmi-eu.news.garr.it!NewsITBone-GARR!fu-berlin.de!uni-berlin.de!ppp-1-133.cvx1.telinco.NET!not-for-mail From: "Nick Roberts" Newsgroups: comp.lang.ada Subject: Re: List Container Straw Man Date: Tue, 6 Nov 2001 23:02:44 -0000 Message-ID: <9s9s8p$11vt7l$1@ID-25716.news.dfncis.de> References: <9s941p$11mrei$4@ID-25716.news.dfncis.de> <9s99tt$pdb$1@nh.pace.co.uk> NNTP-Posting-Host: ppp-1-133.cvx1.telinco.net (212.1.136.133) X-Trace: fu-berlin.de 1005089882 35648757 212.1.136.133 (16 [25716]) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Xref: archiver1.google.com comp.lang.ada:15960 Date: 2001-11-06T23:02:44+00:00 List-Id: "Marin David Condic" 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