> 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

Reply via email to