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: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Getting the index for an element in mutually referencing containers Date: Wed, 15 Mar 2017 09:44:09 +0100 Organization: Aioe.org NNTP Server Message-ID: References: <86o9xa36oq.fsf@gaheris.avalon.lan> <86k27xpikd.fsf@gaheris.avalon.lan> <86wpbxneuz.fsf@gaheris.avalon.lan> NNTP-Posting-Host: vZYCW951TbFitc4GdEwQJg.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 X-Mozilla-News-Host: news://news.aioe.org X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:33514 Date: 2017-03-15T09:44:09+01:00 List-Id: On 2017-03-14 21:40, Randy Brukardt wrote: > "Dmitry A. Kazakov" wrote in message > news:oa70rj$12td$1@gioia.aioe.org... >> On 2017-03-13 20:55, Randy Brukardt wrote: >>> "Dmitry A. Kazakov" wrote in message >>> news:oa41a4$1ko5$1@gioia.aioe.org... >>>> On 2017-03-12 17:44, Simon Wright wrote: >>> ... >>>> P.S. It is a pity that Implicit_Dereference type does not have proper >>>> interface to work with *any* type instead of discriminated records. This >>>> is design fault when the use case #2 was taken for #1. >>> >>> It works with any type, since the real target type is the thing >>> designated >>> by the discriminant. The discriminant is the key, because it is the only >>> way >>> in Ada to get an access type with a controlled lifetime. The >>> discriminated >>> type is just a helper, not the end result. >> >> That would be the case #1 with *no* helper type whatsoever: >> >> type Element ... >> type Index ... >> type Container ... >> function Get (X : Container; I : Index) return Element; >> for Container'Get_Element use Get; >> >> function Get (X : Container; I : Index) return access Element; >> for Container'Access_Element use Get; >> >> etc > > The second case here doesn't limit the lifetime of the return access type, > and provides no notification when the caller is finally finished with the > accesss value (which is critical). Don't see how that solves anything for > "case 1". It is no problem because the operations are not to be called explicitly. They must be private. I was never a fun of aspects or representation clauses, the proper notation should be this: function "()" (X : Container; I : Index) return Element; procedure "()" (X : in out Container; I : Index; V : Element); This is for user copy-out / copy-in semantics. And this function "()" (X : Container; I : Index) return not null access Element; procedure "()" (X : in out Container; I : Index; V : not null access Element); For by-reference semantics. The second operation is called to commit element transaction. E.g. X (I).Member := Foo; Will be equivalent to declare Reference : not null access Element := <()> (X, I); begin Reference.Member := Foo; <()> (X, I, Reference); exception when others => <()> (X, I, Reference); raise; end; In particular, the first "()" could take a lock and the second would release it. >>> Yes, we could have done that some other way, >> >> There is no other way, there is another use case #2, when a reference >> object is required to live longer. > > We were not trying to solve that problem, Yes, that is my problem with the design. The use case is #1, the solution is #2. > it's relatively easy to solve with > the existing features (as your reference counted library shows). Ada is > about building blocks, not necessarily polished solutions. It is far from being easy. In practice it leads to a geometric explosion of generic instances when a types hierarchy is involved. Believe me, it extreme even catastrophic. The problem is that the smart pointer type must be anonymous (ad-hoc) like access T is. Otherwise, you get the problem of parallel type hierarchies of the targets and the pointers. And the pointer type must have the interface of the target AKA implicit dereference. > ...>> and indeed we started with a >>> separate construct, but the semantics ended up identical to that of an >>> access discriminant of a controlled type -- so why build another >>> construct >>> (with all of the additional chances of getting it wrong) when an existing >>> one will do? >> >> Because it gets everything wrong in the major use case #2. > > Which it was not intended to solve. The whole "strong/weak reference" > business is not fundemental to solving problems -- if anything, it gets in > the way. Theoretically it is not fundamental, in practice it is. Same as in-out parameters. They are not fundamental, any program can theoretically be immutable, if you could clone everything including the Universe producing program inputs. > We were only trying to solve the problem of having a reference that > is still safe (in the sense that the underlying data can be protected from > destruction while the reference exists). That requires two things: having a > reference that can't be copied, and having a call-back possibility when the > reference goes away. The Ada 2012 reference mechanism provides both. Except that it is not a reference (compiler-managed view of an object), it is an object of a different type that plays a role of a reference. And this falls right into the use case you didn't want to solve in the first place. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de