Kotlin needs try-with-resources

It appears that is use, but based on AutoCloseable instead of Closeable. Many things that implement AutoCloseable also implement Closeable, but some do not. However the issue is that AutoCloseable is not available in Java 6, but Closeable is and Kotlin targets only Java 6.

It occurs to me that there could be a use for a more general purpose use:

inline fun <T,R> use(t: T,  onExit:T.() -> Unit, block: (T) -> R): R {
    try {
        return block(t);
    } finally {

The general purpose function with an onExit is very useful. That does not mean that an autoclose function would not be very useful as well (extending on your base, in this case with Closeable, but overloads to other types would be acceptable, for example to the jdbc types that for some reason don’t implement closeable):

inline fun <T:Closeable, R> autoClose(t:T, block: (T) -> R) = use(t, { close() }, block)

What would be really cool is if the following code would actually compile (maybe using some sort of template like SFINAE approach), note that this fails if T does not have a close method, but that the method could be resolved at compile time:

inline fun <reified T, R> autoClose(t:T, block: (T) -> R) = use(t, { close() }, block)

I am aware however that the error messages that can generated if this is brought forward can be horrific (see C++ template substitution failure)

It is not better itself. The only fact is that “use” is only working for “Closeable” classes, not for “AutoCloseable”.

And the reason is that Kotlin only targets Java 6 and AutoClosable did not exist in Java 6. If you are only targeting later Java it is trivial to add to your code

For those who do not want to implement the utility themselves and while Kotlin developers think whether to add it or not to stdlib, you may use a basic implementation (as described above) already available in Maven Central


Targeted JRE 8, ancient stuff is not going to be supported…

I completely agree with the point that new language construct should be avoided. But the lack of the try-with-resources (a feature that both Java and C# have) is a step backwards. It’s a fundamental concept which is a must-have in language without destructors. It deserves a proper syntax and a language construct which would make it fool-proof, as safe as possible and autocomplete-, fixit- and diagnostcs- friendly. It’s 10 times as important as any other candidate for a language construct.

@cubuspl42 That’s right, but given that all of that could be achieved with the help of standard use function, is there still a reason to introduce special language construct for that?

I completely agree with @alexd457. I took the idea presented here and extended it a little further, please let me know what you think.

Here is the implementation.

And usage examples via unit tests.

But seriously, none of this should be remotely necessary. This is something that should absolutely be a language construct. It makes sense for it to be, and would solve a whole host of problems.

This + overload is the exactly reason why many people don’t like operator overloading. + is about numbers, not about resource management. I would suggest just to use some function name. Otherwise great idea, I didn’t know that you could “overload” catch like that. I made similar library for myself. Honestly Jetbrains should just add something like that to standard library along with use.

I agree about + overloading. Better to use something like use or even resource to avoid name clashes. As for the whole discussion, I think it is a great idea to move a lot of features from language into library, it simplifies understanding of the code and gives a lot of additional freedom.

I also think that try-with-resources should be in library functions.
On the other hand, I think that a seperate project “Kotlin-EE” like “Java-EE” should be maintained, where things like this should be standardized.
But maybe it’s to early for that, yet?

1 Like

I agree with both of you, the + overload was bad and I’ve switched it out for a standard extension method, .autoClose(). Due to the overhead of the ResourceManager, and the messiness of requiring the finally {} block else all exceptions would be eaten (which is what people would inevitably do), I stand by my position that this is too important to just be a library function. If someone comes up with some cool new syntax for dealing with this that is natural, efficient, and safe, then I’ll be happy to use it. But so far no one has offered up anything which satisfies all three of those requirements.

The natural part is hard to satisfy. I would say that Kotlin property delegates were not natural to me when I first read about them, but now I use them like I never knew any better.

But I think the standard use function satisfies efficiency and safety (otherwise it probably would not be part of the standard library). The only downside of use is that it only works with Closeable on the JVM target, but that is solvable: Generic use function

Assuming a generic version of use, the remaining question is: Is it really that unnatural to nest a few uses?

I am a method extraction fanatic, so when I am bothered by a deeply nested structure, I simply extract additional methods.

Why did you used this design with catch-finally things? I don’t really understand it. Here’s topic with my code: Is there standard way to use multiple resources? I don’t really see any problems with exceptions. May be I missed something?

There’s also use for AutoCloseable, it is available in kotlin-stdlib-jre7 library: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/use.html

In my opinion, yeah it’s pretty unnatural. Well, at the worst maybe just messy and ugly. Sure, those aren’t deal breakers, I’m not saying Kotlin is a bad language because of this, but for me it’s a major pain point. Everywhere else Kotlin is clean and accomplishes it’s goals with simplicity, but here it falls flat on it’s face. Even with additional methods you still have the issue that to get any kind of exception handling built in you always have to nest it inside another try-catch.

To me this speaks of a poorly designed resource management system. As @alexd457 said, when a language uses exceptions to handle error states, resource management should be closely designed with it. Simply throwing the exception in the .use() block and catching that in a subsequent try-catch block underneath it is just dirty.

I’m not saying that it doesn’t work. .use() certainly works, and you can use it perfectly safely. I am saying the current system is not very good and needs to be improved, and as far as I’ve seen extending the language itself is far and away the best option for doing that. I kind of understand the idea that accomplishing it with the stdlib is easier to work with and undersatnd, but I disagree. Complex stdlib methods are not easy to work with, language constructs built specifically around these goals are typically much better suited. .use() is not a complex method by any means, but it’s simplicity brings it’s drawbacks.


Are there any plans for common (non JVM specific) AutoCloseable and/or Closeable interfaces, and use extension function?

I’m writing mostly multiplatform libraries and I find it inconvenient to define my own use() extensions for the lib users. I believe it’s nicer if they can simply use the stdlib functions (and I wouldn’t need to test it :stuck_out_tongue:) .

Why not defining some sort of deconstructor for each class?

Like the unusable (so meaningless) finalize() function in java.
Kolin could call this function 100% before beginning the object deallocation.

So a nice place for putting the expected close() into.

No it can’t. Deallocation is done by the JVM garbage collector and the control you have over that is quite low and depends on the jvm implementation. Maybe this can be done on native, but I don’t see this working on the JVM.

I know. Therefore I wrote

Kotlin native would have the potential.

Perhaps there is a possibility tweaking the compiler so that all objects are somehow soft-referenced by the “kotlin runtime” and then deconstructed and after that released (for java deallocation).