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

Dave Abrahams dabrahams at apple.com
Sat Dec 19 17:14:52 CST 2015

> On Dec 19, 2015, at 2:59 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
>>> CFAttributedString has actually been audited, but pretend it hasn't been...
>>> 	let attributedString = CFAttributedStringCreate(nil, anotherString,nil).takeCreatedObject()
>>> 	let str = CFAttributedStringGetString(attributedString).takeRetrievedObject()
>>> I'm not a huge fan of the "take" here,
>> Then why did you use it, if you don't mind my asking?  What is it supposed to mean in this context?
> I suppose I'm struggling with the fact that there's clearly an action taking place here (at least in the created case), and yet merely saying `createdObject()` or `retrievedObject()` doesn't imply that. Those operations sound idempotent, but they're not.

But you applied "take" to both of them?  One of them is idempotent while the other is not.

> (I kind of want to suggest that retrieving an object through these calls should destroy the reference so it can't be used again, but I don't think that fits with Swift's mutation model without turning `Unmanaged`/`UnsafeReference` into a reference type and adding lots of overhead.)

Yes, there's no way to reconcile that with the safety offered by the recommended usage patterns, since you can't mutate an rvalue.

>>> but I think this general strategy of trying to say whether the Create Rule or the Get Rule applies is better than trying to make people understand when they should use "released" or not.
>> Why is that better?
> Mainly, because simply saying "release" or "released" is a bit ambiguous to me.Are you saying it *has been* released, or are you saying it *needs to be* released?

But nobody proposed "released" as a method name.  In what way is "release" ambiguous?  It's an imperative verb.

> I have the same problem with the current `takeRetainedValue()`/`takeUnretainedValue()` calls—I'm never sure which one I'm supposed to use. I'm hoping that, by stepping up a level and describing the semantic you want rather than the operation needed to achieve that semantic, this confusion can be cleared up.
> I also like that this creates a matched pair of methods. Because they look sort of like each other, it's easier to understand that you should call one or the other, and to remember them.

The similarity of those names seems to me like a weakness of the current Unmanaged design: to me they are so similar it's hard to understand which one to call.

>> And how does "Retrieved" map onto "Get"?
> Not all that cleanly, I admit. "Gotten" would be better, but "get" is an irregular verb and I'm a little concerned about programmers who have English as a second language. (Plus, I subjectively think it's kind of ugly.)
> (One possibility would be to have a single call with an enum parameter, like `bridge(.Create)` and `bridge(.Get)`. This would let you use the regular form of the verb.)

There's no "bridging" going on here, though.  This is simply "turn this unsafe thing into a safe thing in one of two ways"

>> Isn't it the users of the functions that don't contain "Create" or "Get" in their names that need the most help?
> I think of it more as "treat this like a Create function" or "treat this like a Get function".

So far, my personal assessment of this direction is that it's no better than what I proposed, and has several weaknesses I'd like to avoid.  In fact, it seems very similar to and roughly as understandable as the current Unmanaged design.  I recognize that this is a highly subjective judgement, so if others disagree with me, I'd really like to hear about it.  This is a tough design space and ultimately, what resonates best with the community is likely to be the best choice.

Thanks again,


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

More information about the swift-evolution mailing list