<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.2.1" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: If Java Could Have Just One C++ Feature&#8230;</title>
	<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/</link>
	<description>A man needs a little madness, or else he never dares cut the rope and be free. -Nikos Kazantzakis</description>
	<pubDate>Wed, 20 Aug 2008 20:44:27 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2.1</generator>

	<item>
		<title>By: Sree</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-1076</link>
		<author>Sree</author>
		<pubDate>Mon, 14 Aug 2006 10:44:03 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-1076</guid>
		<description>Catching Uncaught Exceptions 
http://www.roseindia.net/javatutorials/catching_uncaught_exceptions_in_jdk_5.shtml</description>
		<content:encoded><![CDATA[<p>Catching Uncaught Exceptions<br />
<a href="http://www.roseindia.net/javatutorials/catching_uncaught_exceptions_in_jdk_5.shtml" rel="nofollow">http://www.roseindia.net/javatutorials/catching_uncaught_exceptions_in_jdk_5.shtml</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Infernoz</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-993</link>
		<author>Infernoz</author>
		<pubDate>Fri, 11 Aug 2006 13:54:22 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-993</guid>
		<description>"why doesn’t a file stream close itself before it throws the exception?"

Because a stream may contain state, like a line number, file offset, connection parameters etc., you need to record when an exception occurs, exceptions often don't pass state or provide enough information, that is what a catch clause is for.

This naive comments on this thread suggest that some people here don't have a clue how important logging is or knowing why an issue occured e.g. via exceptions and object state, this requirement quite validly applies to close() too, so a boolean return value is not OK.</description>
		<content:encoded><![CDATA[<p>&#8220;why doesn’t a file stream close itself before it throws the exception?&#8221;</p>
<p>Because a stream may contain state, like a line number, file offset, connection parameters etc., you need to record when an exception occurs, exceptions often don&#8217;t pass state or provide enough information, that is what a catch clause is for.</p>
<p>This naive comments on this thread suggest that some people here don&#8217;t have a clue how important logging is or knowing why an issue occured e.g. via exceptions and object state, this requirement quite validly applies to close() too, so a boolean return value is not OK.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: adiGuba</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-980</link>
		<author>adiGuba</author>
		<pubDate>Fri, 11 Aug 2006 07:07:56 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-980</guid>
		<description>Hello.


Even if the finalize() method close the stream, it's better to close it immediatly at the end of the task, because you cannot determine exactly (and easyly) when the GC while finalize the stream...

I use this pattern to correctly close the strea, which has the advantage to use only one catch for all the stuff (close() included) :


try
{
	FileInputStream f = new FileInputStream(“somefile”);
	try
	{
 	   // Do some stuff
	}
	finally
	{
		f.close();
	}
}
catch(IOException e)
{
	// Frankly, my dear…
}</description>
		<content:encoded><![CDATA[<p>Hello.</p>
<p>Even if the finalize() method close the stream, it&#8217;s better to close it immediatly at the end of the task, because you cannot determine exactly (and easyly) when the GC while finalize the stream&#8230;</p>
<p>I use this pattern to correctly close the strea, which has the advantage to use only one catch for all the stuff (close() included) :</p>
<p>try<br />
{<br />
	FileInputStream f = new FileInputStream(“somefile”);<br />
	try<br />
	{<br />
 	   // Do some stuff<br />
	}<br />
	finally<br />
	{<br />
		f.close();<br />
	}<br />
}<br />
catch(IOException e)<br />
{<br />
	// Frankly, my dear…<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Shai Almog</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-806</link>
		<author>Shai Almog</author>
		<pubDate>Thu, 03 Aug 2006 15:44:01 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-806</guid>
		<description>It just occured to me now (after all these years...) why doesn't a file stream close itself before it throws the exception? It knows it would fail, right? right before the throw statement include a close (technically its thrown in native but same thing). 
So I looked a bit in the mustang source code (an old source tree but still...) and it seems they didn't do that but it seems pretty trivial to add this (Mustang submission anyone?). The nice thing is that you can easily create an Input/Output stream that wrapps any existing stream and provides this functionality ;-)</description>
		<content:encoded><![CDATA[<p>It just occured to me now (after all these years&#8230;) why doesn&#8217;t a file stream close itself before it throws the exception? It knows it would fail, right? right before the throw statement include a close (technically its thrown in native but same thing).<br />
So I looked a bit in the mustang source code (an old source tree but still&#8230;) and it seems they didn&#8217;t do that but it seems pretty trivial to add this (Mustang submission anyone?). The nice thing is that you can easily create an Input/Output stream that wrapps any existing stream and provides this functionality <img src='http://www.alittlemadness.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Shai Almog</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-805</link>
		<author>Shai Almog</author>
		<pubDate>Thu, 03 Aug 2006 15:30:39 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-805</guid>
		<description>Jason,
I think we agree on most things but see different sets of problems.

1) You are very right with your diffrentiation between limited resources other than memory and GC. The question is: what are these resources you speak of and do they matter?
In GUI we have GDI memory which is quite limited yet AWT does not require any freeing of memory and works (sort of works, but none of the problems I ran into related to GDI), when programming MFC GDI leaks would just kill me... SWT does take the approach of manually freeing stuff but this is really unrelated to destructors and is more of a "taste" issue.
Databases are resource pooled by the application server and if an exception occurs the application server should recycle everything for me (still Hibernate freaks out when I don't close the session but it has a configuration option to turn this off).
In networking we have a limited set of connections we can open, but then most networking and connections are pooled by the application server for us and despite building very high volume networked applications you reach the thread limit well before you reach the stream limit (with selectors both problems go away).
On the file system I am aware of some theoretical limitations but I have to say that the only time where I ran into a problem related to an unclosed file was in Mac OS 9 (which is really a special case). Most of the programmers I know have some code like: myMethod(new FileInputStream(file)); somewhere, even if you don't have any code like that its probable that one of your libraries has code like that and surprisingly it scales.

Don't get me wrong, you should close files and not waste resources even if the OS has plenty but my point is that this is not something to get excited about even for resources other than memory. Current performance issues are no longer related to resource conservation, if you look in the Java message boards even with the relatively advanced developers you will rarely see complaints of resource hogging related to resources other than memory. Is it because these resources are harder to detect? Or maybe because people are less familiar with them? 

3) I think the real advantage of laying everything on a GC is in my ability to tune the application later on for better performance. We had several applications that got a HUGE boost (20% - 30% difference) just by changing GC parameters.

The 4 years was a time span in which the problem existed, with 1 million lines of code and weird crashes that only occured when building release versions (no debugging) there was no way we could detect this... We tried memory tools, the few that worked (crawled) didn't produce anything so we just left it... There was no one who understood that rather complex piece of code developed by an aeronautics engineer for modeling flight and path envelopes (don't ask). So finding this particular code was a needle in one huge haystack... I'd love to claim genious on finding that bug but I was lucky, the upgrade to a new version of visual studio made the application crash in debug mode which allowed me to detect the problem... RAII would assume that we actually wrote the code, this is obviously not the case for most real world projects. 

4) You can put the stream object on the thread local or even in the exception object and then rethrow the exception to handle it in a generic location. But really thats a silly idea because you would have to catch the exception anyway so might as well handle it rather than propogate it forward. My point was to illustrate other possible solutions for propogating the exception rather than handling it in place.</description>
		<content:encoded><![CDATA[<p>Jason,<br />
I think we agree on most things but see different sets of problems.</p>
<p>1) You are very right with your diffrentiation between limited resources other than memory and GC. The question is: what are these resources you speak of and do they matter?<br />
In GUI we have GDI memory which is quite limited yet AWT does not require any freeing of memory and works (sort of works, but none of the problems I ran into related to GDI), when programming MFC GDI leaks would just kill me&#8230; SWT does take the approach of manually freeing stuff but this is really unrelated to destructors and is more of a &#8220;taste&#8221; issue.<br />
Databases are resource pooled by the application server and if an exception occurs the application server should recycle everything for me (still Hibernate freaks out when I don&#8217;t close the session but it has a configuration option to turn this off).<br />
In networking we have a limited set of connections we can open, but then most networking and connections are pooled by the application server for us and despite building very high volume networked applications you reach the thread limit well before you reach the stream limit (with selectors both problems go away).<br />
On the file system I am aware of some theoretical limitations but I have to say that the only time where I ran into a problem related to an unclosed file was in Mac OS 9 (which is really a special case). Most of the programmers I know have some code like: myMethod(new FileInputStream(file)); somewhere, even if you don&#8217;t have any code like that its probable that one of your libraries has code like that and surprisingly it scales.</p>
<p>Don&#8217;t get me wrong, you should close files and not waste resources even if the OS has plenty but my point is that this is not something to get excited about even for resources other than memory. Current performance issues are no longer related to resource conservation, if you look in the Java message boards even with the relatively advanced developers you will rarely see complaints of resource hogging related to resources other than memory. Is it because these resources are harder to detect? Or maybe because people are less familiar with them? </p>
<p>3) I think the real advantage of laying everything on a GC is in my ability to tune the application later on for better performance. We had several applications that got a HUGE boost (20% - 30% difference) just by changing GC parameters.</p>
<p>The 4 years was a time span in which the problem existed, with 1 million lines of code and weird crashes that only occured when building release versions (no debugging) there was no way we could detect this&#8230; We tried memory tools, the few that worked (crawled) didn&#8217;t produce anything so we just left it&#8230; There was no one who understood that rather complex piece of code developed by an aeronautics engineer for modeling flight and path envelopes (don&#8217;t ask). So finding this particular code was a needle in one huge haystack&#8230; I&#8217;d love to claim genious on finding that bug but I was lucky, the upgrade to a new version of visual studio made the application crash in debug mode which allowed me to detect the problem&#8230; RAII would assume that we actually wrote the code, this is obviously not the case for most real world projects. </p>
<p>4) You can put the stream object on the thread local or even in the exception object and then rethrow the exception to handle it in a generic location. But really thats a silly idea because you would have to catch the exception anyway so might as well handle it rather than propogate it forward. My point was to illustrate other possible solutions for propogating the exception rather than handling it in place.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jason</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-803</link>
		<author>Jason</author>
		<pubDate>Thu, 03 Aug 2006 13:54:19 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-803</guid>
		<description>Shai,

Let the debate continue :).

1) Your are mixing the general concept of resource management with the specific task of memory management. Resources *are* limited, and the GC does not know a thing about them (except memory), so it doesn't know when it needs to kick in.  This is the first problem with finalizers: they burden the GC with management of resources it knows nothing about.  Nothing against GC, just don't expect it to solve everything.

3) The cost of the destructor function is clearly unavoidable when we need to clean up.  In an ideal world we would have a resource collector for every kind of resource that would know a timely and efficient way to trigger and perform cleanup.  In reality, the number of possible resources is infinite and there needs to be a generic method for dealing with them.  This generic method cannot have all the advantages of a GC which knows the kind of resource it is dealing with.

As for the stack problem, I concede these bugs can be a pain to find (but 4 years?!?).  This is a massive disadvantage of C++, but can be largely avoided by use of RAII everywhere except where you absolutely *must* start dealing with raw pointers (very rare in practice).  I don't think this is a reason to write off stack usage (after all, there are plenty of other ways to corrupt memory in C++).  Indeed, the vast majority of objects created in a typical application have a very short lifespan bounded by some stack frame.  I can't wait till compilers catch up and take full advantage of this!

4) You've lost me now.  Attach the stream object to a thread local and bother some code that shouldn't know a thing about it?

5) Close returning a boolean probably would have been a decent compromise.  The main argument against it would be API consistency.</description>
		<content:encoded><![CDATA[<p>Shai,</p>
<p>Let the debate continue :).</p>
<p>1) Your are mixing the general concept of resource management with the specific task of memory management. Resources *are* limited, and the GC does not know a thing about them (except memory), so it doesn&#8217;t know when it needs to kick in.  This is the first problem with finalizers: they burden the GC with management of resources it knows nothing about.  Nothing against GC, just don&#8217;t expect it to solve everything.</p>
<p>3) The cost of the destructor function is clearly unavoidable when we need to clean up.  In an ideal world we would have a resource collector for every kind of resource that would know a timely and efficient way to trigger and perform cleanup.  In reality, the number of possible resources is infinite and there needs to be a generic method for dealing with them.  This generic method cannot have all the advantages of a GC which knows the kind of resource it is dealing with.</p>
<p>As for the stack problem, I concede these bugs can be a pain to find (but 4 years?!?).  This is a massive disadvantage of C++, but can be largely avoided by use of RAII everywhere except where you absolutely *must* start dealing with raw pointers (very rare in practice).  I don&#8217;t think this is a reason to write off stack usage (after all, there are plenty of other ways to corrupt memory in C++).  Indeed, the vast majority of objects created in a typical application have a very short lifespan bounded by some stack frame.  I can&#8217;t wait till compilers catch up and take full advantage of this!</p>
<p>4) You&#8217;ve lost me now.  Attach the stream object to a thread local and bother some code that shouldn&#8217;t know a thing about it?</p>
<p>5) Close returning a boolean probably would have been a decent compromise.  The main argument against it would be API consistency.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jason</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-802</link>
		<author>Jason</author>
		<pubDate>Thu, 03 Aug 2006 13:38:07 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-802</guid>
		<description>Tom,

