This makes sense, but I'm wondering how far should one go.
Since I'm making a data-first language called Adama ( https://www.adama-platform.com ), things that go bad are very bad. I'm aiming for nothing bad to happen without forcing the developer's hand. For instance, I recently upgraded the signature for division to return maybe<double>, so 1 / x has a type of maybe<double> which means you may not have a value.
I then added the appropriate algebraic extensions such that double + maybe<double> -> maybe<double> and this all requires a final if (that_value as x) { ... use x as the final result of the computation }. I even force division into the double space since integer division can be surprising.
I went a bit nuts and even made complex numbers a first class citizen so (-1).sqrt() returns a complex number.
One reason for this is that exceptions are surprise. I want to minimize surprises. Resources and the need to close them are a form of a surprise for long-lived applications. However, how far does one go? That's a fun question.
It's worth noting that I don't even have untyped nulls since I use maybe/optional types.
I wonder why in the middle of 2022 people still put pre-2011 and pre-JDK7 snippets. And even try-with-resources example is not all what JDK7 provides, there are better, high-level utilities added which haven't got a proper attention.
Namely, in JDK7 and newer, you can just write:
Files.readAllBytes(Path.get("story.txt"))
The point of the article was to compare how resource cleanup works in general in different languages. What you show here is a very special case that does not extend to other resources or even other file operations. Still, try-with-resources and AutoClosable is the best what Java has to offer, and it is clearly inferior to Rust/C++ approach (and to some degree also to Go and Zig, but less so).
Since I'm making a data-first language called Adama ( https://www.adama-platform.com ), things that go bad are very bad. I'm aiming for nothing bad to happen without forcing the developer's hand. For instance, I recently upgraded the signature for division to return maybe<double>, so 1 / x has a type of maybe<double> which means you may not have a value.
I then added the appropriate algebraic extensions such that double + maybe<double> -> maybe<double> and this all requires a final if (that_value as x) { ... use x as the final result of the computation }. I even force division into the double space since integer division can be surprising.
I went a bit nuts and even made complex numbers a first class citizen so (-1).sqrt() returns a complex number.
One reason for this is that exceptions are surprise. I want to minimize surprises. Resources and the need to close them are a form of a surprise for long-lived applications. However, how far does one go? That's a fun question.
It's worth noting that I don't even have untyped nulls since I use maybe/optional types.