RFC: Proposed rewrite of Unmanaged<T>


(Rainer Brockerhoff) #1

OK, guess I qualify as "steeped" there - I still use MRC in all my
shipping apps, although I've tentatively used ARC in small fry like
build-time utilities. (Never got used to GC.)

Anyway, much of my code looks like one of these patterns:

// 1
NSDictionary* dict = [(id)CFCreateSomeCFDictionary() autorelease];
... use dict for some lines, done

// 2
NSArray* array = (NSArray*)CFGetSomeCFArray();
... use array for some lines, done

// 3
NSString* str = (NSString*)CFCreateSomeCFString();
... use str for some lines
[release str];

One thing about my not migrating to ARC is that I find the bridging cast
names opaque - can't memorize them! Same, sadly, was true for the
Umanaged<T> methods.

So I'd say, use `.release` or `.autorelease` if they'd be used in the
same place as above...

···

On 18/12/15 16:46 , swift-evolution-request@swift.org wrote:

Date: Fri, 18 Dec 2015 11:38:31 -0800
From: Dave Abrahams <dabrahams@apple.com>
Subject: Re: [swift-evolution] RFC: Proposed rewrite of Unmanaged<T>
Message-ID: <E82AADA9-F4A4-4E4E-98C3-6E9A3CEC4D12@apple.com>

> On Dec 17, 2015, at 6:23 PM, T.J. Usiyan <griotspeak@gmail.com> wrote:

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

Well, unsafeRef.release() is equivalent to

  {
    let x = $0.object
    CFRelease($0) // if CFRelease() wasn't @unavailable
    return x
}(unsafeRef)

If you let the return value drop on the floor, it ends up being
exactly equivalent to the method with the exact same name from the
MRC strategy. So the correspondence is strong and shouldn’t be a
problem. That’s just my opinion, though, and part of the reason
we’re asking for feedback here is so people steeped in MRC like you
can argue with me about that :-), so if you find this unconvincing
please explain why.

--
Rainer Brockerhoff <rainer@brockerhoff.net>
Belo Horizonte, Brazil
"In the affairs of others even fools are wise
In their own business even sages err."
http://brockerhoff.net/blog/


(TJ Usiyan) #2

Would `consumeReleased` work at all? It captures the 'don't use this again'
aspect and 'release' without much extra.

···

On Sat, Dec 19, 2015 at 7:45 PM, Rainer Brockerhoff via swift-evolution < swift-evolution@swift.org> wrote:

On 18/12/15 16:46 , swift-evolution-request@swift.org wrote:
> Date: Fri, 18 Dec 2015 11:38:31 -0800
> From: Dave Abrahams <dabrahams@apple.com>
> Subject: Re: [swift-evolution] RFC: Proposed rewrite of Unmanaged<T>
> Message-ID: <E82AADA9-F4A4-4E4E-98C3-6E9A3CEC4D12@apple.com>
>
>> > On Dec 17, 2015, at 6:23 PM, T.J. Usiyan <griotspeak@gmail.com> > wrote:
>
>> > 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.
> Well, unsafeRef.release() is equivalent to
>
> {
> let x = $0.object
> CFRelease($0) // if CFRelease() wasn't @unavailable
> return x
> }(unsafeRef)
>
> If you let the return value drop on the floor, it ends up being
> exactly equivalent to the method with the exact same name from the
> MRC strategy. So the correspondence is strong and shouldn’t be a
> problem. That’s just my opinion, though, and part of the reason
> we’re asking for feedback here is so people steeped in MRC like you
> can argue with me about that :-), so if you find this unconvincing
> please explain why.

OK, guess I qualify as "steeped" there - I still use MRC in all my
shipping apps, although I've tentatively used ARC in small fry like
build-time utilities. (Never got used to GC.)

Anyway, much of my code looks like one of these patterns:

// 1
NSDictionary* dict = [(id)CFCreateSomeCFDictionary() autorelease];
... use dict for some lines, done

// 2
NSArray* array = (NSArray*)CFGetSomeCFArray();
... use array for some lines, done

// 3
NSString* str = (NSString*)CFCreateSomeCFString();
... use str for some lines
[release str];

