[swift-evolution] SE-0138 UnsafeBytes

Andrew Trick atrick at apple.com
Fri Sep 2 19:14:35 CDT 2016

> On Sep 2, 2016, at 11:14 AM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> on Thu Sep 01 2016, Andrew Trick <swift-evolution at swift.org> wrote:
>> I’m resending this for Review Manager Dave A. because the announce list is dropping his messages...
>> Hello Swift community,
>> The review of "UnsafeBytes" begins now and runs through September
>> 7th. This late addition to Swift 3 is a follow-up to SE-0107:
>> UnsafeRawPointer. It addresses common use cases for UnsafeRawPointer,
>> allowing developers to continue working with collections of UInt8 values,
>> but now doing so via a type safe API. The UnsafeBytes API will not require 
>> direct manipulation of raw pointers or reasoning about binding memory.
>> The proposal is available here:
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0138-unsafebytes.md <https://github.com/apple/swift-evolution/blob/master/proposals/0138-unsafebytes.md>>
>> * What is your evaluation of the proposal?
> I strongly support inclusion of the feature, but I have issues with the

Clearly, otherwise you wouldn't have announced it 4 times ;)

> name.  It seems to me that in order to fit into the standard library, it
> should be called Unsafe[Mutable]RawBufferPointer.  Each part of the name

Well, that's natural from a stdlib designer's viewpoint. It is almost
identical functionality, but it also exposes the UnsafeRawPointer API
for loading and storing arbitrary types. This naming issue was
discussed for a couple weeks on swift-evolution. Let's see if I can
recap inline with your comments.

> conveys something important, and for the same reasons we're using
> Unsafe[Mutable]BufferPointer instead of UnsafeMutableElements, we should
> stick to the scheme:
> - “Unsafe,” because you can break memory safety with this tool

OK. Let's not drop that one!

> - “Raw,” because the fundamental model is that of “raw,” rather than
>  “typed,” memory.

To me, bytes only exist in memory. Accessing a byte, as opposed to some
in-memory type, is always a raw access.

> - “Buffer,” because it works on a series of contiguous elements of known
>  length.

To me, bytes always represent a contiguous chunk of raw memory. The
term implies that we're dealing with memory layout, as opposed to just
some opaque chunk of data, which is I think what Foundation Data is for.

> - “Pointer,” because it has reference semantics!  When you pass one of
>  these things around by value, you're not passing the bytes; you're
>  passing a shared reference to the bytes.

Unsafe means that this value doesn't own the memory. I agree with you
that reference semantics are important, and we need to clearly
distinguished this from something like Data. I just think Unsafe is
enough for the name.

UnsafeMutableRawBufferPointer does not actually convey that it can be
viewed as a collection of 8-bit values, which is fairly important.

Now that I've satisfied my pedantic side, let's look at it from the developer's side.
To me it's a question of whether a longer or shorter name is more meaningful in
the natural setting of users' source code:

func foo(bytes: UnsafeMutableRawBufferPointer)

withUnsafeMutableRawBufferPointer(to: &header) {
  foo(bytes: $0)
func foo(bytes: UnsafeMutableBytes)

withUnsafeBytes(of: &header) {
  write(bytes: $0)

I don't think the longer name is more descriptive. I do think the
shorter name is more intuitive and meaningful.

UnsafeMutableRawPointer is already too long to be recognizable to
users. A benefit of UnsafeBytes is that the most developers won't need
to know how to work directly with raw pointers. So the name doesn’t
need to evoke them.


More information about the swift-evolution mailing list