[Review] SE-0055 Make unsafe pointer nullability explicit using Optional


(Anton Zhilin) #1

UnsafePointer is most often used for interfacing with C libraries. They
will almost never add nullability annotations. It means that
UnsafePointer<Type>? will become an idiom. But we currently have a terser
form, and it's arguably clear from it that Pointer can be null.

90% of programmers and 99.9% of those working with C libraries are familiar
with concept of C pointer and null pointer. So it's clear for every one we
can call a programmer that *Pointer types contain plain C nullable pointers
with Swift whistles.

Overall, separating strongly connected concepts and then tying them
together using compiler magic just can't have a reasonable explanation.
~0x0 in UnsafeBufferPointer is utterly rediculous.

What is your evaluation of the proposal?

-1

Is the problem being addressed significant enough to warrant a change to

Swift?
No, I don't see any motivation for the change.

Does this proposal fit well with the feel and direction of Swift?

No, it's headed in the opposite direction.

If you have you used other languages or libraries with a similar feature,

how do you feel that this proposal compares to those?
Rust denotes pointers using * and has no problems with that.

How much effort did you put into your review? A glance, a quick reading,

or an in-depth study?
Followed the discussion.


(Jordan Rose) #2

But we currently have a terser form, and it's arguably clear from it that Pointer can be null.

For the record, I literally talked to someone last week who didn't know that UnsafePointer can be null. :slight_smile: They thought we'd already implemented this and there was a bug in the importer.

Overall, separating strongly connected concepts and then tying them together using compiler magic just can't have a reasonable explanation. ~0x0 in UnsafeBufferPointer is utterly rediculous.

I'm not sure what this comment refers to. Can you explain?

Jordan

···

On Mar 26, 2016, at 9:15, Антон Жилин via swift-evolution <swift-evolution@swift.org> wrote:


(Anton Zhilin) #3

UnsafeBufferPointer is currently represented as a (nullable) C pointer plus
size. It can be implemented almost in pure Swift (with calls to C
functions).

After the proposal is accepted, it will be replaced with
Optional<UnsafeBufferPointer>. But it will require a compiler-only "hack"
for Optional not to require extra memory for nil (I assume, Optional will
look into address part of UnsafeBufferPointer). This symbiosis will have to
be built in the compiler, and I call that "compiler magic".

The need for such magic is an argument for unified UnsafeBufferPointer to
be more "natural". I'm not going to say that this argument will seem strong
for everyone, though.

For that last statement, I was trying to say that we wouldn't need to
invent special value for "empty" UnsafeBufferPointer if we left everything
as it is now.

Also I agree that this change will be positive for use of *Pointer strictly
inside Swift. It is mainly interaction with C that will become more verbose.

···

2016-03-28 20:45 GMT+03:00 Jordan Rose <jordan_rose@apple.com>:

On Mar 26, 2016, at 9:15, Антон Жилин via swift-evolution < > swift-evolution@swift.org> wrote:

But we currently have a terser form, and it's arguably clear from it that
Pointer can be null.

For the record, I literally talked to someone last week who didn't know
that UnsafePointer can be null. :slight_smile: They thought we'd already implemented
this and there was a bug in the importer.

Overall, separating strongly connected concepts and then tying them
together using compiler magic just can't have a reasonable explanation.
~0x0 in UnsafeBufferPointer is utterly rediculous.

I'm not sure what this comment refers to. Can you explain?

Jordan


(Jordan Rose) #4

Thank you for elaborating on your concerns! Some responses below.

UnsafeBufferPointer is currently represented as a (nullable) C pointer plus size. It can be implemented almost in pure Swift (with calls to C functions).

After the proposal is accepted, it will be replaced with Optional<UnsafeBufferPointer>.

That is not the proposal; please re-read the section on UnsafeBufferPointer. <https://github.com/apple/swift-evolution/blob/master/proposals/0055-optional-unsafe-pointers.md#unsafebufferpointer> (You might not be happy with this version either, though.)

But it will require a compiler-only "hack" for Optional not to require extra memory for nil (I assume, Optional will look into address part of UnsafeBufferPointer). This symbiosis will have to be built in the compiler, and I call that "compiler magic".

This is actually standard behavior for all enum types (guaranteed) and all struct types whose first property is such an enum or built-in type with available "extra inhabitants" (an optimization whose details may change in the future). This includes structs beginning with a non-optional AnyObject, and enum types you define like this:

enum Maybe<T> {
  case just(T)
  case nothing
}

If 'T' is a type that has a known invalid representation, such as AnyObject, that representation will be used for the 'nothing' case of 'Maybe<T>'

Best,
Jordan

···

On Mar 28, 2016, at 11:09, Антон Жилин <antonyzhilin@gmail.com> wrote: