[swift-evolution] RFC: Proposed rewrite of Unmanaged<T>

Janosch Hildebrand jnosh at jnosh.com
Fri Dec 18 20:18:39 CST 2015

I like `UnsafeReference` as the new name of the type and I think the basic API is clearer than with `Unmanaged`.
The initializers are much better than the static methods and `take(Un)RetainedValue()` were certainly less than ideal method names.

> On 18 Dec 2015, at 02:37, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> The name of the release() method has been contentious.

This is a hard one. I don't particularly like `release()` for this but I can't really think of anything better either.
I think it's descriptive which is good but it will take some getting used to as the "consuming" method although the documentation is pretty clear about the semantics which is helpful.

The `.releaseAndReturnObject` proposed by TJ feels a bit clearer but is also a lot more verbose.
Also I don't think it would make anything clearer if I didn't already know about the manual memory management terminology.
And something along these lines would also be bit more awkward to use if the return values were then discarded, although the proposed `manuallyRelease()` would take care of that...

> We’re not sure about the terminology <https://github.com/dabrahams/swift/blob/6eb86b48d150342709da3f3be9c738df23382866/stdlib/public/core/UnsafeReference.swift#L27> (Unretained/Retained/Released) used to precisely describe the semantics of UnsafeReference. We’d like to know if these terms make sense to you or whether you have better ideas.

Coming from Objective-C I find it makes sense. I also don't think the terminology is a big issue here. If you know the concepts you're probably able to map them to these terms and the documentation seems helpful in that case.

If, on the other hand, you are not familiar with manual reference counting concepts I doubt this will be very helpful.
But I don't think that can be solved with different terminology but instead requires more extensive documentation.
However I don't think the documentation for `UnsafeReference` is the place to try to explain the whole concept and this is more of a topic for `The Swift Programming Language` or a separate (advanced) tutorial or guide.

I like that the documentation tries to lay out a clear path to follow if you just want to get an object out of some un-annotated CF API but I can't really personally judge how well that works for a novice.

One other approach to terminology that comes to mind would be to focus more on the transfer of ownership into ARC as opposed to out of MRC.
Personally I often reason in that direction when thinking about the topic but I can't see a way in which it would be helpful for the documentation or method names...

> We want to know whether the usage pattern recommended above works for you.

For interacting with un-annotated CF APIs: Yes.

> We want to know if the API is sufficiently broad or if there are things you currently get—and need—from Unmanaged that we’ve left out.

> On 18 Dec 2015, at 03:05, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
> - `Unmanaged` has also been promoted as a solution for people who need to do manual reference counting, for performance or other reasons, so I think we might want to keep the 'retain()' method. Conveniently enough, `release()`-ing and dropping the return value would have the net effect of decrementing the refcount by one, though the admonitions about the `UnsafeReference` become invalid after that point wouldn't hold if you're using `release()` purely for that effect, so maybe `manuallyRetain()`/`manuallyRelease()` would be more appropriate for manual refcounting applications.

As Joe mentioned, `Unmanaged` has a use for manual ref counting beyond immediate transfer from un-annotated APIs. 

I have used it for performance reasons myself (~ twice) and while I think it's a pretty small use case there isn't really any alternative.
If it would help I can also describe my use-cases in more detail.

I don't think this use case even needs to be described in the documentation for `UnsafeReference` and it's fine if its use is very much discouraged.

Personally I prefer the proposed `manuallyRetain()`/`manuallyRelease()` over plain `retain()`/`release()` as it clearly separates the returning and more generally applicable `release()` from the MRC methods. `retain()` would probably also have to return the object which would interfere with the max safe usage pattern.

> On 18 Dec 2015, at 03:05, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
> - The `bitPattern:` constructors should be between UnsafeReference and Unsafe[Mutable]Pointer<Void>, not COpaquePointer. Let COpaquePointer retire gracefully.

Very much agreed.

- Janosch

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151219/44e345d1/attachment.html>

More information about the swift-evolution mailing list