Agreed, there is an element of style to it.  Your point about there still needing a way to specify a lifetime outside of the scope is quite right.  In C++, the modern way to achieve this is to use an object on the heap wrapped in a smart pointer that gives the desired lifetime (reference counting, ownership transfer, ...).  This is elegant, but does leave more decisions up to the programmer.</description>
		<content:encoded><![CDATA[<p>Tom,</p>
<p>Agreed, there is an element of style to it.  Your point about there still needing a way to specify a lifetime outside of the scope is quite right.  In C++, the modern way to achieve this is to use an object on the heap wrapped in a smart pointer that gives the desired lifetime (reference counting, ownership transfer, &#8230;).  This is elegant, but does leave more decisions up to the programmer.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Shai Almog</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-801</link>
		<author>Shai Almog</author>
		<pubDate>Thu, 03 Aug 2006 13:26:55 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-801</guid>
		<description>Jason,
I specifically said that I don't compare finalizers to destructors ;-)

To respond to your responses:
1) Resources are not limited, thats a mistake common for C++ programmers. Once they become limited the GC will run and finalizers will occur pretty much guaranteed. Finalizers are bad because they require another GC cycle to occur but for the special case of streams its really as close to an elegant solution as GC can get. Unless you are arguing against GC which is the only proven none manual memory handling solution (reference counting breaks in very hard to detect ways).

3) Finalizers have a performance penalty (we both mentioned it) its unavoidable. So do destructors (function call cost and the cost of the content of that function), the advantage of the finalizer approach is that this cost can occur whenever the GC algorithm chooses that cost to occur (low priority thread unless resources are low). In the case of destructors they have to occur NOW, which might not be a "good time". 
Stack is a pain depending on how you look at it. As a C++ programmer I was a maintainer of a project with over 1 million lines of code. However, for more than 4 years we had to release the project with a specific module compiled in debug mode (this was passed on by our predecessors) anyway one day after upgrading to a new version of VisualStudio I got a crash in a section of that particular module, turns out someone returned a pointer to a stack object... It took us 4 years to discover this (and yes purify... right it wouldn't even look at the amount of code we had). That problem is a C++ problem, in Java this would probably be simpler but then you have to explain to most users the difference between a "stack object" and "heap object" (hell try to explain it to most people who call themselves C++ programmers, they say they understand but they don't really). The problems can be illustrated quite clearly by C# that has the terrible support for this nonsense:
   a) An object isn't REALLY a stack object anymore if you pass it onwards (to prevent memory corruption), so you might expect the performance of a stack object but you are really using a heap object.
   b) There is no reason to complicate peoples lives with such complex concepts when the JIT can scope these things for us... Hell with virtual method inlining the application flow changes completely and stack objects can be considerably wider.
   c) There are very few cases where stack objects can be used in a proper real world Java application. Streams are one such exception but these are rare, having built MANY J2ME/Java SE and Java EE applications over the past 10 years I'd say that is is hardly necessary. You can argue that members initialized in the class constructor/fields/static section could be stack objects but I disagree since this is a JIT optimization and really doesn't require a language modification.

