From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: A suggestion for resource management
Date: Tue, 07 Sep 2010 13:14:34 +0300
Date: 2010-09-07T13:14:34+03:00 [thread overview]
Message-ID: <8emhkaFskqU1@mid.individual.net> (raw)
In-Reply-To: <87k4n14977.fsf@mid.deneb.enyo.de>
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 <statement>". 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 <statement>"? 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
. @ .
next prev parent reply other threads:[~2010-09-07 10:14 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-21 16:20 A suggestion for resource management Florian Weimer
2010-08-21 19:07 ` Dmitry A. Kazakov
2010-08-21 19:47 ` Florian Weimer
2010-08-21 20:53 ` Dmitry A. Kazakov
2010-08-21 21:09 ` Florian Weimer
2010-08-22 6:40 ` Dmitry A. Kazakov
2010-08-23 23:22 ` Randy Brukardt
2010-08-21 20:34 ` Niklas Holsti
2010-08-21 21:01 ` Florian Weimer
2010-08-22 10:53 ` Niklas Holsti
2010-08-22 15:29 ` Florian Weimer
2010-08-22 16:12 ` Florian Weimer
2010-08-23 12:25 ` Niklas Holsti
2010-09-04 19:09 ` Florian Weimer
2010-09-07 10:14 ` Niklas Holsti [this message]
2010-08-22 11:32 ` Georg Bauhaus
2010-08-23 23:37 ` Randy Brukardt
2010-08-22 13:09 ` stefan-lucks
2010-08-22 14:30 ` Florian Weimer
2010-08-22 15:09 ` Florian Weimer
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox