[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.

-Andy


More information about the swift-evolution mailing list