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=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,7fcf9180e7ba7ab1 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: A suggestion for resource management Date: Tue, 07 Sep 2010 13:14:34 +0300 Organization: Tidorum Ltd Message-ID: <8emhkaFskqU1@mid.individual.net> References: <8762z4gcoi.fsf@mid.deneb.enyo.de> <8darikF1b0U1@mid.individual.net> <87eidr3cje.fsf@mid.deneb.enyo.de> <8dcdu1F4v9U1@mid.individual.net> <878w3yhbi2.fsf@mid.deneb.enyo.de> <8df7ksFu5fU1@mid.individual.net> <87k4n14977.fsf@mid.deneb.enyo.de> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net dSkocokTB0frNG/nDZp/ywPjUauyG/Tt4G7Q3PS90l4Pu6HWkl Cancel-Lock: sha1:dtpMButFPmF1BWmakgkH6YnACws= User-Agent: Mozilla-Thunderbird 2.0.0.24 (X11/20100328) In-Reply-To: <87k4n14977.fsf@mid.deneb.enyo.de> Xref: g2news1.google.com comp.lang.ada:13963 Date: 2010-09-07T13:14:34+03:00 List-Id: Florian Weimer wrote: > In retrospect, the construct suggested by Stefan (with the additional > tweak I mentioned) should work well enough, it just introduces a > pointless identifier. For reference, since those posts appeared some time ago, here is a part of your pragma proposal: > On Sat, 21 Aug 2010, Florian Weimer wrote: > >> The example at the end of section B.4 could use the Scoped pragma in >> this way: >> >> procedure Test_External_Formats is >> ... >> COBOL_File : File_Type; >> ... >> >> begin >> Open (COBOL_File, Name => "Some_File"); >> pragma Scoped (Close (COBOL_File)); >> >> loop >> ... >> exception >> when End_Error => ... >> end Test_External_Formats; >> And here is Stefan's construct: stefan-lucks@see-the.signature wrote: > I don't quite why this needs an extra pragma -- your example is, > apparently, easy to handle by current Ada's capacities: > > procedure New_Test_External_Formats is > ... > COBOL_File : File_Type; > > procedure Close_Cobol_File is > begin > Close(COBOL_FILE); > end Close_Cobol_File; > > Finisher: Finish_Package.Finisher; > -- The type Finish_Package.Finisher is derived from > -- Ada.Finalization.Limited_Controlled. > ... > > begin > Open (COBOL_File, Name => "Some_File"); > -- pragma Scoped (Close (COBOL_File)); > -- we don't need the pragma > Finisher.Set(Close_Cobol_File'Access); > -- we will call Close_Cobol_File > -- when Finisher goes out of scope > loop > ... > exception > when End_Error => ... > end Test_External_Formats; > > The only disadvantage of this approach, in comparison > to your pragma, is the need to define a parameterless > procedure Close_Cobol_File. But defining such parameterless > procedures is a design pattern you get used to anyway, > when working with Ada.Containers. And finally your tweak on Stefan's proposal: Florian Weimer wrote: > Or even this: > > COBOL_File : File_Type; > package Finisher_COBOL_File is > new Finisher (File_Type, COBOL_File, Close); > Curiously, it [Stefan's construct] shares many of the > things you [Niklas] criticize about pragma Scoped. I would like to discuss this. I criticized your "pragma Scoped" suggestion on these points: - Using a pragma to define flow of control. Stefan's construct does not use a pragma, so it escapes this criticism. - Violation of the principle that flow of control should match textual order (the procedure_call_statement in pragma Scoped would be executed later, at end of scope). This criticism can be applied to any use of implicitly invoked finalization, so it does apply to Stefan's construct, but it applies even more to my suggested alternative to pragma Scoped, which was new syntax of the form "at end do ". However, since Ada now supports automatic, implicit finalization (a good thing), this principle cannot always be followed, and (as I admitted earlier) there are other arguments against the principle, too. I don't think we need to discuss it further. - The difficulty of defining and using your suggestions for the early evaluation and saving of the parameter values of the procedure_call_statement in "pragma Scoped". This does not apply to Stefan's construct since it does not save any parameters (because it is limited to a parameterless clean-up procedure). It might apply to your tweak in which the clean-up procedure has one parameter (COBOL_File in the example) that (depending on its generic formal mode) is perhaps evaluated and saved in the instantiation of the generic package Finisher. Do you propose mode "in" or mode "in out" for this parameter of package Finisher? - The fact that "pragma Scoped" was limited to scheduling a single procedure_call_statement at end of scope, rather than any kind of statement or statement sequence. Stefan's construct, and your tweak, have this limitation too, and even limit the kind of parameters that the call can have. In summary, as I see it, all these suggestions try to create a kind of "ad hoc" finalization code that could also have been done by wrapping the resource (COBOL_File) in a controlled type. The question is, do we need such an "ad hoc" finalization feature? Stefan showed that it can be done in the existing language by using a kind of general finalizable object or package that can play host to an arbitrary clean-up procedure. To me, this seems to introduce almost as much clutter as the nested block and exception-handling syntax that you considered cumbersome. Stefan says that such parameterless "helper" procedures are common when using Ada.Containers, but I believe that there are current proposals for new Ada syntax to avoid such procedures and instead write their statements "in line", for example in loops that iterate over containers, or statements that find and update a specific element in a container. >> - Florian's proposal is unique in suggesting a "pragma" syntax. All >> the other languages use syntax that is made part of the core language >> and is not just a "compiler directive". > > The idea was to implement it in an existing compiler if the semantics > are well-received. If you were to implement this pragma in an existing compiler as an extension -- which is of course your right -- and if the pragma were then extensively used, it would tend to constrain later standardization and force the standard to use or at least support such a pragma, to which my reaction is still negative. Is it really much simpler to implement "pragma Scoped" than to implement "at end do "? After all, both are syntactic sugar for Stefan's construct. >>> For evidence that try-finally doesn't work, it's instructive >>> to run a suitable static analyzer on a code base for the >>> first time. Even if the developers are competent, you'll >>> find rule violations, several of them caused by a desire to >>> reduce syntactic overhead. >> Concrete examples would be interesting. > > In Java, I often see programmers using FileInputStream or Socket > without try-finally blocks, relying on the garbage collector to close > file descriptors. And of course garbage collection can be indefinitely delayed. Good example, thanks. I don't know Java well (on my list...) but IIUC Java does not provide end-of-scope finalization, as Ada does for controlled objects, so Stefan's construct is not available and try-finally is the only option left in Java. Perhaps it would be easier to use controlled objects than try-finally. I do understand the advantages of writing resource-deallocation (clean-up) code close to the resource-allocation code, an argument for "ad hoc" finalization. My main objections are to using a pragma and to any automatic saving of clean-up state. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .