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-09 20:39:41 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!newsfeeds.belnet.be!news.belnet.be!uni-erlangen.de!fu-berlin.de!uni-berlin.de!ppp-1-20.cvx1.telinco.NET!not-for-mail From: "Nick Roberts" Newsgroups: comp.lang.ada Subject: Re: List Container Straw Man Date: Sat, 10 Nov 2001 03:24:32 -0000 Message-ID: <9sib29$13aeg3$7@ID-25716.news.dfncis.de> References: <9s941p$11mrei$4@ID-25716.news.dfncis.de> <9s99tt$pdb$1@nh.pace.co.uk> <9s9s8p$11vt7l$1@ID-25716.news.dfncis.de> <9scke9$12jb14$4@ID-25716.news.dfncis.de> NNTP-Posting-Host: ppp-1-20.cvx1.telinco.net (212.1.136.20) X-Trace: fu-berlin.de 1005367179 37042691 212.1.136.20 (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:16202 Date: 2001-11-10T03:24:32+00:00 List-Id: "Stephen Leake" 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