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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,2c6139ce13be9980 X-Google-Attributes: gidfac41,public X-Google-Thread: 1108a1,2c6139ce13be9980 X-Google-Attributes: gid1108a1,public X-Google-Thread: 103376,3d3f20d31be1c33a X-Google-Attributes: gid103376,public X-Google-Thread: f43e6,2c6139ce13be9980 X-Google-Attributes: gidf43e6,public From: nospam@thanks.com.au (Don Harrison) Subject: Re: Interface/Implementation (was Re: Design by Contract) Date: 1997/09/09 Message-ID: X-Deja-AN: 270926247 Sender: news@syd.csa.com.au References: Reply-To: nospam@thanks.com.au X-Nntp-Posting-Host: dev50 Organization: CSC Australia, Sydney Newsgroups: comp.object,comp.software-eng,comp.lang.ada,comp.lang.eiffel Date: 1997-09-09T00:00:00+00:00 List-Id: Robert Dewar wrote: :Don says : :<> : :No, and neither does the Ada 83 standard in this context, so your comment :about finding this annoying is simply confused. Yes, as you say, operations etc. declared in the spec can be freely ordered in the body. My mistake. What I'm referring to, is the fact that depedendency-related ordering is imposed for elements (operations/types etc.) declared and used in the *same* spec or the *same* body - a different issue, as you say below. (More on this at the end). :We are talking about the order in the body of entities declared in the spec. :Clearly these have all been previously declared, so the order of subprogram :bodies in the body of the package is completely free, I have no idea what :you are talking about. While the order of elements previously declared in the spec is free, the order of elements declared in the body is not, which, though explicable, is inconsistent. :If you see a different ordering in the spec than in the body, it is not :because of "compilation dependencies", it is because the programmer thinks :this is a good idea.. [..] :On the other hand, you never need to browse the body as a client of the :package, so the logical ordering requirement for such browsing does not :apply. The two files are viewed VERY differently in an Ada environment, :not only will different people touch them, but different people will look :at them, and the client of a package should almost never be looking inside :the body -- if they need to, it shows something is wrong with the spec. The client and the implementer are not necessarily different parties. For example, for a maintainer of a package whose spec and body were written by different people, it can be annoying to find them ordered differently. At least, that is my experience. :Incidentally the separate files aid this goal. An Ada programmer expects :to find everything they need in one file, and is definitely annoyed, and :knows that there is a bug, if they have to go and look at the body. If you :put things in one file, even a single file with different views, it is far :too easy for programmers to get in the habit of looking at this file without :going though the restricted interface view, and thus not to be sensitive :enough to enforcing the separation. Yes, tools could make this harder, but :in practice, not everyone is using such tools, and it is all too easy for :a client to easily browse the implementation. In the case of Eiffel, commercial implementations *do* provide a short form tool, so storing interface and implementation in separate files isn't necessary. :Going back to the ordering issue, in the body, I usually prefer to arrange :the subprograms in alphabetical order, because this is easier for reference :purposes for the implementor who needs to go to a particular body to debug :or otherwise fiddle around. My own preference is to organise along functional lines in both spec and body. That way, related operations get grouped together and you can often just scroll up or down to look at what you're interested in. That's why I have no problem with consistent ordering being enforced. However, forcing consistent ordering doesn't necessarily mean that you can't *access* in some other order. An Eiffel implementation could provide, for example, a "very short form" consisting of just feature names. Feature ordering in the window could be changed in just the same way as you can select different directory views in a file manager. Possible feature views might be: a) Same as short form (the default) b) Alpabetical c) Most recently updated d) etc. With such a capability, forced consistent ordering would not be the end of the world if you prefer some other view. :That's the *crucial* difference between the spec and the body, the spec gets :browsed as a whole, the body never does. Not if you order on functional lines, in which case, *sections* may be browsed as a whole. BTW, wouldn't it be hard to maintain alphabetical ordering when you add operations specific to the body? - you would lose your ordering due to dependencies. :I quite see how Eiffel programmers, :or other programmers not used to this strong separation would not see the :benefit of being able to organize the two objects differently, you do not :miss what you do not have. OTOH, I can see why Ada programmers might consider this more of an issue because they are dealing with modules of typically coarser granularity than Eiffel programmers. In the case of co-encapsulation, Ada modules map one-to-many to abstractions, potentially giving rise to many features. It's less of an issue in Eiffel because modules correspond one-to-one to abstractions. :One of the most widespread weaknesses, even among experienced professional :programmers, is the inability to comprehend the importance of separating :specification from implementation. Note tha the entire "comments are useless, :my code is self documenting" view is fundamentally at odds with this basic :requirement of separation. Sorry, don't see the connection. Can you explain? :Yes, you can separate effectively in any language if you work hard enough :(the equivalent of a separate spec can be created entirely by commenting :even in a language like COBOL or BASIC with absoslutely NO avbstraction :capability of this sort), but in practice, a language like Ada where this :separation is very strong will encourage more programmers to understand :the importance of the separation. In the Ada world, absolutely everyone :understands that you should be able to use a package only looking at its :spec and not its body, and the fact that the spec can be handled separatly :as a coherent compilable entity is one of the most important aspects of :Ada, since it leads even inexperienced not very competent programmers :to fully grasp the importance of the separation of spec and body. I can assure you Eiffel developers place just as much importance on the interface as Ada programmers. With the exception perhaps of the ordering argument (which itself is not very strong, IMO), all of the arguments I've seen advanced in favour of separate interfaces are not intrinsically that at all. They are arguments in favour of being able to *distinguish* between interface and implementation. While these arguments are perfectly valid, they're incorrectly passed off as supporting separate interfaces. They're not. For the purpose of those arguments, how the interface came about is immaterial. It doesn't matter whether it was written first or generated from the implementation. The claim that you need separate interfaces to realise the benefits of distinguishing between them is bogus. :<> : :Though this technical point is completely irrelevant to the main thread :of discussoin here, if you are saying that you should be able to use entities :before they are declared. I strongly disagree. Sure my compiler can make :multiple passes through a source document, but as a human reading the :document, I prefer not to. There is a reason why we arrange text books, :and other materials not to have forward references (such as mentioning :a character in a novel before introducing them). Programs benefit in the :same way from a basically linear approach, in which overall understanding :can be obtaineed in a single linear pass. I agree to the extent that I think a linear pass is useful for gaining an overall impression of what a program does. Consequently, I agree with the recommended Eiffel style of identifying broad categories of functionality which are consistently applied and ordered in all classes. It's then easy to gain a broad-brush view of a class by scanning it linearly. However, once a reader has gained such an impression, they typically want to move from sequential to direct access, more like consulting an encyclopaedia than reading a novel. (I think someone has already mentioned this). In that case, what they want to do is to jump around within the text with the aid of the string search facility of the underlying editor. They get a bonus if the implementation is ordered along functional lines because they can scroll as well. Incidentally, well-written technical books may be read this way as well. Eliminating dependency-related ordering has another advantage: removing the need for redundant pre-declarations (for me, another of Ada's little annoyances). In the absence of this constraint, the redundant lines marked "no longer needed" could be removed from the following declarations in a body: type a_rec; -- no longer needed type a_rec_ptr is access a_rec; type a_rec is record next: a_rec_ptr; end record; procedure do_d; -- no longer needed procedure do_c is begin do_d; end; procedure do_d is begin do_c; end; :But as I noted, this point is totally irrelevant to the discussion, since :of course the spec appears "before" the body, so there are no ordering :relationships imposed on the entities in the body that correspond to those :in the spec in any case. True. Don. (Reverse to reply) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Don Harrison au.com.csa.syd@donh