Function level try recourse directives.

Red IO redio.development at gmail.com
Wed Dec 28 10:43:50 UTC 2022


I think there where many valid points against it mentioned. But I disagree
with your scope thesis. The "open try resource" is not meant to be used
like this:
void foo() {
..
{
try (..);
..
}
..
}
Which is what I understand you mean by opening a scope just for the scope
itself. It is meant primarily for use cases where your resource live the
lifetime of the function, which is pretty common in well refractored code.
Also adding the scope defeats the idea of the feature entirely. You could
write:
void foo() {
 ..
try (..) {

  ..
 }
 ..
}
Which is exactly what the current existing try resource is. The motivation
of feature is to remove redundant nesting. You often encounter situations
like this:
void foo() {
try (..) {
//the entire code of the function
}
}
In this example the layer of nesting the try resource introduces is totally
unnecessary since the scope is the same as the function scope. I think you
underestimate the occurrences of the code above. Also with closable
resources increasing in numbers the amount of nesting in Java code will be
greatly increased. My estimate is that the scopeless try resource is as
often applicable in Java as the scopeless if is.
I proposed adding this feature not only because I think it's a great
feature in general but also since it already has a track record of being
useful and used by a community very similar to the java community. C# has
the exact same feature as java's try resource just with a different keyword
used (using). It has the scopeless version and if you look at some c# code
that uses closable resources the scopeless variant is used 70+% of the time.
It removes a lot of redundant scoping while not really adding much
complexity nor using syntax that is likely to be used by some other feature
in the future.
I'm not sure how difficult the addition of a feature like this is since I
still have no idea how changes in syntax are done in Java by any means. But
if it's not to difficult to implement why not try it and ask the community
what they think. I think asking the community whether they would use it or
not is way more effective than speculating how popular it might be. It
wouldn't even have to be implemented to ask the community what they think.
I don't have the audience to make such surveys by any means. Otherwise I
would do a post, video or poll myself.

On Tue, Dec 27, 2022, 20:15 Reinier Zwitserloot <reinier at zwitserloot.com>
wrote:

> Lombok’s @Cleanup (https://projectlombok.org/features/Cleanup) works
> exactly like that:
>
> @Cleanup var foo1 = new Foo1();
> @Cleanup var foo2 = new Foo2();
>
>
> Does what you want. However, it runs to the end of the scope that foo1 is
> defined in. An exotic java feature is that you can just write braces
> whenever you feel like, so you can use that to scope your resources as
> desired:
>
> void example() {
>   @Cleanup var db = ...; // scoped for the method, so closed at the end
>
>   String acctName; { // note, just an opening brace here, on its own. Legal.
>     @Cleanup var rs = db.query(...);
>     acctName = rs.getString(1);
>   }
>
>   System.out.println(acctName);
> }
>
>
> It feels like the road not taken: That looks fine, is as flexible as you
> need it to be (in that you control exactly where the resource should be
> closed) and works great in daily use. It’s just… not what the
> try-with-resources construct ended up doing. It feels a little odd to add
> it *now*, and ‘just write some braces to scope some variables’ is not a
> thing your average java programmer ever does. I’m not quite sure why not
> (it’s quite useful given that java doesn’t make it easy to put helper
> methods inside methods), but, it is what it is: Introducing this feature
> more or less demands of the community that they get into the habit of
> writing braces solely to define a scope. This is a big ordeal; for example,
> most autoformatters will make this unduly ugly by forcibly trying to let
> the opening brace start on its own line (sometimes, it’s own entire
> paragraph, i.e. 2 newlines are injected), even though often it is more
> convenient and easier to read to open it *after* the relevant variable
> declaration, or a comment or label explaining what the point of this block
> is.
>
> A casual analysis indicates that going all out leads to nice results and
> anything in between would incur significant costs. In other words, we
> should have *either* a java where everybody is used to using braces to
> create scoped blocks and the *only* variant of try-with is the
> stand-alone one as you propose - *or* we have the java we have today,
> where almost nobody knows it’s legal to just write braces to create a
> scoped block, auto-formatters don’t know what to do with them, and try-with
> comes with its own mandatory block.
>
> Given that at this juncture it’s not possible to travel back in time and
> get rid of the existing try-with (with the mandatory block), I’d say: This
> idea doesn’t “work” for java. And that’s coming from someone who is so
> convinced your way is better, he programmed it into lombok about a year
> before try-with was introduced :)
>
> In other words, better is great, but ‘does not demand significant cultural
> adjustments and does not lead to endless style wars’ is better.
>
> The costs incurred are high cultural friction, style wars, and likely,
> that this alternate ‘form’ of try-with will be so rarely used, it will end
> up being a member of that list of ’java lang features most programmers
> don’t *ever* use and cannot recognize’. It’s not a good idea for that
> list to grow any longer than it already is.
>
>  --Reinier Zwitserloot
>
>
> On 27 Dec 2022 at 14:49:13, Red IO <redio.development at gmail.com> wrote:
>
>> I was once again writing closing heavy code in a java method and was
>> wondering if I could reduce the clutter of the multi line try block:
>> try (var foo1 = new Foo1() ;
>> var foo2 = new Foo2() ;
>> ....) {
>> ...
>> }
>> Sometimes we need to initialize something between the resources and we
>> get multiple levels of nesting.
>> And I was wondering if we could not just lose the block and auto close at
>> the end of a method like this :
>>
>> void foo() {
>> try (var foo1 = new Foo1());
>> //init some stuff
>> try (var foo2 = new Foo2());
>> // do some stuff
>> // auto close at end of method
>> }
>>
>> I think method level try recourse would improve readability and
>> unnecessary nesting significantly.
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20221228/aff4907d/attachment.htm>


More information about the amber-dev mailing list