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!nntp-feed.chiark.greenend.org.uk!ewrotcd!newsfeed.xs3.de!io.xs3.de!news.jacob-sparre.dk!franka.jacob-sparre.dk!pnx.dk!.POSTED.rrsoftware.com!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Smart pointers and delegation Date: Fri, 4 Aug 2017 18:03:17 -0500 Organization: JSA Research & Innovation Message-ID: References: Injection-Date: Fri, 4 Aug 2017 23:03:18 -0000 (UTC) Injection-Info: franka.jacob-sparre.dk; posting-host="rrsoftware.com:24.196.82.226"; logging-data="13528"; mail-complaints-to="news@jacob-sparre.dk" X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Response X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.7246 Xref: news.eternal-september.org comp.lang.ada:47590 Date: 2017-08-04T18:03:17-05:00 List-Id: "Dmitry A. Kazakov" wrote in message news:oluk0l$a8o$1@gioia.aioe.org... > On 2017-08-03 05:36, Randy Brukardt wrote: ... >>> ? Not even close. Adjust and Finalize are primitive operations, which >>> was >>> a horrific design choice, but nevertheless. Implicit dereference is not >>> an >>> operation, not even a body. >> >> In the intended use, Implicit_Dereference is always combined with a >> controlled type, which provides the actual hooks. > > ? These are not hooks on the operation of dereferencing. > > [E.g. you cannot make a task-safe dereferencing by taking a lock at the > beginning and releasing it at the end, i.e. a typical Ref/Unref pair] Why not? That's precisely the sort of use that is intended. One seizes the lock when the dereference object is created (the start of the dereference) and the frees it when the dereference object is destroyed (finalized). > [...] >> That's the problem: the Implicit_Dereference mechanism is intended for >> the >> rare cases where "normal primitive operations" don't work (because they >> imply copies for function results). If "normal primitive operations" >> work, >> you don't need (and shouldn't use) any special mechanism. > > I must and I need it, because in real-life examples (e.g. #1) it is many > thousands lines of noise code in both package declarations and bodies. > Which is quite error-prone too. Sorry, I meant the mechanism as intended is only needed in limited cases. You have a very different use-case that has nothing whatsoever to do with the need for the Implicit_Dereference mechanism. I didn't intend to say anything about the value of that use-case. Indeed, the proposal you made (as best as I understand it) only used "normal primitive operations"; the idea was to automatically construct them in some cases. Nothing wrong that I can see with that idea, but it doesn't have anything to do with Implicit_Dereference as intended. (You'd still need a mechanism like that for uses where copies can't be used, assuming you care about safety.) >> From your description, you're trying to solve an altogether different >> problem. That's fine, of course, but just don't confuse that with the >> rather >> low-level problem that Implicit_Dereference was actually trying to solve. > > Yes it is a wider problem, but one use-case is exactly same. The solution > is different: > > 1. Dereference: > > type Target_Interface is interface; > type Reference (Pointer : access Target_Interface) is null record > with Implicit_Dereference => Pointer; > > 2. Delegation: > > type Target_Interface is interface; > type Reference is new Target_Interface record > Pointer : access Target_Interface'Class > end record > with Delegate => Pointer; > > Delegation has no magic whatsoever. It could be done by an ASIS-aware > preprocessor actually. The problem is that the delegation is unsafe -- it has very different semantics. The use of an access discriminant in Implicit_Dereference is what gives the limited lifetime to the access type, and that makes it possible to use finalization to get control at the end of the life of the dereference. You can't do that with an ordinary component, which has no limits on the lifetime of the dereference. And there is nowhere obvious to hang the "end dereference" hook. That could be fixed with additional new features, I suppose, but the rules for access discriminants are such a mess that trying to repeat them in some way is not an appealing project (one of the reasons that Implicit_Dereference ended up like it did.) Ergo, (2) is not in any way a replacement for (1). Unless (1) is being used without the controlled object and finalization "hook" -- but there is no reason whatsoever to do that (you can just use a regular access value in that case). Randy. Randy.