Hello core-libs devs, The ExtentLocal <https://bugs.openjdk.org/browse/JDK-8263012> proposal adds a new way to transfer arguments to methods, e.g. (taken from project’s loom git <https://github.com/openjdk/loom/blob/2bf3cbcf3254a08ca9d1c20ed14e0976660351b8/src/jdk.incubator.concurrent/share/classes/jdk/incubator/concurrent/ExtentLocal.java#:~:text=target%3D%22ExtentLocal%23newInstance%22%20%3A-,*%20%20%20private%20static%20final%20ExtentLocal%3CCredentials%3E%20CREDENTIALS%20%3D%20ExtentLocal.newInstance()%3B,*%20%20%20%7D,-*%20%7D> )
private static final ExtentLocal<Credentials> CREDENTIALS = ExtentLocal.newInstance(); Credentials creds = ... ExtentLocal.where(CREDENTIALS, creds).run(() -> { ... Connection connection = connectDatabase(); ... }); ... Connection connectDatabase() { Credentials credentials = CREDENTIALS.get(); ... } I have a question about the proposal, why not allow try-with-resources with this API? private static final ExtentLocal<Credentials> CREDENTIALS = ExtentLocal.newInstance(); Credentials creds = ...// Hopefully one day Java will support anonymous variables in "try-with-resource" to get rid of the "var _ =" part// note that we still can introduce several binding with chaining ".where" without introducing several dummy variablestry(var _ = ExtentLocal.where(CREDENTIALS, creds)) { // maybe have a new method instead of "where" that returns some wrapper class, so ExtentLocal.Carrier won't need to implement AutoClosable ... Connection connection = connectDatabase(); ... } ... Connection connectDatabase() { Credentials credentials = CREDENTIALS.get(); ... } The syntax of .where(...)....where(...).run(...) is nice, but it is weird that we “introduce variables” from a different clause then the run (I know it is only bindings, but it acts similar enough), the syntax of try-with-resources is already well known to introduce new variables. Another advantage is the ability of “catch” block without increasing nesting: try { ExtentLocal.where(CREDENTIALS, creds).run(() -> { Connection connection = connectDatabase(); }); } catch (...) { ... } versus try(var _ = ExtentLocal.where(CREDENTIALS, creds)) { Connection connection = connectDatabase(); } catch (...) { ... } (Another solution to this is too add .catch method to ExtentLocal.Carrier to handle exceptions, but this will cause problems with call vs run) Further furthermore, one can combine it with structured concurrency <https://openjdk.org/jeps/428>: public Response handle(Credentials creds) throws ExecutionException, InterruptedException { try (var scope = new StructuredTaskScope.ShutdownOnFailure(); var _ = ExtentLocal.where(CREDENTIALS, creds)) { // functionally this binding is part of the scope Future<String> user = scope.fork(() -> findUser()); Future<Integer> order = scope.fork(() -> fetchOrder()); scope.join().throwIfFailed(); return new Response(user.resultNow(), order.resultNow()); } } Instead of doing something like: // If this solution is possible at all, if the Credentials are a field in the object then you need to introduce some method to use "handle()" with the correct Extent binding, or wrap the body of "handle()" inside of the method "handle()" which needlessly increase nestingspublic Response handle(Credentials creds) throws ExecutionException, InterruptedException { return ExtentLocal.where(CREDENTIALS, creds).call(this::handle) } public Response handle() throws ExecutionException, InterruptedException { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<String> user = scope.fork(() -> findUser()); Future<Integer> order = scope.fork(() -> fetchOrder()); scope.join(); scope.throwIfFailed(); return new Response(user.resultNow(), order.resultNow()); } } Before saying that I shouldn’t couple handle() to CREDENTIALS, note that findUser and fetchOrder are already coupled to it, in fact the use of private ExtentLocal variable introduce coupling pretty much by definition (which is the intended use case <https://github.com/openjdk/loom/blob/fibers/src/jdk.incubator.concurrent/share/classes/jdk/incubator/concurrent/ExtentLocal.java#:~:text=An%20%7B%40,nest).>, although I can think on some use cases with public ExtentLocal). Now, I do really like the where-run syntax, but I see a lot of merits in allowing also try-with-resources as well. Thanks for the read, Yuval Paz