4) We agree that you don't need to handle the exception in place. However, what I was trying to say is that EVENTUALLY you will need to catch an IOException (this is actually a great example of Java's declared exceptions), since any real world application MUST handle an IOException at some place. You can catch it in a generic way tack on the stream object into the thread local and throw it onwards letting the generic handling code close the stream for you.

5) I agree, close can fail but I doubt whether we care about this. Close is probably one of those rare cases that should return a boolean for the special cases who do care... Checked exceptions are great IMO but overused in MANY cases in the API!</description>
		<content:encoded><![CDATA[<p>Jason,<br />
I specifically said that I don&#8217;t compare finalizers to destructors <img src='http://www.alittlemadness.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>To respond to your responses:<br />
1) Resources are not limited, thats a mistake common for C++ programmers. Once they become limited the GC will run and finalizers will occur pretty much guaranteed. Finalizers are bad because they require another GC cycle to occur but for the special case of streams its really as close to an elegant solution as GC can get. Unless you are arguing against GC which is the only proven none manual memory handling solution (reference counting breaks in very hard to detect ways).</p>
<p>3) Finalizers have a performance penalty (we both mentioned it) its unavoidable. So do destructors (function call cost and the cost of the content of that function), the advantage of the finalizer approach is that this cost can occur whenever the GC algorithm chooses that cost to occur (low priority thread unless resources are low). In the case of destructors they have to occur NOW, which might not be a &#8220;good time&#8221;.<br />
Stack is a pain depending on how you look at it. As a C++ programmer I was a maintainer of a project with over 1 million lines of code. However, for more than 4 years we had to release the project with a specific module compiled in debug mode (this was passed on by our predecessors) anyway one day after upgrading to a new version of VisualStudio I got a crash in a section of that particular module, turns out someone returned a pointer to a stack object&#8230; It took us 4 years to discover this (and yes purify&#8230; right it wouldn&#8217;t even look at the amount of code we had). That problem is a C++ problem, in Java this would probably be simpler but then you have to explain to most users the difference between a &#8220;stack object&#8221; and &#8220;heap object&#8221; (hell try to explain it to most people who call themselves C++ programmers, they say they understand but they don&#8217;t really). The problems can be illustrated quite clearly by C# that has the terrible support for this nonsense:<br />
   a) An object isn&#8217;t REALLY a stack object anymore if you pass it onwards (to prevent memory corruption), so you might expect the performance of a stack object but you are really using a heap object.<br />
   b) There is no reason to complicate peoples lives with such complex concepts when the JIT can scope these things for us&#8230; Hell with virtual method inlining the application flow changes completely and stack objects can be considerably wider.<br />
   c) There are very few cases where stack objects can be used in a proper real world Java application. Streams are one such exception but these are rare, having built MANY J2ME/Java SE and Java EE applications over the past 10 years I&#8217;d say that is is hardly necessary. You can argue that members initialized in the class constructor/fields/static section could be stack objects but I disagree since this is a JIT optimization and really doesn&#8217;t require a language modification.</p>
