The point here is that the escape of the inner value necessitates the (implicit) escape of the outer captured value. That's something closures don't have to deal with.
~Robert Widmann 2016/12/24 13:13、Callionica (Swift) <[email protected]> のメッセージ: > I may be missing your point about lifetime extension problems. How would > lifetime extension be different for captures by classes than for captures by > function closures? > >> On Sat, Dec 24, 2016 at 12:00 PM Robert Widmann <[email protected]> >> wrote: >> That still doesn't answer the lifetime extension problems. What is being >> described here is a complex extension to the lifetime of memory that is only >> being kept alive because of these implicit captures. It sounds like what >> you want is a member, and I'm not sure it's worth saving 5 lines to avoid >> that fact. >> >> ~Robert Widmann >> >> 2016/12/24 11:45、Callionica (Swift) via swift-evolution >> <[email protected]> のメッセージ: >> >>> Missed swift-evol in my reply >>> >>> ---------- Forwarded message --------- >>> From: Callionica (Swift) <[email protected]> >>> Date: Sat, Dec 24, 2016 at 9:44 AM >>> Subject: Re: [swift-evolution] Should we relax restriction on closing over >>> outer scope in class declarations? >>> To: Robert Widmann <[email protected]> >>> >>> >>> These are good questions. >>> >>> I believe Swift closures currently do implicit self-capture. I wouldn't >>> expect that behavior to be different when capturing for classes. >>> >>> If a class needs to refer to an outer self, I would expect the user to have >>> to give the outer self a new name by assigning to a local. Same deal for >>> referring to members in an outer class where there are members of the same >>> name in the inner class: assign outer self to a local and refer to members >>> through that local. >>> >>>> On Fri, Dec 23, 2016 at 10:16 AM, Robert Widmann >>>> <[email protected]> wrote: >>>> >>> >>>> On Dec 23, 2016, at 1:10 AM, Callionica (Swift) via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> I'm certainly assuming that users have a basic understanding of scope >>>> (without that, what would be the intention behind defining the class >>>> within the function?). >>>> >>> >>> Despite its simplicity to you (given the example you’ve cited) this feature >>> is quite an advanced extension to the current scoping rules. >>> >>>> I'm not clear on what you see as the downside of letting classes capture >>>> locals for users that are unaware of capturing. >>>> >>> >>> I’ll be blunt: This opens a gaping hole in the semantics of variable >>> lifetimes and potentially introduces an ambiguity into resolution of the >>> `self` keyword. For the former, consider a light extension to your >>> original example that introduces a nested class: >>> >>> class Outer { >>> let widgetString: String = createWidgetString() >>> >>> // Initializer suppressed >>> func foo() -> WidgetStringProvider { >>> class SimpleProvider: WidgetStringProvider { >>> // Initializer suppressed >>> func provideWidgetString() -> String { >>> return widgetString >>> } >>> } >>> return SimpleProvider() >>> } >>> } >>> >>> Now, from SIL’s point of view, widgetString must escape the scope it’s in >>> and its lifetime should be extended beyond this block. Fine. But what >>> about Outer? Because we’re returning a reference to SimpleProvider which >>> escapes the scope of foo(), and instance members of a SimpleProvider >>> capture outer context, this means we also have to keep Outer alive and >>> around for destruction (perhaps at the point where SimpleProvider is >>> destroyed?) >>> >>> For the latter consider trying to explicitly reference widgetString here. >>> In provideWidgetString() we close over self in both foo() and >>> provideWidgetString(). So, if I wish to make reference to Outer’s self >>> explicitly, how would I go about doing it? Given that today a nested >>> aggregate can have members with the same identifiers as their parent, how >>> do we know if we’re capturing them or not when they’re referenced in the >>> inner aggregate? >>> >>> ~Robert Widmann >>> >>>> On Thu, Dec 22, 2016 at 11:26 PM Xiaodi Wu <[email protected]> wrote: >>>> Only if you're also assuming that people defining classes within functions >>>> would know about capturing. This violates the principle of progressive >>>> disclosure, since people naturally learn about functions and classes >>>> before they learn about closures and capturing. >>>> >>>> >>>> On Fri, Dec 23, 2016 at 01:51 Callionica (Swift) >>>> <[email protected]> wrote: >>>> Assuming capture were allowed, people defining classes within functions >>>> who didn't want them to capture could position the class definition prior >>>> to any other code in the function so that there would be nothing to >>>> capture. >>>> >>>> On Thu, Dec 22, 2016 at 4:13 PM Xiaodi Wu via swift-evolution >>>> <[email protected]> wrote: >>>> 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 >>>> <[email protected]> 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 <[email protected]> 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 >>>> >> <[email protected]> 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 >>>> >>>> >>>> >> [email protected] >>>> >>>> >>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> >>>> >>>> > >>>> >>>> >>>> _______________________________________________ >>>> >>>> >>>> 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 >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> 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
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
