> On Aug 19, 2017, at 6:16 PM, Taylor Swift <kelvin1...@gmail.com> wrote:
> 
> What you’re describing is basically an earlier version of the proposal which 
> had a slightly weaker precondition (source >= destination) than yours (source 
> == destination). That one basically ignored the Sequence methods at the 
> expense of greater API surface area.

The Sequence methods don’t provide the simpler, more convenient form of 
initialization/deinitialization that I thought you wanted. I see two reasonable 
options.

1. Don’t provide any new buffer initialization/deinitialization convenience. 
i.e. drop UsafeMutableBufferPointer moveInitialize, moveAssign, and 
deinitialize from your proposal.

2. Provide the full set of convenience methods: initialize, assign, 
moveInitialize, and moveAssign assuming self.count==source.count. And provide 
deinitialize() to be used only in conjunction with those new initializers.

The question is really whether those new methods are going to significantly 
simplify your code. If not, #1 is the conservative choice. Don't provide 
convenience which could be misused. Put off solving that problem until we can 
design a new move-only buffer type that tracks partially initialized state.

-Andy 

> On Sat, Aug 19, 2017 at 9:08 PM, Andrew Trick <atr...@apple.com 
> <mailto:atr...@apple.com>> wrote:
> 
>> On Aug 19, 2017, at 6:03 PM, Taylor Swift <kelvin1...@gmail.com 
>> <mailto:kelvin1...@gmail.com>> wrote:
>> 
>> 
>> 
>> On Sat, Aug 19, 2017 at 8:52 PM, Andrew Trick <atr...@apple.com 
>> <mailto:atr...@apple.com>> wrote:
>>>> 
>>>> The problem is I would expect to be able to safely call deinitialize() and 
>>>> friends after calling initialize(from:). If Element is a class type and 
>>>> initialize doesn’t fill the entire buffer range, calling deinitialize() 
>>>> will crash. That being said, since copy(from:bytes:) and copyBytes(from:) 
>>>> don’t do any initialization and have no direct counterparts in 
>>>> UnsafeMutableBufferPointer, it’s okay if they have different behavior than 
>>>> the other methods.
>>> 
>>> You astutely pointed out that the UnsafeMutableBufferPointer.deinitialize() 
>>> method is dangerous, and I asked you to add a warning to its comments. 
>>> However, given the danger, I think we need to justify adding the method to 
>>> begin with. Are there real use cases that greatly benefit from it?
>>> 
>>> I agree that’s a problem, which is why i was iffy on supporting partial 
>>> initialization to begin with. The use case is for things like growing 
>>> collections where you have to periodically move to larger storage. However, 
>>> deinitialize is no more dangerous than moveInitialize, 
>>> assign(repeating:count:), or moveAssign; they all deinitialize at least one 
>>> entire buffer. If deinitialize is to be omitted, so must a majority of the 
>>> unsafe pointer API.
>> 
>> Here's an alternative. Impose the precondition(source.count == self.count) 
>> to the following UnsafeMutableBufferPointer convenience methods that you 
>> propose adding:
>> 
>> +++ func assign(from:UnsafeBufferPointer<Element>)
>> +++ func assign(from:UnsafeMutableBufferPointer<Element>)
>> +++ func moveAssign(from:UnsafeMutableBufferPointer<Element>)
>> +++ func moveInitialize(from:UnsafeMutableBufferPointer<Element>)
>> +++ func initialize(from:UnsafeBufferPointer<Element>)
>> +++ func initialize(from:UnsafeMutableBufferPointer<Element>)
>> 
>> I don't that introduces any behavior that is inconsistent with other 
>> methods. `copyBytes` is a totally different thing that only works on trivial 
>> types. The currently dominant use case for UnsafeBufferPointer, partially 
>> initialized backing store, does not need to use your new convenience 
>> methods. It can continue dropping down to pointer+count style 
>> initialization/deinitialization.
>> 
>> -Andy
>>  
>> the latest draft does not have 
>> assign(from:UnsafeMutableBufferPointer<Element>) or  
>> initialize(from:UnsafeMutableBufferPointer<Element>), it uses the generic 
>> Sequence methods that are already there that do not require that 
>> precondition.
> 
> Sorry, I was pasting from your original proposal. Here are the relevant 
> methods from the latest draft:
> 
> https://github.com/kelvin13/swift-evolution/blob/1b7738513c00388b8de3b09769eab773539be386/proposals/0184-improved-pointers.md
>  
> <https://github.com/kelvin13/swift-evolution/blob/1b7738513c00388b8de3b09769eab773539be386/proposals/0184-improved-pointers.md>
> 
> +++ func moveInitialize(from:UnsafeMutableBufferPointer<Element>)
> +++ func moveAssign(from:UnsafeMutableBufferPointer<Element>)
> 
> But with the precondition, the `assign` method could be reasonably added 
> back, right?
> +++ func assign(from:UnsafeMutableBufferPointer<Element>)
> 
> Likewise, I don’t have a problem with initialize(from: UnsafeBufferPointer) 
> where self.count==source.count. The Sequence initializer is different. It’s 
> designed for the Array use case and forces the caller to deal with partial 
> initialization. 
> 
> UnsafeMutableRawBufferPointer.moveInitializeMemory on the other hand probably 
> doesn't need that precondition since there's no way to deinitialize. It just 
> needs clear comments.
> 
> -Andy
> 

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to