<p>4) We agree that you don&#8217;t need to handle the exception in place. However, what I was trying to say is that EVENTUALLY you will need to catch an IOException (this is actually a great example of Java&#8217;s declared exceptions), since any real world application MUST handle an IOException at some place. You can catch it in a generic way tack on the stream object into the thread local and throw it onwards letting the generic handling code close the stream for you.</p>
<p>5) I agree, close can fail but I doubt whether we care about this. Close is probably one of those rare cases that should return a boolean for the special cases who do care&#8230; Checked exceptions are great IMO but overused in MANY cases in the API!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tom Palmer</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-787</link>
		<author>Tom Palmer</author>
		<pubDate>Thu, 03 Aug 2006 05:34:12 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-787</guid>
		<description>Um, or some linguistic construct for outliving the block. My "API" comment was a bit off. Anyway, done chattering now.</description>
		<content:encoded><![CDATA[<p>Um, or some linguistic construct for outliving the block. My &#8220;API&#8221; comment was a bit off. Anyway, done chattering now.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tom Palmer</title>
		<link>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-784</link>
		<author>Tom Palmer</author>
		<pubDate>Thu, 03 Aug 2006 03:44:56 +0000</pubDate>
		<guid>http://www.alittlemadness.com/2006/08/03/if-java-could-have-just-one-c-feature/#comment-784</guid>
		<description>Jason, I see Ruby's use of closures/blocks as a simple and convenient language construct that is very versatile.

As for "forgetting the block" in Ruby, I only have some experience myself, but I look at things as a path of least resistence issue. In any language, you sometimes need a resource to outlive the current block, so some API has to be available for that. The questions I see are, "How obvious is what I'm doing here?" and "How easy is it to accidentally forget or get lazy and cheat?". And C# is perhaps risky. The code looks the same. You just have to remember to use "using". Compared with Ruby, the constructs look more different (so code structure makes meaning clearer than in C++), but it's also very convenient and pretty (at least within the confines of the language). Being convenient and pretty makes it a nice path of least resistance.

So, anyway, all that together is why I like Ruby's style best, but I haven't carried out any statistical research or anything.

Meanwhile, thanks for the great post. Java is very much lacking in this important area, and I think raising awareness is important. And either C++, C#, or Ruby style would be an improvement over the current easily buggy style that Java has.

(By the way, I remembered to put in my last name finally. Figured it was worth doing after the confusion the last time I commented on your blog.)</description>
		<content:encoded><![CDATA[<p>Jason, I see Ruby&#8217;s use of closures/blocks as a simple and convenient language construct that is very versatile.</p>
<p>As for &#8220;forgetting the block&#8221; in Ruby, I only have some experience myself, but I look at things as a path of least resistence issue. In any language, you sometimes need a resource to outlive the current block, so some API has to be available for that. The questions I see are, &#8220;How obvious is what I&#8217;m doing here?&#8221; and &#8220;How easy is it to accidentally forget or get lazy and cheat?&#8221;. And C# is perhaps risky. The code looks the same. You just have to remember to use &#8220;using&#8221;. Compared with Ruby, the constructs look more different (so code structure makes meaning clearer than in C++), but it&#8217;s also very convenient and pretty (at least within the confines of the language). Being convenient and pretty makes it a nice path of least resistance.</p>
<p>So, anyway, all that together is why I like Ruby&#8217;s style best, but I haven&#8217;t carried out any statistical research or anything.</p>
<p>Meanwhile, thanks for the great post. Java is very much lacking in this important area, and I think raising awareness is important. And either C++, C#, or Ruby style would be an improvement over the current easily buggy style that Java has.</p>
<p>(By the way, I remembered to put in my last name finally. Figured it was worth doing after the confusion the last time I commented on your blog.)</p>
]]></content:encoded>
	</item>
</channel>
</rss>
