Adding try-with-resource to Scala

Your argument seems to boil down to “I can remember to use <- but I can’t remember to use use

The problem comes with teams of people and refactoring. Take the code

Using.Manager { use =>
  val res1 = use(acquireRes1())
  val res2 = use(acquireRes2())
  val res3 = somethingElse()

  compute(res1, res2, res3)
}

another teammate, maybe responsible for somethingElse that comes from an internal library makes it now a “resource”, it needs closing. The compiler wont catch you here and you now have a resource leakage. Good or not, if you use for-comps, that can’t happen:

for {
  res1 <- acquireRes1()
  res2 <- acquireRes2()
  res3 = somethingElse()
} yield compute(res1, res2, res3)

when somethingElse is changed to return a “resource”, now you can’t just pass it to compute, because the value is wrapped.

3 Likes

Okay, so the idea is that you’d change

def somethingElse(): Foo

to

def somethingElse(): Resource[Foo]

but you’d still have

def compute(baz: Baz, bar: Bar, foo: Foo): Quux

Yeah, that would provide additional safety. Not the way you were showing it, where you did the wrapping in AutoClose right where you were using it–because you have to remember to wrap in order for the compiler to force you to unwrap (which it does for you with <-).

It wouldn’t necessarily have to be through for, though. use could do it too; it would just need a different type signature than with Using.Manager so it would take a wrapped type and returned an unwrapped one. You could call it Using.Resources, and the signature of the Resourcer’s apply method would be def apply[R](r: Resource[R]): R. Then you could change somethingElse to return Resource[Foo] instead of Foo and you’d be safe. (You might even be able to just add a method to Manager that does unwrapping and not bother with a new helper object.)

Something like that is, I suppose, worth thinking about.

Having two nearly identical resource-use methods, one more limited but better typechecked than the other, does not sound like the best idea to me.

Not the way you were showing it, where you did the wrapping in AutoClose right where you were using it

Note that I am a different poster than the one with the inline AutoClose example :sweat_smile:.

I agree with the rest of your assessment.

Oops! Maybe I hit reply on the wrong message.

1 Like