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-Thread: a07f3367d7,7ff1de84a8945e80 X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news1.google.com!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!nx02.iad01.newshosting.com!newshosting.com!newsfeed2.ip.tiscali.net!tiscali!newsfeed1.ip.tiscali.net!news.tele.dk!news.tele.dk!small.news.tele.dk!uio.no!fi.sn.net!newsfeed2.tdcnet.fi!news.song.fi!not-for-mail Date: Fri, 14 Aug 2009 19:03:52 +0300 From: Niklas Holsti Organization: Tidorum Ltd User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090706) MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Access types as parameters References: <521c4843-d40f-4545-9e80-ca725e847090@h21g2000yqa.googlegroups.com> <8410fc60-9b8a-4f82-92fc-622a6bbe5931@i18g2000pro.googlegroups.com> <8880c3d0-a07f-4d4e-ac87-372014598576@d15g2000prc.googlegroups.com> <4a83d018$0$26303$4f793bc4@news.tdc.fi> <4a847400$0$26304$4f793bc4@news.tdc.fi> <4a852df2$0$26317$4f793bc4@news.tdc.fi> <1jrxo2acn8evc.x3wfcmp4etbo.dlg@40tude.net> In-Reply-To: <1jrxo2acn8evc.x3wfcmp4etbo.dlg@40tude.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Message-ID: <4a858af5$0$24774$4f793bc4@news.tdc.fi> NNTP-Posting-Host: 81.17.205.61 X-Trace: 1250265845 news.tdc.fi 24774 81.17.205.61:44394 X-Complaints-To: abuse@tdcnet.fi Xref: g2news2.google.com comp.lang.ada:7796 Date: 2009-08-14T19:03:52+03:00 List-Id: Dmitry A. Kazakov wrote: > On Fri, 14 Aug 2009 12:27:02 +0300, Niklas Holsti wrote: > >> Dmitry A. Kazakov wrote: >>> On Thu, 13 Aug 2009 23:13:39 +0300, Niklas Holsti wrote: >>> >>>> Dmitry A. Kazakov wrote: >>>>> On Thu, 13 Aug 2009 11:34:20 +0300, Niklas Holsti wrote: >>>>> >>>>>> Randy Brukardt wrote: >>>>>> >>>>>>> You almost never want redispatching >>>>>> That's interesting as my experience is the opposite: Most of the calls >>>>>> between primitive methods in my code use redispatching. >>>>> Shudder... >>>> Also an interesting reaction. >>>> >>>>> I consider re-dispatch is an indication of a language / design problem, >>>>> because it is a hidden type error. An argument goes as follows. Once you >>>>> have dispatched to some type T, the corresponding controlling parameter is >>>>> of this type. Let we converted it to a class. If now it dispatches again to >>>>> T, then that was just wasting time, if it dispatches to S /= T then it is a >>>>> type error. >>>> To me that is a very abstract and formalistic argument that is easily >>>> weaker than the practical benefits (providing sensible but overridable >>>> default behaviour while avoding code duplication) that make me use >>>> redispatching. >>> If some formal premises are not satisfied (a type consistency is one of >>> them) then it is meaningless to talk about benefits. In an extreme case, >>> you might have an erroneous program that occasionally yields a correct >>> result. Would you see a practical benefit here? >> As I said later in the message to which you are replying, I don't agree >> that redispatching implies a type inconsistency. >> >> Do you use the word "erroneous" in the formal Ada sense, "erroneous >> execution"? Then could you please explain what kind of erroneous >> execution redispatching can cause, that cannot occur without using >> redispatching? As far as I understand, redispatching itself is safe; >> erroneous execution can only come from code in the operations that are >> invoked. > > It was merely a counterexample to "benefit" over "formalism". "Benefit" is > bounded by "formalism", not otherwise. If we consider re-dispatch doubtful > for formal reasons, that overrides any benefits (or we change the > formalism). Or we don't agree on the formalism, which seems to be the case for you and me. >> If your argument is just that a program with redispatching is more >> complex and thus more likely to contain programming errors, I partly >> agree; redispatching makes the sequence of invoked operations more >> dynamic and thus possibly harder to grasp and make correct. But this >> argument applies as well to any kind of run-time dispatching, not just >> to *re*-dispatching. > > I disagree. Dispatching does not make it more complex assuming that all > implementations of the primitive operation are conform the interface. You > write the client program in terms of another type, of the type T'Class. > There is nothing automatically more complex in T'Class than in T. If you assume that all operation implementations "conform to the interface" (including semantics) then redispatching is no more complex than dispatching; the effect of the (re)dispatching call is assumed to be the desired one, whatever the actual type of the controlling operand(s). >>> Your initial example was about certain decomposition of operations into >>> class-wide and primitive, so that a primitive operation would call to >>> class-wide ones. >> No, I think you mistunderstood my example, perhaps because I did not >> explain it clearly enough. The two operations in my example are both >> primitive, and can be independently overridden with behaviour suitable >> to derived types. The operations call each other with redispatching to >> activate the most suitable behaviour of each operation for the actual >> type of object. > > Yes, I understand this. The question is why it was decomposed in this way. > If one operation of the type T calls another operation of the same type. > Why should it dispatch. It does *not* call another operation of the same type; it calls another operation of the same *class*. That is what redispatching means, and why the call contains a conversion T->T'Class. > When you call an operation of the type S on T, that > is a type error to me. You have circumvented the type system, by an > explicit type conversion of T to T'Class. Do not we agree that type > conversions should be avoided? I agree that type conversions "should" be avoided, but good grief, sometimes you need them to express something, as in this case, because Ada specifically uses the conversion T->T'Class to invoke dynamic (re)dispatching. And of course this conversion is safe and does not in any way "circumvent" the type system. >>> My point that such cases should be attributed to poor >>> design >> In the mind of the beholder, I think. You haven't shown *why* this >> design is "poor", except by your own design rules. > > I think I did. I disagree (maybe we should have an abbreviation for this, as it seems to occur frequently :-) > Why do you dispatch again, you already checked the tag. Because this gives me the functionality I want, of course. > The type is determined, Of course not, only the point (within the class) of the implementation of the currently executing, (possibly) inherited operation (the caller) is determined. The actual type, as you well know, is any type in T'Class, although it is written "T" in the operation profile. > the reader expects the code to correspond that type, > you break this convention. That depends on the "reader". My convention is different from yours, and I think my convention corresponds more closely to the (full) Ada language, while yours assumes a subset of Ada that follows your design rules. > My concern is the semantics of the code. > Semantically a primitive operation has separate bodies for each type in the > class. Yes, but they are represented by a smaller (sparse) number of bodies in the program text, with the "missing" bodies supplied by inheritance. And that is why the actual type of the actual parameter object is some type in T'Class, not always T (as you well know...) > This gets broken in your design. I.e. it is a third way of how > bodies are decomposed. I may agree that the language could offer more than > one body per class (class-wide) vs. one body per type (primitive). But so > far, a design should conform to the existing model. I fail to understand that. You seem to be claiming that the Ada "model" does not really include redispatching, which is nonsense to me. > Yes, but only if I cannot statically specify the type. Re-dispatch happens > at the places where I already determined the type, The type is *not* already determined; see above. > but for some reasons am > not satisfied with the outcome. Why? Strange... Come on, you know very well that the outcome using redispatching is quite different from the outcome without redispatching. So of course my reason is that I want the former outcome :-) The same outcome could, of course, be gained in another design that does not use redispatching, but at the cost of a different architecture, which (in my view) had significant disadvantages such as code duplication. I suggest that you show how you would design the Divide-and-Conquer example that I described in my reply to Randy earlier today, and then we can compare the two designs. >>> that re-dispatch requires referential semantics, >> I don't see why, > > Because of the type tag. You need same representation for T and T'Class to > have T -> T'Class as a view conversion. That does not imply reference *semantics*, only pass by reference. Not the same thing, as demonstrated by pure functional languages. >> but I don't really care, as I have accepted (albeit >> reluctantly) that I need referential semantics anyway. > > But it means that the design relies on referential semantics and cannot be > rewritten in terms of value semantics. Redispatch does *not* make the design rely on referential semantics. I admit that my design(s) do rely on referential semantics in places, but this is not because of redispatch. > Formally there should be something > fundamentally wrong with that, because there is no reason beyond 1. > optimization issues, 2. outer world communication, why referential > semantics is chosen. Yet we rely on it. Why? In my case, mainly for reason 1. optimization issues. Also because it can sometimes reduce architectural coupling between operations and packages. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .