[swift-evolution] Proposal: Extend unnamed let variable scope

Joe Groff jgroff at apple.com
Thu Dec 10 10:51:04 CST 2015


> On Dec 10, 2015, at 8:46 AM, Jason Pollack via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I was experimenting in Swift with RAII, a technique I find very useful from C++.  In general it works well, but there is something I found unexpected.
> 
> Consider this class:
> 
> class RAII {
>     init() {
>         print("some resource acquired")
>     }
>     deinit {
>         print("some resource released")
>     }
> }
> 
> And this sample code:
> 
>         let b = true
>         if (b)
>         {
>             print("Entered scope")
>             let raii = RAII()
>             print("Going out of scope")
>         }
>         print("Left scope")
> 
> As expected, I see the output:
> 
> Entered scope
> some resource acquired
> Going out of scope
> some resource released
> Left scope
> 
> However, the compiler gives me a warning on the 'let raii = ' line:  "Initialization of immutable value 'raii' was never used; consider replacing with assignment to '_' or removing it"
> 
> If I change that line to:
> 
> let _ = RAII()
> 
> the warning goes away, but I get the unexpected output:
> 
> Entered scope
> some resource acquired
> some resource released
> Going out of scope
> Left scope
> 
> It appears the object instance is being destroyed immediately after being created, because the compiler correctly sees that nobody needs it.
> 
> Therefore, I propose that such instances stay referenced until the end of the scope they are declared in. 

ARC does not normally guarantee scoped lifetimes; the optimizer will shorten lifetimes so that objects get released after their last use, not when their variable goes out of scope. If you don't use the result of a computation at all, it will likely be immediately released. You can use `withExtendedLifetime` to set a minimum bound for the lifetime of a reference:

withExtendedLifetime(RAII()) {
  print("Going out of scope")
}

> (As an aside, I would like to see a deinit on a struct to support this technique as well.)

If structs support destructors, then they potentially also need to support copy constructors and all the other complexity of C++ to describe what happens when they get copied. Resources really do have referential identity in practice; classes are the appropriate way to model them.

-Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151210/e6f5ddbd/attachment.html>


More information about the swift-evolution mailing list