Mac Apps That Use Garbage Collection Must Move to ARC

Manu via Digitalmars-d digitalmars-d at puremagic.com
Wed Feb 25 07:55:14 PST 2015


On 24 February 2015 at 10:36, deadalnix via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On Monday, 23 February 2015 at 09:51:07 UTC, Manu wrote:
>>
>> This is going to sound really stupid... but do people actually use
>> exceptions regularly?
>
>
> I'd say exception are exceptional in most code. That being said, unless the
> compiler can PROVE that no exception is gonna be thrown, you are stuck with
> having to generate a code path for unwinding that decrement the refcount.
>
> It means that you'll have code bloat (not that bad IMO, unless you are
> embeded) but more importantly, it means that most increment/decrement can't
> be optimized away in the regular path, as you must get the expected count in
> the unwinding path.

Can the unwind path not be aware that the non-exceptional path had an
increment optimised away? Surely the unwind only needs to perform
matching decrements where an increment was generated...
I can easily imagine the burden ARC may place on the exceptional path,
but I can't visualise the influence it has on the normal path?


> Moreover, as you get some work to do on the unwind path, it becomes
> impossible to do various optimizations like tail calls.

Tail call is nice, but I don't think I'd lament the loss, especially
when nothrow (which is inferred these days) will give it right back.

Embedded code that can't handle the bloat would be required to use
nothrow to meet requirements. That's fine, it's a known constraint of
embedded programming.
Realtime/hot code may also need to use nothrow to guarantee all
optimisations are possible... which would probably be fine in most
cases? I'd find that perfectly acceptable.


> I think Walter is right when he says that switft dropped exception because
> of ARC.

But what was the definitive deal breaker? Was there one thing, like
it's actually impossible... or was it a matter of cumulative small
things leading them to make a value judgement?
We might make a different value judgement given very different circumstances.


>> I've never used one. When I encounter code that does, I just find it
>> really annoying to debug. I've never 'gotten' exceptions. I'm not sure
>> why error codes are insufficient, other than the obvious fact that
>> they hog the one sacred return value.
>
>
> Return error code have usually been an usability disaster for the simple
> reason that the do nothing behavior is to ignore the error.

I generally find this preferable to spontaneous crashing. That is,
assuming the do nothing behaviour with exceptions is for it to unwind
all the way to the top, which I think is the comparable 'do nothing'
case.

I've pondered using 'throw' in D, but the thing that usually kills it
for me is that I can't have a free catch() statement, it needs to be
structured with a try.
I just want to write catch() at a random line where I want unwinding
to stop if anything before it went wrong. Ie, implicit try{} around
all the code in the scope that comes before.
I don't know if that would tip me over the line, but it would go a
long way to making it more attractive. I just hate what exceptions do
to your code. But also, debuggers are terrible at handling them.


> The second major problem is that you usually have no idea how where the
> error check is done, forcing the programmer to bubble up the error where it
> is meaningful to handle it.

That's true, but I've never felt like exceptions are a particularly
good solution to that problem.
I don't find they make the code simpler. Infact, I find them to
produce almost the same amount of functional code, except with
additional indentation and brace spam, syntactic baggage, and bonus
allocations.

Consider:
if(tryAndDoThing() == Error.Failed)
  return Error.FailedForSomeReason;

if(tryNextThing() == Error.Failed)
  return Error.FailedForAnotherReason;

Compared to:
try
{
  doThing();
  nextThing();
}
catch(FirstKindOfException e)
{
  throw new Ex(Error.FailedForSomeReason);
}
catch(SecondKindOfException e)
{
  throw new Ex(Error.FailedForAnotherReason);
}

It's long and bloated (4 lines became 13 lines!), it allocates, is not
@nogc, etc.
Sure, it might be that you don't always translate inner exceptions to
high-level concepts like this and just let the inner exception bubble
up... but I often do want to have the meaningful translation of
errors, so this must at least be fairly common.


>> I'll agree though that this can't be changed at this point in the game.
>> You say that's a terminal case? Generating code to properly implement
>> a decrement chain during unwind impacts on the non-exceptional code
>> path?
>>
>
> Yes as you can't remove increment/decrement pairs as there are 2 decrement
> path (so there is pair).

I don't follow. If you remove the increment, then the decrement is
just removed in both places...?
I can't imagine how it's different than making sure struct destructors
are called, which must already work right?


>> I agree. I would suggest if ARC were proven possible, we would like,
>> switch.
>>
>
> I'd like to see ARC support in D, but I do not think it makes sense as a
> default.

Then we will have 2 distinct worlds. There will be 2 kinds of D code,
and they will be incompatible... I think that's worse.


>>> 3. Memory safety is a requirement for any ARC proposal for D. Swift
>>> ignores
>>> memory safety concerns.
>>
>>
>> What makes RC implicitly unsafe?
>
>
> Without ownership, one can leak reference to RCed object that the RC system
> do not see.

Obviously, ARC is predicated on addressing ownership. I think that's very clear.


More information about the Digitalmars-d mailing list