> On Feb 20, 2017, at 3:38 PM, John McCall <rjmcc...@apple.com> wrote: > >> On Feb 20, 2017, at 4:26 PM, Matthew Johnson <matt...@anandabits.com >> <mailto:matt...@anandabits.com>> wrote: >>> On Feb 19, 2017, at 11:24 PM, John McCall <rjmcc...@apple.com >>> <mailto:rjmcc...@apple.com>> wrote: >>> >>>> On Feb 18, 2017, at 11:08 AM, Matthew Johnson <matt...@anandabits.com >>>> <mailto:matt...@anandabits.com>> wrote: >>>> Hi John, >>>> >>>> This is fantastic! I’ve been eagerly anticipating this. It looks very >>>> much as I was hoping it would. I can’t wait to see this vision come to >>>> life! >>>> >>>> You only show a mutating generator example. Do you also plan to allow >>>> shared generators? >>> >>> Yes; a generator yielding a shared reference would be used for non-mutating >>> iteration. >>> >>>> One topic you don’t touch on that feels related is the ability to use RAII >>>> and rely on deferred deinit to ensure an owned resource isn’t released >>>> before the scope exits. I can imagine something like `defer let resource >>>> = MyResource()`. It may also be interesting to support “defer only” types >>>> to force a compiler error where non-deferred use would be incorrect. What >>>> do you think? >>> >>> My intuition is the use cases for this that I'm aware of are really a >>> mis-use of values. You might design an API that way in C++, where >>> destructors are really the only language mechanism for injecting code into >>> a function "later", but in Swift I think you would want to use either (1) a >>> generalized accessor (if the protected resource could meaningfully be >>> described as a single value) or (2) a callback that explicitly scopes what >>> happens with the resource. >>> >>> So e.g. if you wanted a Rust-style mutex API, you could do it like so: >>> >>> moveonly struct Locked<T> { >>> var unlockedMemory: T { // probably not the best name >>> read { >>> mutex.acquire() >>> defer { mutex.release() } // There are reasons why I think this needs >>> to be in a defer, but we can talk about them when we get to the detailed >>> proposals for co-routines. I'm still looking for a better language design. >>> yield actualMemory // Recall that 'read' yields a shared value, so >>> this doesn't implicitly copy. >>> } >>> nonmutating modify { // 'nonmutating' is a misnomer, but it's an >>> existing misnomer. Setters are 'mutating' methods by default and normally >>> demand exclusive access to self, but we don't need that here because we're >>> dynamically enforcing exclusive access to the memory, so all we need is >>> shared access, and this is how we express that. >>> mutex.acquire() >>> defer { mutex.release() } >>> yield &actualMemory >>> } >>> } >>> >>> private var mutex: Mutex >>> private mutable var actualMemory: T // Make this variable mutable even >>> within nonmutating methods; whether that makes sense is the programmer's >>> problem. I didn't cover this in the proposal, because it's speculative, >>> but it's useful for things like our nonmutating modify. Lots of open >>> questions here. >>> } >> >> I like this approach. It scopes access to the resource as necessary without >> requiring nesting. >> >>> >>> Or if you wanted a more C-like mutex API, you'd do it like so: >>> >>> moveonly struct Mutex { >>> func withLock<T>(_ function: () throws -> T) rethrows -> T { >>> acquire() >>> defer { release() } >>> return try function() >>> } >>> } >>> >>> But I just don't see the motivation to try to do this by making a function >>> return a C++-style lock guard. >>> >>> Do you have a use case which clearly benefits from an exact scoping and >>> really needs to be an independent value? >> >> To be honest, I don’t know. The primary thing I am looking for is a way to >> encapsulate the scoping of a resource without requiring the introduction of >> a new lexical scope like is required in your second example. > > Yes, I agree that the nesting isn't ideal. In particular, it's awkward to > get values out of the scope. > >> The first approach you show above using generalized accessors may well be >> able to cover our needs. Thanks for taking time to show the example! > > Okay, glad to hear it. If you *do* find something which really benefits from > an RAII-style value, please let me know; I'm certainly open to the idea.
Will do. I’ll keep this in the back of my mind and we’ll see if anything bubbles to the surface! :) > > John. > >> >>> >>> John. >>> >>>> >>>>> On Feb 17, 2017, at 11:08 AM, John McCall via swift-evolution >>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>> >>>>>> On Feb 17, 2017, at 4:50 AM, Adrian Zubarev >>>>>> <adrian.zuba...@devandartist.com >>>>>> <mailto:adrian.zuba...@devandartist.com>> wrote: >>>>>> Hi John, would you mind creating a markdown document for this manifesto >>>>>> in https://github.com/apple/swift/tree/master/docs >>>>>> <https://github.com/apple/swift/tree/master/docs>? :) >>>>>> >>>>>> >>>>> Yes, it should go in the repository. That commit is pending, but the in >>>>> meantime, you can see the document properly rendered at: >>>>> >>>>> https://github.com/rjmccall/swift/blob/4c67c1d45b6f9649cc39bbb296d63663c1ef841f/docs/OwnershipManifesto.md >>>>> >>>>> <https://github.com/rjmccall/swift/blob/4c67c1d45b6f9649cc39bbb296d63663c1ef841f/docs/OwnershipManifesto.md> >>>>> >>>>> John. >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution