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=unavailable autolearn_force=no version=3.4.4 Path: border1.nntp.ams3.giganews.com!border1.nntp.ams2.giganews.com!border3.nntp.ams.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!newsfeed.fsmpi.rwth-aachen.de!nuzba.szn.dk!news.jacob-sparre.dk!munin.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Is this expected behavior or not Date: Tue, 26 Mar 2013 16:31:35 -0500 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: References: <87ec4b1d-f7cd-49a4-8cff-d44aeb76a1ad@googlegroups.com> <78103a2f-5d19-4378-b211-1917175d5694@googlegroups.com> <3p6p8k0yfly7.ctazdw7fc5so$.dlg@40tude.net> <1jtvzi1v65aqm.1k5ejsveno59f.dlg@40tude.net> <1hvv2kd9smnfx.6spgz9thd1mh$.dlg@40tude.net> <1raubw1sk48ca$.69rdgczvnnf.dlg@40tude.net> <2qwq2cdeuvhu$.qtnb8zyhuob9$.dlg@40tude.net> <1u72u7h5j4jg3$.wlxmaltyzqik.dlg@40tude.net> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: munin.nbi.dk 1364333499 23137 69.95.181.76 (26 Mar 2013 21:31:39 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Tue, 26 Mar 2013 21:31:39 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 X-Original-Bytes: 10814 Xref: number.nntp.dca.giganews.com comp.lang.ada:180785 Date: 2013-03-26T16:31:35-05:00 List-Id: "Dmitry A. Kazakov" wrote in message news:1u72u7h5j4jg3$.wlxmaltyzqik.dlg@40tude.net... > On Mon, 25 Mar 2013 17:58:26 -0500, Randy Brukardt wrote: > >> "Dmitry A. Kazakov" wrote in message >> news:a96esjwiniqy$.op3wh7x9wrsl.dlg@40tude.net... >>> On Fri, 22 Mar 2013 21:33:02 -0500, Randy Brukardt wrote: >> ... >>>> That doesn't necessarily mean copying of the data. If the designer >>>> of the abstraction, have put in enough smarts to share >>>> representations -- >>>> after all, >>> >>> You should break your mental block. No shared representation, I want >>> different representations for different string types. >> >> I was talking about sharing representations of *different* objects of the >> same string type (for instance, a string variable and a slice of that >> variable - that case, sharing the data might be preferred to copying it). > > OK, the representation would be for type-specific string objects: > > bounds + pointer > > and for class-wide string objects: > > tag + bounds + pointer Sure, but irrelevant. The question is whether slicing copies the data or not. If it is a new object, the data must be copied logically, but my point was that it would be possible for an abstraction to defer actually making a copy until an assignment is actually done. It's still a copy. ... >> Unifying old junk it's possible without serious breakage of existing >> code, >> which is intolerable. > > Why is it junk? There is nothing wrong with String, Wide_String, > Wide_Wide_String. They should stay. They're junk because they can't be unified without serious breakage of existing code. Since we're not willing to break those eggs, we have to start over. > Unbounded_String is indeed junk, but after adding an array interface to it > = putting it into the same hierarchy it would perfectly serve the purpose. That's the idea, but of course that requires starting over with it. >>> The way is to allow untagged T to have T'Class. This will preserve all >>> semantics and all existing representations. Not even an explicit root >>> type >>> is needed, e.g. for char_array. The technique makes it possible to have >>> ad-hoc supertypes, which would serve the purpose, e.g. you would define >>> Put_Line on such a supertype and it will work for both String and >>> char_array. Not a line changed in Standard or Interfaces.C. >> >> Sounds great, but it won't work in practice. You'd introduce a lot of >> ambiguities and break existing code that way. > > Why? The effect is limited strictly to T'Class objects, which presently do > not exist. Not true, as I explained later in my note. The possibility of dispatching changes a lot of rules about inheritance and assignment. >> (That's why >> Ada.Strings.Unbounded_String doesn't have string literals; we couldn't >> find >> any way to add them without making most existing code using the package >> ambiguous.) > > This is a different problem. I think the model is that string and other > literals would become primitive operations. Upon inheritance in the class > sense, they should be overridden or else dropped. There should be some > syntax invented for handling literals, e.g, some factory operation etc. An > alternative is having literals class-wide, which roughly corresponds to > existing Universal_String approach. In both cases you might wish to add > some preference rules [we already have some] to keep it compatible and > slash ambiguities. It would be worth to consider a possibility for the > user > to control such preference rules and to have user-defined literals in > general. But that's not the problem; that was what we wanted to do. The problem is that Unbounded string has two versions of most operations, one that takes String and one that takes Unbounded_String. If you gave literals to Unbounded_String, all of the operations which took both would be ambiguous for literals unless you qualified them. Which defeats the purpose. We could solve the problem by getting rid of all of the routines that take String parameters, but that of course woulc break any code that passed slices or objects of type String. So the only fix here is to start over with a new package, keeping the old one around for existing code. >> Secondly, the inheritance and overriding of untagged types is much looser >> than the that of tagged types; you don't even have to use the same >> parameter >> modes. > > Yes, but untagged types in the model I have in mind will remain > independent > types, they would not suddenly become Ada-subtypes, if you mean that. So > > subtype S is String ...; > type Q is new String ...; > > would have different semantics, just like they do for tagged types > already. > >> And dispatching is incompatible with untagged types, simply because Ada >> 83 >> got inheritance horribly wrong, and we're stuck with that. > > I disagree. It seems fully compatible with Ada 83 because T'Class would be > a distinct type with objects of that type. It is orthogonal to > Ada-subtypes. You will not dispatch on Positive vs. Integer, these will > reman specific [sub]types. In order to dispatch you will need a class-wide > object of the type Integer'Class (which will be strictly same as > Positive'Class, except, possibly, the constraint). That object will have > the representation tag + value. For Integer and Positive objects nothing > changes. We might consider redefining some existing operations to become > class-wide in some arguments, but that is another story. You missed the point altogether. You can't dispatch in general on untagged types because overriding operations may have different modes and subtypes for the parameters. So what *is* the profile of the operation for T'Class, and how can it work? Consider: Type Int is range 1 .. 10; procedure Op (A, B : in Int); Type Der is new Int; overriding procedure Op (A : in out Der; B : in Der); Obj : Int'Class := Der'(1); Op (A => 1, B => Obj); -- Legal?? Here, we're dispatching to a routine with an "in out" parameter, passing a literal (because the profile of Op for Int'Class has an "in" parameter). Is this legal? If so, what does it mean? If not, how does that work if Der is added to the program later during maintenance. And if you say that Der cannot override Op this way, you're now incompatible with Ada 83- Ada 2012. >>>>> You have a very specific use case in mind, namely containers. There is >>>>> a >>>>> whole world outside that, for which what you said is untrue, e.g. for >>>>> smart pointers. The thing not only exposes access, it also exposes the >>>>> target type. >>>> >>>> You have to expose the target type in order to have strong typing. How >>>> could you hide it and still make type checks? >>> >>> Why should target type be public? >> >> How do you enforce strong typing without that being the case? If you >> don't >> know what the target is, how do you determine how the resulting object >> can >> be used? > > Target and handle types usually implement some public interface. E.g. > > type File_Access is limited interface; > procedure Write (File : in out File_Access; Data : ...) is abstract; > ... > > Somewhere else > > type File_Descriptor is ... limited ... and File_Access ...; > > Somewhere else > > type File_Handle is ... and File_Access ...; An interface can't have "..." as the parameter type for Write; there has to be something there. And that's the target type! Say again how it is that you are not exposing this type?? ... >>>> That's my point about static analysis. Such a tool should be able to >>>> prove >>>> that the majority of run-time checks can't happen, and give you a list >>>> of >>>> those remaining. >>> >>> I don't need any list. Should I send it to my customers? I need the >>> program fail to compile when writing analogue input. >> >> Treat the list as failures if you must, and insist that it be empty >> before >> shipping. > > So, I need an AI system to parse compiler messages (of various vendors) on > top? Huh? Why would you "parse" them? It's a binary choice (just as it is with ACATS testing): either require them to be removed or ignored. You only have to decide which classes of warnings you require to be removed from your code. For that, you have to understand your tools, sure, but if you don't understand your tools you are never going to get anywhere. A programming language definition is only a small part of getting programming right; it could never be more than 10% or so; the tools used provide another 20-30%. The rest is on the programmer's skills (to do good things like decrease coupling). Randy.