[cap-talk] small notes re: waterken

David-Sarah Hopwood david-sarah at jacaranda.org
Sat Mar 5 18:34:14 PST 2011


On 2011-03-05 23:07, Rob Meijer wrote:
> On Sat, March 5, 2011 18:52, Mark S. Miller wrote:
> 
>> #2 is where I think I must be missing something. Let's take the familiar
>> case of opening a file to get a stream, doing stuff with the stream, and
>> then reliably closing the stream when we're done with it, whether by
>> normal
>> or exceptional exit. I understand how to code this in RAII. But why isn't
>> the following just as good in a language without RAII:
>>
>> The equivalent of defining a given RAII abstraction:
>>
>>     ? def withInputStream(file, func) {
>>     >     def stream := file.inputStream()
>>     >     try {
>>     >         return func(stream)
>>     >     } finally {
>>     >         stream.close()

This is wrong because 'stream.close()' may throw an exception that would
replace an exception thrown by 'func(stream)', but that's a general problem
with "finally" and is easily fixed.

>>     >     }
>>     > }
>>
>> The equivalent of using it:
>>
>>     ? withInputStream(<file:index.html>, fn stream { stream.available() })
>>     # value: 1510
>>
>> where "stream.available()" is an example of "arbitrary code that uses the
>> stream", as one might have coded in a C++ RAII block.
>>
>> I did see a comment in this thread that try/finally isn't as good as RAII,
>> but I don't understand why. What am I missing?
> 
> What I think you may be missing is the combination with 'encapsulation'
> that I tried to give an example of. Lets say your file handle resource is
> a deeper encapsulated resource.  With RAII the knowledge that there is a
> file resource that needs closing stops with the file class. Once an object
> with a deeply encapsulated resource goes out of scope 'close()' will get
> invoked on the file handle. With 'finaly', the close() method will need to
> be copied by the encapsulating object and any object encapsulating the
> encapsulating object, etc.

That's not a problem. close() has side-effects and therefore should always be
performed explicitly. If some outer resource holds a reference to an inner
resource, then the correct point at which to dispose the inner resource
will depend on the outer resource's specification. It is not necessarily
the case that the inner resource should be disposed when the outer resource
is (but if that *is* the case, it's trivial to do so explicitly). If the
application forgets about the outer resource without disposing it, that's
an application bug. If the outer resource forgets about the inner resource
without disposing it, that's a bug in the implementation of the outer
resource.

In any case, RAII only handles the cases that are trivial. The resource
leaks that are problematic in practice are those for resources with dynamic
lifetimes where RAII doesn't help.

-- 
David-Sarah Hopwood  ⚥  http://davidsarah.livejournal.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 292 bytes
Desc: OpenPGP digital signature
Url : http://www.eros-os.org/pipermail/cap-talk/attachments/20110306/86673efe/attachment.bin 


More information about the cap-talk mailing list