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-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,72c34c66b38e0e05 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-12-27 09:43:10 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!syros.belnet.be!news.belnet.be!feed.news.nacamar.de!fu-berlin.de!uni-berlin.de!dialin-145-254-037-009.arcor-ip.NET!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Proposal: Constructors, Assignment [LONG] Date: Fri, 27 Dec 2002 18:43:28 +0100 Organization: At home Message-ID: References: Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: dialin-145-254-037-009.arcor-ip.net (145.254.37.9) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7Bit X-Trace: fu-berlin.de 1041010989 7650280 145.254.37.9 (16 [77047]) User-Agent: KNode/0.7.1 Xref: archiver1.google.com comp.lang.ada:32335 Date: 2002-12-27T18:43:28+01:00 List-Id: Nick Roberts wrote: > Forgive me for not quoting Dmitry's post. > > I take the view that the 'object constructor problem' that Ada is > sometimes accused of suffering from is nearly always solved (in a better > way than languages which have special constructor functions) by the old > chestnut of: declaring the type as private (and indefinite) in its own > package specification; providing whichever constructor functions as > primitive operations of this type are appropriate. > > The implementation of the type must use an unsophisticated discriminant > scheme, but this is hidden, and the constructor functions translate from > the appropriate parameters of construction to the implementational ones. > The fact that the result of a function is permitted to be of an indefinite > type allows the user of the package to declare an object of the type > without a constraint, and initialise it using the appropriate function > (the result of which provides the constraint). > > I'm pretty sure Dmitry is well aware of this technique. However, I think > many members of the ARG would feel that the proposer of a functional > construction scheme (for the next language revision) needs to demonstrate > some pretty significant advantage the proposal has over the above general > approach. > > Example 1 that Dmitry gave might be rehashed thus: > > > package Session_Management is > > type Internet_Session(<>) is private; > > function Open (Host: in String) return Internet_Session; > > ... > > private > > type Internet_Session ( > Host_Name_Length: Natural > Traceback_Length: Natural) is > new Ada.Finalization.Controlled with > record > Host_Name: String(1..Host_Name_Length); > Traceback: ?.Node_Array(1..Traceback_Length); > Connection: ?.IP_Connection > ... > end record; > > end; > > package body Session_Management is > > function Open (Host: in String) return Internet_Session; > begin > Open_Connection(Session.Connection,Host); > declare > Result: Internet_Session := ( > Host'Length, > Get_Node_Count(Session.Connection), > ... ); > begin > ... > return Result; > end; > exception > ... > end Open; > > ... > > end Session_Management; > > > I've indulged myself in adding a detail -- the storage of a node > traceback -- to illustrate the idea that not just the parameters of a > constructor function can directly affect the structure of the type, but > also any arbitrary circumstances of its construction (at the time it is > constructed). I've also indulged myself in changing the names of things a > bit. These are only a minor touches. > > Possibly the most relevant point is that the type (Internet_Session) is > not limited, and cannot be (because an initialisation is required and > limited types cannot be initialised). > > If a limited type is required (and it probably is, realistically, for this > example), the typical technique is to make the type's implementation an > access value (referencing a totally private 'payload' type which actually > contains the relevant data, and which can be indefinite). The public > specification of the type can then be definite, so that the user can > declare an object of the type without having to initialise it, and then > maybe call a procedure to get it into a proper (initial) state (which may > well involve allocating an object of the payload type). Of course, this is > usually precisely the situation for the Ada.*_IO.File_Type types. > > It could be argued that the indirection of access this causes is > inefficient, but not (or very rarely) realistically, in my opinion. The first objection is that this schema requires maintenance of two unrelated (to the compiler) hierarchies of types: the implementation types and the handles to them. (*) So, let we want to derive from Internet_Session, say, My_Proprietary_Protocol_Session? -- The idea that a constructor is just a function is IMO badly wrong. Limited types is just one example why. Another example is class-wide types. How to construct a class-wide object from scratch? To write a class-wide function? But then it will never ever dispatch. A dispatching one? But the type is unknown and there is no object. This is why Ada's stream attributes are made hard-wired. This is also why assignment is a problem. And of course, an unnecessary language complexity. This and that work-arounds for initialization, construction, assignment etc, very often lead a programmer to unexpected and undesired side effects to the design. ------------------ (*) Ada offers no tools to ease this task, when the handle type is not an anonymous access type. [which BTW is not allowed to be OUT, INOUT or result] It is definitely necessary to have something to solve this, but no language I know addresses this. And it is not very clear how to do it anyway. -- Merry Christmas, Dmitry A. Kazakov www.dmitry-kazakov.de