April 10, 2015
On Wednesday, 8 April 2015 at 23:11:08 UTC, Walter Bright wrote:
> http://wiki.dlang.org/DIP77

From the DIP:
T foo(ref Payload payload);
...
RC rc;
foo(rc.payload);

rewrite foo(rc) as:

auto tmp = rc;
foo(rc.payload);

The only question I had was whether there was an advantage to rewriting the statement in its own scope:
{
  auto tmp = rc;
  foo(rc.payload);
}

You can save some stack space that way, but I don't know how hard it is to implement.
April 10, 2015
On Thursday, 9 April 2015 at 21:47:47 UTC, Walter Bright wrote:
> On 4/9/2015 12:58 PM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?=
>> indirections...? Is the compiler going to do a recursive scan and create
>> temporaries of all RC-pointers that are reachable?
>>
>> (e.g. RCArrays of RCArrays)
>
>
> It examines the types of all mutable values available to the function.

So if I pass in a graph, linked list or a tree, then it will scan the entire structure at runtime and build a large set of temporaries before calling the function?

April 10, 2015
On Friday, 10 April 2015 at 05:56:40 UTC, Ola Fosheim Grøstad wrote:
> On Thursday, 9 April 2015 at 21:47:47 UTC, Walter Bright wrote:
>> On 4/9/2015 12:58 PM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?=
>>> indirections...? Is the compiler going to do a recursive scan and create
>>> temporaries of all RC-pointers that are reachable?
>>>
>>> (e.g. RCArrays of RCArrays)
>>
>>
>> It examines the types of all mutable values available to the function.
>
> So if I pass in a graph, linked list or a tree, then it will scan the entire structure at runtime and build a large set of temporaries before calling the function?

No, but indeed, passing down indirection require boxing too. The DIP is not clear about it.
April 10, 2015
On Friday, 10 April 2015 at 06:02:35 UTC, deadalnix wrote:
> No, but indeed, passing down indirection require boxing too. The DIP is not clear about it.

Not sure what you mean by boxing. Usually it means that you wrap a value type in an object to turn it into a reference type. In Rust I think it means the same as unique_ptr ( http://rustbyexample.com/box.html ).

How will DIP77 work out if you represent a directed acyclic graph with ref counted edges? (e.g. one RCArray  per node)

Basically the problem that needs to be solved is very close to determining if there is no aliasing between parameters. The compile time solution could be either whole program pointer analysis or heavy type constraints  (linear typing). A general runtime solution would be rather inefficient IMO.

I think memory safety in D probably could be better solved, and with less effort, by a separate tool if DMD could be made to generate high level IR (a D VM that preserves high level information better than say LLVM).
April 10, 2015
On 4/9/2015 10:56 PM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> So if I pass in a graph, linked list or a tree, then it will scan the entire
> structure at runtime and build a large set of temporaries before calling the
> function?


Nope. It'll scan at compile time the types reachable through the parameters. If any of those types are RCO's that have a type that matches a ref parameter, the ref parameter's RCO will get copied.
April 10, 2015
On Friday, 10 April 2015 at 07:01:47 UTC, Walter Bright wrote:
> Nope. It'll scan at compile time the types reachable through the parameters. If any of those types are RCO's that have a type that matches a ref parameter, the ref parameter's RCO will get copied.

But how can this work? If I provide 2 ref parameters to different Node instances (not a RCO) in the same graph. How can I then be sure that it will not disappear?

E.g.

ref1 -> Node->RCRef->Edge(RCO)->Node->RCRef->Edge(RCO)->Node"X"
ref2 -> Node"X"
April 10, 2015
On 4/10/2015 12:10 AM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> On Friday, 10 April 2015 at 07:01:47 UTC, Walter Bright wrote:
>> Nope. It'll scan at compile time the types reachable through the parameters.
>> If any of those types are RCO's that have a type that matches a ref parameter,
>> the ref parameter's RCO will get copied.
>
> But how can this work? If I provide 2 ref parameters to different Node instances
> (not a RCO) in the same graph. How can I then be sure that it will not disappear?
>
> E.g.
>
> ref1 -> Node->RCRef->Edge(RCO)->Node->RCRef->Edge(RCO)->Node"X"
> ref2 -> Node"X"

Because with two parameters, if one is a ref coming from an RCO rc1, and the other is a ref to a type that is the root of a graph that contains an RCO type, then the rc1 is copied.
April 10, 2015
On Friday, 10 April 2015 at 08:47:09 UTC, Walter Bright wrote:
> On 4/10/2015 12:10 AM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?=
>> ref1 -> Node->RCRef->Edge(RCO)->Node->RCRef->Edge(RCO)->Node"X"
>> ref2 -> Node"X"
>
> Because with two parameters, if one is a ref coming from an RCO rc1, and the other is a ref to a type that is the root of a graph that contains an RCO type, then the rc1 is copied.

ref1 -> RCO1 -> N1 -> RCRef1 -> RCO2 -> N2 -> RCRef3 -> RCO3 -> N3
ref2 -> N3

N1..N3 represent resources (like a file).

process(ref1,ref2){
    ref1.stuff.stuff.stuff.release(); // Node2 and Node3 is released.
    ref2.read(); // fails/garbage
}



April 10, 2015
On 4/10/2015 2:14 AM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> On Friday, 10 April 2015 at 08:47:09 UTC, Walter Bright wrote:
>> On 4/10/2015 12:10 AM, "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?=
>>> ref1 -> Node->RCRef->Edge(RCO)->Node->RCRef->Edge(RCO)->Node"X"
>>> ref2 -> Node"X"
>>
>> Because with two parameters, if one is a ref coming from an RCO rc1, and the
>> other is a ref to a type that is the root of a graph that contains an RCO
>> type, then the rc1 is copied.
>
> ref1 -> RCO1 -> N1 -> RCRef1 -> RCO2 -> N2 -> RCRef3 -> RCO3 -> N3
> ref2 -> N3
>
> N1..N3 represent resources (like a file).
>
> process(ref1,ref2){
>      ref1.stuff.stuff.stuff.release(); // Node2 and Node3 is released.
>      ref2.read(); // fails/garbage
> }


ref2 is copied.
April 10, 2015
> http://wiki.dlang.org/DIP77

We seem to be incrementally edging towards Rust's memory management system or something similar and retracing their steps along the path to get there. Hypothetically how close could we get to being able to opt into a Rust world from the GC world or C worlds of memory management?