[swift-evolution] [Proposal] Scoped resources (like C# using statement)

Kevin Ballard kevin at sb.org
Wed Dec 30 15:27:52 CST 2015


On Wed, Dec 30, 2015, at 09:53 AM, Joe Groff wrote:
>
>> On Dec 29, 2015, at 8:55 PM, Kevin Ballard via swift-evolution <swift-
>> evolution at swift.org> wrote:
>>
>> An alternative solution is to do what Rust and C++ do, which is to
>> use RAII. Which is to say, instead of introducing a new language
>> construct that's explicitly tied to a scope, you just use a struct to
>> represent the resource that you hold (e.g. a File that represents an
>> open file). Of course, this does require some changes to structs,
>> notably the addition of a deinit. And if structs have a deinit, then
>> they also need to have a way to restrict copies. This is precisely
>> what Rust does; any struct in Rust that implements Drop (the
>> equivalent to deinit) loses the ability to be implicitly copied (a
>> second trait called Clone provides a .clone() method that is the
>> normal way to copy such non-implicitly-copyable structs).
>
> deinit doesn't make sense for value types. Classes already support
> deinit, and you can use withExtendedLifetime to bound the lifetime of
> a resource-holding class. It would be reasonable to have a scoped
> lifetime marker similar to ObjC ARC too.

If you run with the idea that any resource-holding class should also be
the mechanism by which you access the resource (e.g. a LockGuard that
represents holding the lock and also provides access to the guarded
value) then there's no need for extended lifetimes, because as long as
you're accessing the resource, you're keeping the resource-holding class
alive. I suppose there might be rare cases where you need to extend the
lifetime of a resource-holding class even when you're not accessing the
resource, just to guarantee e.g. order of resource releasing, but you
can always just say something like `withExtendedLifeetime(&val) {}` at
the end of the scope to ensure the value is still alive at that point.
Although I'd really like to define `_ = val` as guaranteeing that the
value is alive at that point (the expression doesn't actually do
anything, but because it references `val` it expresses the programmer's
intent that `val` should still be alive at that point in time).
Alternatively, if we end up with move-only structs (or uniquely-owned
classes), we could even define the expression `_ = val` as "dropping"
the value , i.e. forcing it to deinit at that spot (because it's moving
the value out of the `val` variable). This would be analogous to Rust's
`std::mem::drop()` function (which is literally defined as `pub fn
drop<T>(_x: T) { }` because all it does is move the value into the
function and then forget about it).

-Kevin Ballard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151230/c2dabdbe/attachment.html>


More information about the swift-evolution mailing list