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

ilya ilya.nikokoshev at gmail.com
Thu Dec 31 04:48:20 CST 2015

Honest question, where's the guarantee that the optimizer isn't allowed to
optimize defer {val} away?

On Thu, Dec 31, 2015 at 00:33 Joe Groff via swift-evolution <
swift-evolution at swift.org> wrote:

> On Dec 30, 2015, at 1:27 PM, Kevin Ballard <kevin at sb.org> wrote:
> 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).
> Another possibility I've thought of is defining `defer { val }` to
> guarantee that val remains alive until the defer fires on scope exit. That
> might let us leave `defer` as the one "guarantee something happens exactly
> at scope exit" language construct.
> -Joe
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151231/8f9d0bb8/attachment.html>

More information about the swift-evolution mailing list