[swift-evolution] Should we relax restriction on closing over outer scope in class declarations?

Xiaodi Wu xiaodi.wu at gmail.com
Thu Dec 22 18:12:58 CST 2016


I have to agree with Michael; it seems dangerous to allow implicit capture
by classes. A primary purpose (telos?) of closures is to provide this
functionality, which is actually quite an advanced concept. One knows to
think carefully about this when encountering a closure expression. A
primary purpose of classes is to provide for encapsulation of code.
Accidentally extending the lifetime of a local variable in a containing
scope would be hard to notice and highly unexpected functionality. Better
not to mix these things.

On Thu, Dec 22, 2016 at 17:54 Micah Hainline via swift-evolution <
swift-evolution at swift.org> wrote:

> That's exactly what I'm suggesting, the class declaration could work
> similarly to a closure.
>
> > On Dec 22, 2016, at 4:15 PM, Michael Ilseman <milseman at apple.com> wrote:
> >
> > Are you asking for a class declaration to implicitly capture and extend
> the lifetime of local variables? That seems like something that’s better
> done explicitly. Perhaps it’s better to think about how to reduce the
> boiler plate code, e.g. better default initializers.
> >
> > (this is of course, additive and beyond the current scope of Swift 4
> phase 1 planning)
> >
> >> On Dec 22, 2016, at 2:39 PM, Micah Hainline via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>
> >> Currently we allow declarations of a new class in local scope, but
> >> nothing can be referenced from the outer scope. Thus this is illegal:
> >>
> >> ```
> >> func foo() {
> >>  let widgetString: String = createWidgetString()
> >>  class SimpleProvider: WidgetStringProvider {
> >>     func provideWidgetString() -> String {
> >>        return widgetString // Illegal, defined in outer scope
> >>     }
> >>  }
> >>  doThingsWithWidget(provider: WidgetStringProvider())
> >> }
> >> ```
> >>
> >> I'm trying to feel out the edges of this decision, and figure out why
> >> exactly this isn't allowed now, and how we might want to relax this in
> >> the future if possible. While not a common construct, it is a useful
> >> one.
> >>
> >> Obviously there are ways around it, very simple to create an init and
> >> a private let and do something like this:
> >>
> >> ```
> >> func foo() {
> >>  let widgetString: String = createWidgetString()
> >>  class SimpleProvider: WidgetStringProvider {
> >>     private let widgetString: String
> >>
> >>     init(widgetString: String) {
> >>        self.widgetString = widgetString
> >>     }
> >>
> >>     func provideWidgetString() -> String {
> >>        return widgetString // now legal, references
> >> SimpleProvider.widgetString
> >>     }
> >>  }
> >>  doThingsWithWidget(provider: WidgetStringProvider(widgetString:
> >> widgetString))
> >> }
> >> ```
> >>
> >> That's boilerplate I don't want to write though, as it somewhat
> >> detracts from the readability of the structure. I'm not super
> >> interested in defending the concept of local class definitions itself,
> >> it's already allowed in the language, I'm just interested in the
> >> syntax limitation and where that line might be able to be redrawn.
> >> _______________________________________________
> >> swift-evolution mailing list
> >> swift-evolution at swift.org
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> _______________________________________________
> 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/20161223/70e533ff/attachment.html>


More information about the swift-evolution mailing list