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:
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.