November 01, 2015
On 10/31/2015 11:35 PM, Michel Fortin wrote:
> I think it'd be more important to talk about auto-nulling weak
> references. That's a general concept that is necessary if you want
> reference counting to be useful and safe at the same time.

Agreed. We need to put weak pointers in the initial DIP and carry them through.

Regarding opInc/opDec, here are some rules that the compiler may use:

* Both are callable with an unsigned integer, 1 by default
* opInc(n) followed by opDec(n) against the same object, with no call to isUniquelyReferenced in between, may be removed
* opInc(n1) followed by opInc(n2) against the same object may be replaced with opInc(n1 + n2)
* opDec(n1) followed by opDec(n2) against the same object may be replaced with opDec(n1 + n2)

I'm trying to formalize a bit what removals and fusing the compiler should be allowed.


Andrei
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 01, 2015
2015-11-01 6:02 GMT-08:00 Andrei Alexandrescu <andrei@erdani.com>:

> On 10/31/2015 11:35 PM, Michel Fortin wrote:
>
>> I think it'd be more important to talk about auto-nulling weak references. That's a general concept that is necessary if you want reference counting to be useful and safe at the same time.
>>
>
> Agreed. We need to put weak pointers in the initial DIP and carry them through.
>
>
It' doesn't looks like this kind of mechanism should be baked into the language. It come with a cost that maybe one doesn't want to pay. Maybe one is ok to fallback on the GC on that one. Maybe it is preferable to provide several kind of RC. Adn weak reference are just one variation one may wish.


> Regarding opInc/opDec, here are some rules that the compiler may use:
>
> * Both are callable with an unsigned integer, 1 by default
> * opInc(n) followed by opDec(n) against the same object, with no call to
> isUniquelyReferenced in between, may be removed
> * opInc(n1) followed by opInc(n2) against the same object may be replaced
> with opInc(n1 + n2)
> * opDec(n1) followed by opDec(n2) against the same object may be replaced
> with opDec(n1 + n2)
>
> I'm trying to formalize a bit what removals and fusing the compiler should be allowed.
>
>
Using intrinsic would sidestep this completely, even allowing to have several schemes.


November 01, 2015
On 11/01/2015 02:16 PM, deadal nix wrote:
> 2015-11-01 6:02 GMT-08:00 Andrei Alexandrescu <andrei@erdani.com
> <mailto:andrei@erdani.com>>:
>
>     On 10/31/2015 11:35 PM, Michel Fortin wrote:
>
>         I think it'd be more important to talk about auto-nulling weak
>         references. That's a general concept that is necessary if you want
>         reference counting to be useful and safe at the same time.
>
>
>     Agreed. We need to put weak pointers in the initial DIP and carry
>     them through.
>
>
> It' doesn't looks like this kind of mechanism should be baked into the
> language. It come with a cost that maybe one doesn't want to pay. Maybe
> one is ok to fallback on the GC on that one. Maybe it is preferable to
> provide several kind of RC. Adn weak reference are just one variation
> one may wish.

