On Tue, Aug 22, 2017 at 2:00 AM, Taylor Swift via swift-evolution < swift-evolution@swift.org> wrote:
> > > On Mon, Aug 21, 2017 at 11:09 PM, Andrew Trick <atr...@apple.com> wrote: > >> >> On Aug 20, 2017, at 6:03 PM, Taylor Swift <kelvin1...@gmail.com> wrote: >> >> New draft of the proposal is up here: <https://github.com/kelvin13/s >> wift-evolution/blob/patch-3/proposals/0184-improved-pointers.md> >> >> Important changes start here >> <https://github.com/kelvin13/swift-evolution/blob/patch-3/proposals/0184-improved-pointers.md#proposed-solution> >> . >> >> >> I have more feedback for you after discussing with Ben and Michael. >> >> Under the section "Background". The retaining/releasing counts are >> confusing because we normally talk about "+0/+1" with respect to a single >> value. Here you're summing the reference count effect across different >> source and destination values. I think you can drop the -1/+0/+1 from the >> cell labels and just label the headers as "Source-Copy(+1) vs. >> Source-Move(+0)" and "Dest-Initializing(+0)" vs. "Dest-Destroying(-1)". >> > > I got rid of the total counts, but I used “retaining” and “releasing” > because the word “initialize” is already way overloaded in the document and > using it as a category in addition to referring to the actual method family > `initialize` and `initializeMemory` and Swift’s `init` initializers would > just get too confusing. > > >> >> Ben noticed that we still don't have >> `UnsafeMutableBufferPointer.deallocate()`. >> Please add that as well. >> > > This is in the implementation and 2/3 of the API mocks; idk why it was > lost in the detailed changes section. That was a typo I just fixed it > > >> I think you should also add the default `alignedTo:Int = >> MemoryLayout<UInt>.alignment` to `UnsafeRawMutablePointer`. It is >> effectively part of Swift's memory model... [Background: We're providing a >> language level default guarantee of word-aligned storage. We don't want to >> expose the platform's default alignment. There is no such thing as a >> "maximal" alignment for all imported primitive types. We expect allocators >> to typically provide 16-byte alignment, but when developers are relying on >> that for correctness, we want it to be explicit. Developers usually rely on >> word alignment so there's no value in making that explicit.] >> > > done and committed > > >> >> The source breaking changes can be marked deprecated for now, but can >> only be marked unavailable in Swift 5 mode or later. >> > > done and committed > > >> >> We anticipate adding a ContiguouslyStored protocol "soon", which could be >> used to reduce the amount of overloading on the buffer >> `initialize`/`assign` APIs. But we need a lot more time to iterate on that >> design and it doesn't appear that migrating to it would be source breaking >> w.r.t. your proposal. >> >> I think we would be receptive to a "non-Optional baseAddress" proposal >> now if you or anyone else wants to pitch that. I know Dave Abrahams had a >> working implementation at some point. That would weaken some of the >> incentive to continue adding more convenience to buffer slices. >> > > Really early versions of this proposal pitched that but it didn’t go so > well. also making baseAddress nonnillable means you don’t always have > access to `count` when `count == 0` > > >> >> Sorry to bring this up again, but I was not able to defend the addition >> of `UnsafeMutableBufferPointer.deinitialize()`. It is incorrect for the >> typical use case and doesn't appear to solve any important use case. The >> *only* fully initializing method is `initialize(repeating:)`, but that will >> usually be used for trivial values, which should not be deinitialized. It's >> preferable for the user to explicitly deinitialize just the segments that >> they know were initialized, which can be done on the base pointer. The only >> benefit in having a `deinitialize` on the buffer is to communicate to users >> who see the `initialize` API for the first time that it is their >> responsibility to deinitialize if the type requires it. To that end, we >> could add a `deinitialize(at:count:)` method, communicating the symmetry >> with `initialize(at:from:). Naturally `index + count <= self.count`. >> >> -Andy >> > > I don’t agree with this. If `deinitialize()` is a problem because it > deinitializes the entire buffer, so are `moveAssign` and `moveInitialize`. > They all assume the released buffer operand is fully initialized. ` > deinitialize()` has just as much use as the other full-buffer releasing > methods. Just take the image buffer example there > > let pixels:Int = scanlines.map{ $0.count }.reduce(0, +)var image = > UnsafeMutableBufferPointer<Pixel>.allocate(capacity: pixels) > var filled:Int = 0for scanline:UnsafeMutableBufferPointer<Pixel> in scanlines > { > image.moveInitialize(at: filled, from: scanline) > filled += scanline.count > } > > image.deinitialize() > image.deallocate() > > and replace `Pixel` with a class type like `UIButton`. > > And `deinitialize(at:count:)` is bad because you’re asking for a count on > a buffer method. `moveAssign` and `moveInitialize` can take range > parameters because they each have a second operand that supplies the count > number. `deinitialize` doesn’t. That means calls could end up looking > like > > buffer.deinitialize(at: 0, count: buffer.count) > > which is exactly what we were trying to avoid in the first place. > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > > I’m actually gonna add to this and say it’s by design. A theme in this proposal is the “initialize many times, deinitialize once” pattern. Every operation that involves decrementing a reference count (except copy-assignment because the decrement is glued with an increment) does so on an entire buffer (repeating-assignment, move-assignment, move-initialization). Every operation that involves incrementing a reference count (except repeating-initialization and repeating-assignment because they’re length-less) does so on a segment of a buffer (copy-assignment, move-assignment, move-initialization, copy-initialization). It matches up with real use patterns where you build up Collections in stages, and destroy them at once.
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution