November 02, 2015
On 11/02/2015 10:31 AM, Martin Nowak wrote:
> 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.

Fine by me. Walter's and my thinking was we want to allow minimal overhead refcounting if possible. I'd say we can have a vptr in the implementation but should be careful about requiring it by design. -- Andrei
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 02, 2015
On 11/02/2015 01:20 AM, Andrei Alexandrescu wrote:
> 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).

Why are we trying so hard to make bad code work? Sharing the ownership of a class from within a method can be very surprising and can always be replaced by sharing with the function (passing as argument)/assigning on the callsite.

Even more important the @rc scheme doesn't seem to solve a much more common use case.

class Widget
{
  void fun()
  {
    escapingReferenceToFoo(field);
  }
  Foo field;
}




November 02, 2015
On 11/02/2015 10:38 AM, Martin Nowak wrote:
> On 11/02/2015 01:20 AM, Andrei Alexandrescu wrote:
>> 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).
>
> Why are we trying so hard to make bad code work? Sharing the ownership
> of a class from within a method can be very surprising and can always be
> replaced by sharing with the function (passing as argument)/assigning on
> the callsite.

The example is chosen to be simple, not good or representative. In real code shared ownership is both frequent and desirable.

> Even more important the @rc scheme doesn't seem to solve a much more
> common use case.
>
> class Widget
> {
>    void fun()
>    {
>      escapingReferenceToFoo(field);
>    }
>    Foo field;
> }

Is Foo a class type or not?


Andrei

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

November 02, 2015
On 11/02/2015 04:46 PM, Andrei Alexandrescu wrote:
> Is Foo a class type or not?

Let's assume Foo is an int.



November 02, 2015
On 11/02/2015 10:52 AM, Martin Nowak wrote:
> On 11/02/2015 04:46 PM, Andrei Alexandrescu wrote:
>> Is Foo a class type or not?
>
> Let's assume Foo is an int.

Well so I'm unclear then. You asserted that code escaping a class reference is in poor style and we needn't support it. But now you're asserting code that escapes the address of an int is a "much more common case". These two can't be simultaneously true.

I don't want to start a debate here, so let me ujust say what I think in the matter:

* Classes are meant to be used as references, escape freely, etc.

* Structs and primitive data types are not supposed to escape freely in safe code so we can afford to restrict escaping for them.

This seems to be the spirit of D. Want unrestricted use of references to objects? Use class. Want value semantics and fewer guarantees regarding escaping? Use non-class.


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

November 02, 2015
On 11/02/2015 01:20 AM, Andrei Alexandrescu wrote:
> 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.

@noescape in the presented form is not modular, which will be painful outside toy examples.
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 02, 2015
On Saturday, 31 October 2015 at 10:19:12 UTC, Jonathan M Davis wrote:
> On Saturday, October 31, 2015 03:10:41 Jakob Bornecrantz wrote:
>> On Friday, 30 October 2015 at 21:31:56 UTC, Andrei Alexandrescu wrote:
>> > A few matters Walter and I just discussed and wanted to submit for scrutiny:
>> >
>> > * @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.
>>
>> Have you done any investigation how this effects exception
>> handling and
>> dynamic upcasts?
>
> Why would the existence (or lack thereof) of a root object affect either exceptions or casting?
>
> Unless Throwable becomes an @rc class (which might be a good idea), exceptions won't be affected by @rc. And if Throwable does become an @rc class, then Throwable would be the root of all exception classes, and the lack of a general @rc class root would be irrelevant. As it is, exceptions aren't treated as Objects under normal circumstances. The closest that they get to to that would be when they're treated as an Exception or Throwable.
>
> The same goes with casting. Having a root object is irrelevant to casting. As long as the class reference that you're casting refers to an object whose type is either the target type or a type derived from the target type, then the cast will succeed. And if it doesn't, the result will be null. I don't see how the existence of a root object would affect that.
>
> Remember that C++ doesn't have a root object, and exceptions and casting work just fine there.

Correct, but vtable will effect it. Casts on classes in D
are dynamic by default unless they are downcasts.

In C++ dynamic_cast wont work on classes that doesn't
have a vtables, see example http://vp.dav1d.de/5ZOm?cpp I had
to check for myself since it was a long time I programmed
in C++ thanks to D. :)

I think just slapping @rc on Throwable will probably break code
that is out there in the wild.

Cheers, Jakob.

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

November 02, 2015
On Monday, 2 November 2015 at 15:35:01 UTC, Andrei Alexandrescu wrote:
> On 11/02/2015 10:31 AM, Martin Nowak wrote:
>> 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.
>
> Fine by me. Walter's and my thinking was we want to allow minimal overhead refcounting if possible. I'd say we can have a vptr in the implementation but should be careful about requiring it by design. -- Andrei

My aversion to vptr-less classes isn't so much the concept itself,
it has it uses and place, its just that the current semantics of
"@rc class Foo" also implies cpp style class implicit polymorphism.
Because in D a class declaration has a set of semantics with it.

Consider (where disable explicitly removes the vtable):

class Foo {}               // regular class
@rc class Foo {}           // regular rc class
@rc class Foo : disable {} // vptr-less rc class

Gives us that declarations that are syntactically closer are
also semantically closer to each other. It also allows for
enforcing of no virtual functions in the class body.

This all made sense in my head I hope it turns out well
in text for as well.

Cheers, Jakob.


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

November 02, 2015
On 11/02/2015 03:24 PM, Timon Gehr wrote:
> @noescape in the presented form is not modular, which will be painful
> outside toy examples.

I thought it can be made modular (save the attribute with the function signature, allow @noescape arguments to go to @noescape etc). What am I missing? Thx! -- Andrei
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study

November 02, 2015
On 11/02/2015 10:14 PM, Andrei Alexandrescu wrote:
> On 11/02/2015 03:24 PM, Timon Gehr wrote:
>> @noescape in the presented form is not modular, which will be painful
>> outside toy examples.
>
> I thought it can be made modular (save the attribute with the function
> signature, allow @noescape arguments to go to @noescape etc). What am I
> missing? Thx! -- Andrei

It is modular in the sense that it can be conservatively checked locally, but there will be cases where inlining a function or aggregate makes code compile that wouldn't otherwise, so it hinders composition, which would also be needed for modularity. Escape information only flows down the call tree but never up, nor does it flow across aggregate boundaries.


Simple examples:

C id(@noescape C x){ return x; }

C foo(@noescape C x){
    auto l=rc!C;
    auto bar(@noescape C y){
        return tuple(x,y);
    }
    auto r=bar(l);
    return r[0];
}


One other obvious example is something like:

void bar(){
    RC!(int[]) x;
    // ... (initialize x)
    foreach(a;x.map!foo){
        writeln(a);
    }
}
_______________________________________________
Dlang-study mailing list
Dlang-study@puremagic.com
http://lists.puremagic.com/cgi-bin/mailman/listinfo/dlang-study