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: Smart pointers and delegation Date: Sat, 5 Aug 2017 10:33:15 +0200 Organization: Aioe.org NNTP Server Message-ID: References: NNTP-Posting-Host: MajGvm9MbNtGBKE7r8NgYA.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 Content-Language: en-US X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:47605 Date: 2017-08-05T10:33:15+02:00 List-Id: On 2017-08-05 01:03, Randy Brukardt wrote: > "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). What is dereference object? There is a target object X and reference object R, both already exist. Let I want to pass R to an operation F of X. This should lock/unlock on the way. I cannot do that without some third type. >> [...] >>> 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. Implicit dereferencing semantically does the same. For each visible operation of the target type it declares an anonymous operation of the reference type that dereferences and then calls to the original operation. Delegation has these operations named. [and primitive. In this sense it is more restricted] > 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. It could be an access discriminant too. But I used an access component to illustrate that it need not to be a discriminant. The use-case is reference counting smart pointers. I guess you rather meant a temporary reference into some container when the reference is short-lived and the container element is long-lived. Smart pointers use the opposite approach. Pointers (the last one) outlive the targets. If a container is built then out of smart pointers, e.g. it keeps pointers to the elements. Alternatively, it can keep raw elements and hold a reference to each. You access elements strictly through pointers which need not to be disposed immediately. They can live as long as necessary. It can be used in transactional schemes, e.g. cloning elements for mutators if the reference count > 1 etc. > 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. (I must know what dereference is) There are cases which do not involve access types. E.g. multiple-inheritance for poor: type File_Interface is limited interface; type File_Type is new File_Interface with ...; type Widget is ...; type File_Selector_Widget is new Widget and File_Interface with record Selected_File : File_Type; end record with Delegate => Selected_File; -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de