One thing about my not migrating to ARC is that I find the bridging cast
names opaque - can't memorize them! Same, sadly, was true for the
Umanaged<T> methods.

So I'd say, use `.release` or `.autorelease` if they'd be used in the
same place as above...

--
Rainer Brockerhoff <rainer@brockerhoff.net>
Belo Horizonte, Brazil
"In the affairs of others even fools are wise
In their own business even sages err."
http://brockerhoff.net/blog/
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #3

Would `consumeReleased` work at all? It captures the 'don't use this again' aspect and 'release' without much extra.

Unfortunately that name seems to imply you're consuming something that has already been released. You're actually consuming a retain that happened in the CF function.

> Date: Fri, 18 Dec 2015 11:38:31 -0800
> From: Dave Abrahams <dabrahams@apple.com <mailto:dabrahams@apple.com>>
> Subject: Re: [swift-evolution] RFC: Proposed rewrite of Unmanaged<T>
> Message-ID: <E82AADA9-F4A4-4E4E-98C3-6E9A3CEC4D12@apple.com <mailto:E82AADA9-F4A4-4E4E-98C3-6E9A3CEC4D12@apple.com>>
>
>
>> > 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.
> Well, unsafeRef.release() is equivalent to
>
> {
> let x = $0.object
> CFRelease($0) // if CFRelease() wasn't @unavailable
> return x
> }(unsafeRef)
>
> If you let the return value drop on the floor, it ends up being
> exactly equivalent to the method with the exact same name from the
> MRC strategy. So the correspondence is strong and shouldn’t be a
> problem. That’s just my opinion, though, and part of the reason
> we’re asking for feedback here is so people steeped in MRC like you
> can argue with me about that :-), so if you find this unconvincing
> please explain why.

OK, guess I qualify as "steeped" there - I still use MRC in all my
shipping apps, although I've tentatively used ARC in small fry like
build-time utilities. (Never got used to GC.)

Anyway, much of my code looks like one of these patterns:

// 1
NSDictionary* dict = [(id)CFCreateSomeCFDictionary() autorelease];
... use dict for some lines, done

// 2
NSArray* array = (NSArray*)CFGetSomeCFArray();
... use array for some lines, done

// 3
NSString* str = (NSString*)CFCreateSomeCFString();
... use str for some lines
[release str];

One thing about my not migrating to ARC is that I find the bridging cast
names opaque - can't memorize them! Same, sadly, was true for the
Umanaged<T> methods.

So I'd say, use `.release` or `.autorelease` if they'd be used in the
same place as above...

--
Rainer Brockerhoff <rainer@brockerhoff.net <mailto:rainer@brockerhoff.net>>
Belo Horizonte, Brazil
"In the affairs of others even fools are wise
In their own business even sages err."
http://brockerhoff.net/blog/
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

-Dave

···

On Dec 19, 2015, at 5:04 PM, T.J. Usiyan via swift-evolution <swift-evolution@swift.org> wrote:
On Sat, Dec 19, 2015 at 7:45 PM, Rainer Brockerhoff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On 18/12/15 16:46 , swift-evolution-request@swift.org <mailto:swift-evolution-request@swift.org> wrote:
>> > On Dec 17, 2015, at 6:23 PM, T.J. Usiyan <griotspeak@gmail.com <mailto:griotspeak@gmail.com>> wrote:


(Rainer Brockerhoff) #4

I thought of `autoreleased` (for copy semantics) and `retained` (for
create semantics), but people not used to MRC might think misunderstand
them, I suppose.

···

On 20/12/15 1:19 , Dave Abrahams wrote:

On Dec 19, 2015, at 5:04 PM, T.J. Usiyan via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Would `consumeReleased` work at all? It captures the 'don't use this
again' aspect and 'release' without much extra.

Unfortunately that name seems to imply you're consuming something that
has already been released. You're actually consuming a retain that
happened in the CF function.

--
Rainer Brockerhoff <rainer@brockerhoff.net>
Belo Horizonte, Brazil
"In the affairs of others even fools are wise
In their own business even sages err."
http://brockerhoff.net/blog/