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-Thread: 103376,7d83a6223f4f2443 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!feeder.news-service.com!feeder4.cambrium.nl!feed.tweaknews.nl!news.netcologne.de!newsfeed-hp2.netcologne.de!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Run-time accessibility checks Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: Date: Fri, 12 Dec 2008 10:21:55 +0100 Message-ID: NNTP-Posting-Date: 12 Dec 2008 10:21:56 CET NNTP-Posting-Host: a6696e9a.newsspool2.arcor-online.net X-Trace: DXC=_mW8V7NMa^5Tia]Ho99G50A9EHlD;3Yc24Fo<]lROoR1^YC2XCjHcb9O^aBVWN2hE6DNcfSJ;bb[5FCTGGVUmh?4LK[5LiR>kg2f^jSd73Q[j3 X-Complaints-To: usenet-abuse@arcor.de Xref: g2news1.google.com comp.lang.ada:2969 Date: 2008-12-12T10:21:56+01:00 List-Id: On Thu, 11 Dec 2008 16:15:39 -0600, Randy Brukardt wrote: >> "Dmitry A. Kazakov" wrote > >> My solution is inheritance, disliked so much. If you want >> a referential type to be a substitute for the target type, then the >> referential type simply must inherit to the target. (We don't need "all", though it >> can be preserved using some intermediate referential type.) > > Well, this doesn't make any sense to me at all. And the following example > doesn't help; you've made it the *same* type, which is definitely not what > you want. No I made it having same interface, the implementation is different. You have a wrong model in mind. Same interface does not imply same representation / implementation. > The result of dereferencing an access value is a *different* type, > with *different* operations. I don't *want* interchangability!! Then you have what you have - an inability to assign an element in the container, *because* it is of a different type. In my solution the container element does not magically change its type, just because you don't want to copy it. Why should it? The container knows how to access its elements. >> Because Ref_Type is not abstract, you will have to override all primitive >> operations of Target_Type, and assignment must be a primitive operation, >> and components getter/setters of, in case Target_Type were a record type, >> must be as well. > > That sounds like a maintenance headache (any change must be replicated > everywhere. That became such a pain for the Claw Builder program that it > almost ground development on it to a halt.) That is another issue. Ada has no good support for delegation. You should be able to delegate Target.Operation to Ref_Type.all.Operation without writing boring wrappers. It is not specific to this case. >>> You certainly can't have a procedure ":=" to do assignment in because of >>> discrimant-dependent components. > >> ":=" is a statement. What I would do is to define *two* primitive >> subprograms the compiler will use in order to compose *one* ":=". The >> first operation will determine the discriminants, the second will continue >> with those known. > > That's not the problem; the problem is that components appear and disappear, > and there is no way to assign them. I don't see any problem. All discriminants are known in the *second* primitive operation. That allows you to write a case statement and assign existing components. > And there is no way in Ada to just set > the discriminants without giving values to the components as well; that is a > fundamental invariant of the language which I don't think can be changed > without making everything erroneous. You don't need it. The *first* primitive operation does not deal with the values. The idea is very simple. For each type T there is a predefined type T'Constraint defined as a tuple of discriminants (array bounds, type tags) of T. For example, when type T (X : Integer) is record case X is ... end case; end record; then type T'Constraint (X : Integer) is null record; Now the *first* primitive operation determines T'Constraint. The *second* primitive operation is called either on an object with the constraints set from the result of the *first* operation or else with a value of T'Constraint. That is it: procedure Set (T : in out Object); or function Set (Constraint : T'Constraint) return T; >> Records are not iterated. If we want a container to support iterations, >> that must be an abstract array. It also was getter and setters: >> function "()" (A : Abstract_Array_Type; I : Index_Type) return >> Element_Type is abstract; procedure "()" (A : in out Abstract_Array_Type; >> I : Index_Type; E : Element_Type) is abstract; > > That's not flexible enough for iteration; the index can be anything (it need > not have an inherent ordering; it surely cannot be restricted to a discrete > type) and thus just having this interface does not allow iteration. I proposed to introduce unordered arrays long time ago. > There also is very little chance of such an interface being supported in > Ada, if I read the feelings of the group well enough. One concern I've heard > is that there is no practical way to support this for slicing (again, > because the index does not necessarily have ordering). Personally, I'd give > up slicing for this sort of abstraction, but I don't think that will fly. I think it is solvable. First we have to introduce abstract index types. Ada lacks this abstraction completely. If we had index types we could make ranges first-class citizens. That would allow to solve slicing. > Another concern is that almost all of the existing predefined packages would > have to be scrapped and replaced to make any use of this (especially the > string packages). But people aren't willing to do that ("insufficiently > broken"), even if there is plenty of evidence that we could do a lot better > for those packages. Why scrapped? Simply moved to the Annex J (:-)) >>> And it also isn't very flexible -- where does the Cursor of a container >>> go?? > >> To me to the recycle bin. *BUT* there is no any problem with cursors, >> absolutely. A cursors is a pair. The first component is a type derived >> from the container's interface (a reference to the container), the second >> component is the container's index. Done! > > The cursor is the index in the model you have here. And it already is a pair > (container, access to something). To me index is an instance of an abstract ordered or unordered index type. Its values are unrelated to any specific container. Cursor is an index + a specific container. > Not sure what you dislike about them; > they've have the same semantics if not the same name. (I was talking about a > record selector interface, which makes more sense for getting individual > elements.) Referential semantics is what I dislike in cursors. Cursor is a dressed pointer. It is very difficult to use it in concurrent/volatile environment. It is inherently unsafe, what happens with it upon container update? Where is that described? How to prevent update when a cursor is still there. And so on, and so forth. Cursor is a bad, crippled thing. > What *cannot* be the case is that the index is required to be > some sort of discrete type. Right, that must be an abstract interface, which any type could implement. > That would require a map to translate said index > into some sort of access to the actual element. But that would be silly, > especially for map containers (you'd have to go through two maps to find > anything, and for what??) You have pointer model in mind. But there is no pointers in my world. There is a setter operation. The setter takes an index argument, it is not my business to look into the implementation of. > But the real problem in all of these things you've suggested is that they > are all technically by-copy for reading. If that is all you want, the > existing Ada containers do that just fine. The problem is that if the > elements are large, copying them may be very expensive, so a by-reference > access method is reading. That's the core of the problem I'm trying to > address (because I think there is a chance that people will view it as > significant enough to deal with). Functions returning values of a type *do > not* provide any solution to that (and cannot). This makes no sense to me. Reading is not an operation. If a primitive operation of Element_Type has to be called on an element of Container_Type specified by Index_Type, that is not "reading." If you mean "functional" appearance of "getter," them firstly, it is not obvious why the getter is to be used to achieve the goal, and secondly return by reference is marked as "solved" in Ada 2005. Those Pickwickian functions were praised for that, or? (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de