Sent from my iPad

> On Dec 30, 2015, at 3:33 PM, Joe Groff via swift-evolution 
> <[email protected]> wrote:
> 
> 
>> On Dec 30, 2015, at 1:27 PM, Kevin Ballard <[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]> 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.

+1.  This seems like a really good way to do it.

> 
> -Joe
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to