> On Dec 17, 2015, at 7:32 PM, Félix Cloutier <[email protected]> wrote: > > If this can be used as any reference, I wrote some code to help interoperate > with Python in C++.
BTDT; see http://boost.org/libs/python :-) > The Python API inconsistently returns references with a +0 or +1 count. I use > macros called TAKEREF (when the object is returned with a +1 count) and > ADDREF (when it's returned with +0) to create smart wrappers. The wrapper > will always decrement the reference count during destruction. > > I find it unambiguous: you need to add a reference if you're going to take > one away at destruction, so ADD; but if the object is returned with a +1 > count, you can just TAKE the reference. It coincidentally does not borrow > terminology from Objective-C's memory management system. But it does tread on an area we’re trying very hard to clear up in Swift’s use of terminology: what does the word “take” mean? In fact the “take” problem was partly caused by the existing design of Unmanaged. Also, while unambiguous, it’s a very low-level description of what’s happening, that doesn’t much help the user reading the documentation of a CF function to answer the “which one do I use?” question unless s/he’s already experienced with how to map what it says in that docs onto the use of ADDREF/TAKEREF. >> Le 17 déc. 2015 à 21:23:56, T.J. Usiyan via swift-evolution >> <[email protected] <mailto:[email protected]>> a écrit : >> >> I think I see what you mean about parity. `.object` can be called multiple >> times, then? Why not make `release()` slightly more verbose since it should >> only be called once anyway? Something along the lines of >> `.releaseAndReturnObject` or … something slightly less verbose. >> >> My main point of contention with `.release()` is that it has the *exact* >> same name as a method from the MRC strategy. Maybe this is a silly point, >> but this overlap could further complicate teaching how ARC works and in what >> ways it is based on MRC conventions. I am not of the opinion that ARC is >> fundamentally more difficult to understand than MRC, but I do believe that >> it takes a very particular kind of faith now that we don't get to manually >> write the retains and releases. This is completely worth it, in my opinion, >> but I want to avoid making it *more* confusing to explain what ARC doing at >> compile time. >> >> TJ >> >> On Thu, Dec 17, 2015 at 9:13 PM, Dave Abrahams <[email protected] >> <mailto:[email protected]>> wrote: >> Thanks very much for the quick feedback TJ, >> >>> On Dec 17, 2015, at 5:52 PM, T.J. Usiyan <[email protected] >>> <mailto:[email protected]>> wrote: >>> >>> Hello Dave, >>> >>> I like this change and think that it will help clarify the purpose of the >>> type. As I was reading, the only concern that I had was the name. Could you >>> please provide some of the names that you all have considered >> >> Honestly, I am sorry to say, we did that exercise almost a month ago and I >> don’t remember the ones we discussed. >> >>> so that we can avoid suggesting the same things? My suggestion is >>> >>> CFSomething(arguments…).retainedObject() // when the result is returned >>> at +1 >>> >>> or >>> >>> CFSomething(arguments…).unretainedObject() // when the result is >>> returned at +0 >>> >>> on the premise that the important bit of information is whether or not the >>> object is already retained. No matter what names are chosen, that is the >>> data which determines which method to call. `retainedObject | >>> unretainedObject`, `takeRetainedObject | takeUnretainedObject`, or >>> `retained | unretained` all seem like viable options (that you have >>> probably considered). >> >> >> Some issues with these names: >> >> The “ed/ing” rule >> <https://swift.org/documentation/api-design-guidelines.html#be-grammatical> >> makes these names suggest that the accessors are idempotent, but the first >> one must be called exactly once. That name should really be an active verb >> since it is state-changing. >> “retainedObject” also suggests that it’s returning some underlying object >> after retaining it, which is almost the opposite of what that API does… and >> vice-versa for “unretainedObject" >> Also, the object “has been retained” in all cases, or it would have been >> deallocated. The question is whether the object would leak if we fail to >> call release on it >> Nothing in these names connect them to what the documentation says about the >> functions that return Unmanaged, so it’s hard to know which one to call >> The second API is objectively safer than the first one (which causes >> undefined behavior when overused and only leaks when underused). The API I >> proposed makes it clear that they are not peers, where yours implies >> parity—though I am of two minds about the value of representing the lack of >> parity. >> >> You may legitimately argue that any of these concerns are unimportant, but >> those are the ones that come up for me. >> >>> TJ >>> >>> >>> On Thu, Dec 17, 2015 at 8:37 PM, Dave Abrahams via swift-evolution >>> <[email protected] <mailto:[email protected]>> wrote: >>> Hi Everybody, >>> >>> We’ve been working on a rewrite of the Unmanaged<T> component, and are >>> soliciting comments. First, a little background: >>> >>> Unmanaged >>> <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID79> >>> is primarily used as a return type from imported CoreFoundation functions >>> that haven’t been annotated with reference-counting semantic information >>> A secondary known use-case is as a vehicle for creating a COpaquePointer >>> containing a reference’s bits, e.g. for when you need to pass a reference >>> through C APIs that use “void*” as a universal “give me some info and I’ll >>> give it back to your callback” mechanism. >>> >>> We saw several problems with Unmanaged that we wanted to fix: >>> It was poorly-named (the reference is managed by somebody, we just aren't >>> representing that management in the type system). >>> Its interface was much broader than it needs to be to cover the use-cases >>> The purpose of many of its APIs was unclear >>> Its documentation was vague and hard to understand. >>> It didn’t establish a maximally-safe usage pattern for handling the results >>> of un-annotated CoreFoundation functions. >>> >>> The code for the proposed replacement, called UnsafeReference, is here >>> <https://github.com/dabrahams/swift/blob/6eb86b48d150342709da3f3be9c738df23382866/stdlib/public/core/UnsafeReference.swift>, >>> and a commit that updates Swift to use it is here >>> <https://github.com/dabrahams/swift/commit/6eb86b48d150342709da3f3be9c738df23382866>. >>> >>> >>> Maximally Safe Usage >>> >>> The recommended usage pattern for handling an UnsafeReference<T> returned >>> by a function CFSomething is to always use the T instance produced by one >>> of the forms: >>> >>> CFSomething(arguments…).release() // when the result is returned at +1 >>> >>> or >>> >>> CFSomething(arguments…).object // when the result is returned at +0 >>> >>> In other words, turn the UnsafeReference<T> into a safe T as quickly as >>> possible, and never store the UnsafeReference<T> in a variable so that it >>> can’t be (mis)used thereafter. >>> >>> Points of Discussion >>> >>> We’re interested in any feedback you might have, but there are a few points >>> we’d especially like to address: >>> >>> The name of the release() method has been contentious. >>> 👍: Documentation—or naming conventions such as the “create rule >>> <https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html>”—normally >>> says something like “you are responsible for releasing the result” in >>> those cases where release() must be called, so there’s a very direct way to >>> know which variant of the recommended usage pattern to employ. >>> 👎: Some people who are very familiar with existing manual retain/release >>> programming find the recommended usage pattern really counter-intuitive >>> because they're “using something after calling release on it,” which one >>> never does in Objective-C. >>> The alternative names we’ve been able to think of so far are verbose, >>> clumsy, and don’t match up with anything in the documentation of the called >>> function, so this seems like a really hard naming problem. Better ideas >>> from the community would be most welcome here. >>> 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. >>> We want to know whether the usage pattern recommended above works for you. >>> 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. >>> >>> Thanks in advance, >>> >>> -Dave >>> >>> >>> >>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] <mailto:[email protected]> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> >>> >> >> -Dave >> >> >> >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] <mailto:[email protected]> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> -Dave
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
