Idea[Simplified try-with-resources statement]

Brian Goetz brian.goetz at oracle.com
Mon Sep 25 16:26:16 UTC 2023


I'm not sure taking inspiration from Go's `defer` is a great idea here.  
Yes, cleanup is a common problem in C, and defer lets you co-locate 
actions with their compensating cleanup actions, but Go's approach 
explicitly ignores scopes in favor of function boundaries. The result is 
that things like "extract method" refactors actually changes when 
cleanup side-effects can be observed.

For example:

     func f() {
         defer fCleanup();
         for i := 0; i <= 3; i++ {
             defer x(i)
             y(i)
         }
         // cleanups haven't happen yet
     }

Now, if we refactor:

     func g(i int) {
         defer x(i)
         y(i)
     }

     func f() {
         defer fCleanup();
         for i := 0; i <= 3; i++ {
             g(i)
         }
         // loop-based cleanups have happened here, their side-effects 
are visible
     }

the timing of cleanup side-effects changes in a visible way.  While 
"most of the time" this might be OK, this behavior is an error waiting 
to happen, and it comes from mixing block-level scoping with 
function-level scoping.  I wouldn't want to introduce this same problem 
into Java.  (But, this isn't essential to your proposal; Swift's `defer` 
doesn't fall into this trap.)

Java's scoping rules may result in more indentation, but it means users 
don't have to engage in complex reasoning about the timing of cleanup 
actions.  Java lets you say clearly what you mean here. Reading code is 
more important than writing code, and the explicit scoping makes code 
easier to read.



> This proposal introduces a shorthand declaration that eliminates the
> scope limitations of `try-with-resources statement`. It enables
> variable declaration, assignment, and usage within the same scope,
> reduces indentation levels for improved code readability (particularly
> in `nested try-with-resources statements`), and defers the timing of
> resource release to the system, ensuring resource disposal before the
> scope in `try-with-resources statement` is declared ends. (Similar to
> Golang's `Defer statement` + resource
> close[https://go.dev/tour/flowcontrol/12], C#'s `using
> declarations`[https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/using],
> and Swift's `Defer statement` + resource
> close[https://docs.swift.org/swift-book/documentation/the-swift-programming-language/statements/#Defer-Statement])



More information about the amber-dev mailing list