DIP74 - where is at?

Manu via Digitalmars-d digitalmars-d at puremagic.com
Sun Oct 11 01:55:16 PDT 2015


On 11 October 2015 at 17:30, deadalnix via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On Sunday, 11 October 2015 at 06:48:54 UTC, Manu wrote:
>>
>> I don't really see that DIP25 and DIP74 are particularly closely related.
>
>
> Ho they are. It is all about ownership.
>
>> DIP25 is a lame cop-out with respect to scope. I was a major backer of
>> a proper scope implementation, and given that, I don't/didn't support
>> DIP25 at all.
>>
>
> DIP25 being a sorry excuse for ownership is the very reason DIP74 is needed.
> Rust can do reference counting just fine all in library without need for
> core language support.
>
>> DIP74 on the other hand introduces 2 magic functions that the compiler
>> calls as the appropriate moments to implement ref counting. The
>> implementation is somewhat detail, theoretically changeable in the future,
>> but I think language support for ref-counting primitives is critical for ref
>> counting to be efficient and simple. Look at C++, and we see a disaster. C++
>> basically implemented rval-references to improve (not solve) the RC
>> problem... we don't have rval-ref's in D, so we're screwed from the library
>> angle.
>>
>
> C++ ref counting is not slow for the reasons you think it is. ARC is overly
> complex and also not as fast as you think it is.
>
> First, they are slow because in C++ (or ObjC), you don't know what is shared
> and what isn't. As a result, you got to go the pessimistic road and use
> thread safe ref counting. This can be a solved problem in D purely using the
> type qualifier.
>
> Second, exceptions. Their unwinding makes pair of inc/dec hard to recognize,
> plus now cleanup is need at pretty much every frames, meaning incredibly
> slow exceptions + various control flow optimization that aren't possible
> anymore (tail call being one of them).
>
> One that one, nobody has a solution. Not ARC (that's why swift does not have
> exception), not C++ and not us. IMO the obvious solution here is to allow
> ourselves to leak on unwind and rely on the GC. Yes, sometime the GC is
> best. That being said, it is up to the application to decide if leaking is
> acceptable or not, and so this can't be baked in the language (this also
> means that the user must be in charge the of deallocation policy, which puts
> a major dent into DIP74).
>
> The 3rd problem is safety. This is where ownership shines.
>
> The 4th problem is elision of refcount operations when not needed. Some
> thing, ownership can solve this. No need to do refcount operations when not
> necessary.
>
> The compiler is perfectly able to optimize pairs of inc/dec granted it has
> the rights infos. And a proper ownership system provide the right infos.
>
>> Yup, I was firmly behind scope (ie, borrowing), but that was
>> destroyed, and DIP25 kinda cements the death of that :(
>>
>
> It is implemented with a flag. That allowed us to try it and get real life
> experience. That is a good thing. We aren't committed to it at this stage.
> And now we have actual experimentation that shows that it is too
> underpowered to be really useful. The smart move here is to admit defeat and
> reconsider.

Nothing here explains to me how it is that the compiler can do without
RC primitives that the compiler knows it is allowed to
optimise/schedule as it likes?
How does it look in rust that it is able to optimise calls to inc/dec
primitives?

You also make the points that I expect to bank on in D; we are
thread-local by default (big advantage!), nothrow is pervasive (big
advantage!), but the language still doesn't know the primitives that
it can use to optimise.

The ownership proposal solving the problem isn't entirely correct.
Sure, borrowed pointers imply RC elision, and it's particularly useful
for writing API's that are allocation/ownership agnostic, but it
doesn't solve the problem as you suggest. Once a pointer is borrowed,
it can't be assigned to another RC pointer anymore. If you must use
borrowing to implement RC elision across calls, then you lose the
ability to give someone else a reference down the call-tree.
Passing an RC object proper to a function also elides RC fiddling, but
the compiler can't distinguish between RC fiddling and copying logic
unless the RC primitives are explicit. I find that this is a very
common case.


More information about the Digitalmars-d mailing list