After much deliberation and collective experience, C++ chose to support weak_ptr as a complement to shared_ptr, in spite of the well-understood performance overhead. It is sensible to draw from that experience as well; also, I agree with Michel that safety makes it all the more important that we design weak pointer support in from day one. -- Andrei
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 01, 2015
That doesn't follow. C++ doesn't have a GC to pick up the cycles, not it bakes RC into the language (and in fact, it is not that uncommon to see C++'s project rolling their own RC mechanism).

2015-11-01 11:28 GMT-08:00 Andrei Alexandrescu <andrei@erdani.com>:

> On 11/01/2015 02:16 PM, deadal nix wrote:
>
>> 2015-11-01 6:02 GMT-08:00 Andrei Alexandrescu <andrei@erdani.com <mailto:andrei@erdani.com>>:
>>
>>     On 10/31/2015 11:35 PM, Michel Fortin wrote:
>>
>>         I think it'd be more important to talk about auto-nulling weak
>>         references. That's a general concept that is necessary if you want
>>         reference counting to be useful and safe at the same time.
>>
>>
>>     Agreed. We need to put weak pointers in the initial DIP and carry
>>     them through.
>>
>>
>> It' doesn't looks like this kind of mechanism should be baked into the language. It come with a cost that maybe one doesn't want to pay. Maybe one is ok to fallback on the GC on that one. Maybe it is preferable to provide several kind of RC. Adn weak reference are just one variation one may wish.
>>
>
> After much deliberation and collective experience, C++ chose to support weak_ptr as a complement to shared_ptr, in spite of the well-understood performance overhead. It is sensible to draw from that experience as well; also, I agree with Michel that safety makes it all the more important that we design weak pointer support in from day one. -- Andrei
>


November 01, 2015
On 11/01/2015 02:37 PM, deadal nix wrote:
> That doesn't follow. C++ doesn't have a GC to pick up the cycles, not it
> bakes RC into the language (and in fact, it is not that uncommon to see
> C++'s project rolling their own RC mechanism).

Java also has weak references since 1.2; also, we want to support folks who want to do memory management without relying on a garbage collector. -- Andrei
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 01, 2015
On Wednesday, 28 October 2015 at 00:45:00 UTC, Andrei Alexandrescu wrote:
> @rc class Widget {
>     ...
> }

Copied post from http://forum.dlang.org/post/n15trm$2r5h$1@digitalmars.com.

Let's think about this more clearly before we bake a monolithic feature for a single problem into the language.

A few thoughts:

- @rc and @noescape are orthogonal

  while @rc requires @noescape the latter could
  be useful for other purposes

- If the compiler knows a reference has a limited lifetime
  it could check for @noescape making most of RC implementable
  in a library.

  struct RC
  {
    Object get() return; // lifetime of Object is bound to RC, compiler
could check any function called on Object for @noescape
  }

- I'm not a fan of adding yet another attribute but as inference support
  is currently limited it seems we'd need an explicit attribute for
  public APIs.



November 01, 2015
On 11/01/2015 10:14 PM, Martin Nowak wrote:
>   while @rc requires @noescape the latter could
>   be useful for other purposes

For example @rc completely ignore unique ownership of classes which has the same @noescape problems. This is already a good indication that @rc should be generalized more.



November 01, 2015
Le 1 nov. 2015 à 9:02, Andrei Alexandrescu <andrei@erdani.com> a écrit :

> Agreed. We need to put weak pointers in the initial DIP and carry them through.

It might be good enough to simply make sure someone can create them as a library type. But for that you need to add a way to have the compiler *not* do automatic reference counting inside the implementation of the weak pointer. A @manualrc attribute you could attach to a function to simply disable automatic insertion of opInc/opDec in that function would probably be all that's really needed.

That being said, while I guess it's okay, a library implementation using a struct will suffer some of the same problems Rebindable has.


> Regarding opInc/opDec, here are some rules that the compiler may use:
> 
> * Both are callable with an unsigned integer, 1 by default
> * opInc(n) followed by opDec(n) against the same object, with no call to isUniquelyReferenced in between, may be removed

"isUniquelyReferenced" is not a special case. Any function that can mutate the lvalue you are passing as an argument is in the same boat. In other words, you can only elide the opInc/opDec pair if you can prove that the function won't change the object referenced by that lvalue during its execution.


> * opInc(n1) followed by opInc(n2) against the same object may be replaced with opInc(n1 + n2)
> * opDec(n1) followed by opDec(n2) against the same object may be replaced with opDec(n1 + n2)

That's fine in theory, but it's better to avoid doing it this way if you can. Keep in mind that for many RC systems the cost will be proportional to the integer you provide. If for instance I was to implement opInc for COM objects I'd have to write it like this:

	void opInc(int n) {
		while (n--) AddRef(); // n virtual calls, n atomic increments
	}

So ideally the compiler should always use the smallest "n" possible.


-- 
Michel Fortin
michel.fortin@michelf.ca
https://michelf.ca


_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 01, 2015
On 11/1/15 4:14 PM, Martin Nowak wrote:
> - If the compiler knows a reference has a limited lifetime
>    it could check for @noescape making most of RC implementable
>    in a library.
>
>    struct RC
>    {
>      Object get() return; // lifetime of Object is bound to RC, compiler
> could check any function called on Object for @noescape
>    }

Yah, I think it's worth exploring a variant in which we annotate @noescape methods and then only allow those methods to be called from RC!T.get.

Note, however, that we may end up with a more conservative scheme. Consider:

class Widget
  static Widget g;
  void fun()
  {
    g = this;
  }
}

If we make the entire Widget reference-counted, the compiler knows how to make the code work. If we go the @noescape route, this code and others like it will be statically disallowed. So we end up with something more restrictive (or more complicated if we decide to allow certain escape patterns).


Andrei
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 02, 2015
On Friday, 30 October 2015 at 21:31:56 UTC, Andrei Alexandrescu wrote:
> * @rc classes shall not be single-rooted. Rationale: there is no strong advantage in it and it would force all @rc classes to embed a vptr. This has been already discussed and largely agreed upon in this group.

I this really such a good idea to it simply b/c it's possible?
It would kind of add a third species to struct/class, implying lots of
work (compiler changes, debuggers, typeinfo...).
And unless you want to break typeid(baseclass) which currently returns
the dynamic type you wouldn't even safe the pointer.