> On Dec 31, 2015, at 2:48 AM, ilya <[email protected]> wrote: > > Honest question, where's the guarantee that the optimizer isn't allowed to > optimize defer {val} away?
There isn't one, today. It would be a language change if we wanted to make that guarantee. -Joe > On Thu, Dec 31, 2015 at 00:33 Joe Groff via swift-evolution > <[email protected] <mailto:[email protected]>> wrote: > >> On Dec 30, 2015, at 1:27 PM, Kevin Ballard <[email protected] >> <mailto:[email protected]>> 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 >>>> <[email protected] <mailto:[email protected]>> 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 > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
