August 11, 2016
On Thursday, 11 August 2016 at 21:28:57 UTC, sclytrack wrote:
> On Wednesday, 10 August 2016 at 20:36:38 UTC, Dicebot wrote:
>> http://forum.dlang.org/post/pqsiqmkxenrwxoruzaml@forum.dlang.org
>>
>> The first DIP has just landed into the new queue. It is a proposal from language authors and thus it bypasses usual nitpicking process and proceeds straight to requesting community (your!) feedback.
>>
>> Essentially, it is an attempt to solve reference lifetime problem by extending implementation of `scope` keyword.
>>
>> Proposal text: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md
>>
>> Few notes:
>>
>> - Please submit pull requests to adjust the markdown document if you want to propose any improvements (mentioning @WalterBright and @andralex for confirmation).
>> - The proposal refers to a number of other documents and it is recommended to become familiar at least briefly with all of them.
>> - At this point the question I'd personally suggest to be evaluated is "does this proposal enable enough useful designs?". A good check would be to try taking some of your projects and see if having DIP1000 approved and implemented could improve them.
>
>
> There is confusion between what lifetime and visibility in the DIP.
> (Well, I am confused)
>

I'm a confused by the terminology as well.

lifetime(p) denotes the lifetime of the value which is referred to by 'p', is that correct? And visibility(p) denotes the lifetime of 'p' itself?

I found this very confusing...
August 12, 2016
On Thursday, 11 August 2016 at 22:00:06 UTC, Walter Bright wrote:
> On 8/11/2016 4:46 AM, Robert burner Schadek wrote:
>> Can I do this:
>>
>> ```
>> struct Foo { int a; }
>> auto rcs = RefCountedSlice!Foo(); // assume rcs.length > 0
>>
>> scope Foo zero = rcs[0];
>> zero.a = 1337;
>> assert(rcs[0].a == 1337);
>> ```
>
> No, because the lifetime of zero exceeds the lifetime of rcs[0].

Hm, that is really bad IMO. The shown use case is properly the most common use case. Is there no way to make it transitive so the lifetime of rcs[0] is the lifetime of rcs.

To be blunt, this is a real show-stopper for me.
August 12, 2016
On Friday, 12 August 2016 at 09:42:35 UTC, Robert burner Schadek wrote:
> On Thursday, 11 August 2016 at 22:00:06 UTC, Walter Bright wrote:
>> On 8/11/2016 4:46 AM, Robert burner Schadek wrote:
>>> Can I do this:
>>>
>>> ```
>>> struct Foo { int a; }
>>> auto rcs = RefCountedSlice!Foo(); // assume rcs.length > 0
>>>
>>> scope Foo zero = rcs[0];
>>> zero.a = 1337;
>>> assert(rcs[0].a == 1337);
>>> ```
>>
>> No, because the lifetime of zero exceeds the lifetime of rcs[0].
>
> Hm, that is really bad IMO. The shown use case is properly the most common use case. Is there no way to make it transitive so the lifetime of rcs[0] is the lifetime of rcs.
>
> To be blunt, this is a real show-stopper for me.

No, the DIP doesn't handle several levels of indirection.
August 12, 2016
On Thursday, 11 August 2016 at 21:57:06 UTC, Walter Bright wrote:
> With conditionals, the scope of it is the narrowest scope of each of its leaves.
>
>> (cond ? a : c) = &b;   // not ok, accepted even though a outlives b
>
> I had overlooked the lvalue case, but you're right. The rules for it are inevitable.
>

I raised that in November 2014 already.

To be honest I'm to a point were I'm starting withdrawing from these conversation because I have no idea how to reach to you guys. I could write on toilet paper before using it to the same effect.

August 12, 2016
> No, the DIP doesn't handle several levels of indirection.

What about:

struct Bar { int a; int b }
auto rcs = RefCountedTree!(string,Bar)();

fcs["bar"].a = 1337;  // log n
fcs["bar"].b = 1338;  // log n

? I need to pay log n twice to assign two members


August 12, 2016
On 8/12/2016 3:12 AM, deadalnix wrote:
> I raised that in November 2014 already.

I remember the discussion.


> To be honest I'm to a point were I'm starting withdrawing from these
> conversation because I have no idea how to reach to you guys. I could write on
> toilet paper before using it to the same effect.

I believe I understood your point. I just didn't agree that was the best way forward for D. I didn't expect you'd changed your mind, either :-)
August 12, 2016
On 8/12/2016 2:42 AM, Robert burner Schadek wrote:
> Hm, that is really bad IMO. The shown use case is properly the most common use
> case. Is there no way to make it transitive so the lifetime of rcs[0] is the
> lifetime of rcs.

  rcs[0].a = 1337;
  assert(rcs[0].a == 1337);

It shouldn't be a big problem if the containers are shallow - the optimizer can remove the redundant computations.

> To be blunt, this is a real show-stopper for me.

Generally, it will require a more thorough use of encapsulation of containers and operations on them, if one is to use malloc/free or ref counting safely.
August 12, 2016
On Friday, 12 August 2016 at 10:24:22 UTC, Robert burner Schadek wrote:
>> No, the DIP doesn't handle several levels of indirection.
>
> What about:
>
> struct Bar { int a; int b }
> auto rcs = RefCountedTree!(string,Bar)();
>
> fcs["bar"].a = 1337;  // log n
> fcs["bar"].b = 1338;  // log n
>
> ? I need to pay log n twice to assign two members

What you are proposing is having the returned value survive not till the end of the expression, but longer. The question is how long. If, instead of a tree, you use an hashmap, then the reference to rcs["bar"] may die long before rcs itself (because of a rehash).
So for this to work the compiler should consider the references returned by the functions to be valid until a mutable operation is applied to the container, i think.
August 12, 2016
On 8/12/2016 3:24 AM, Robert burner Schadek wrote:
> ? I need to pay log n twice to assign two members


In order to return a pointer that lasts longer than an expression, make it a ref counted entity as well.
August 12, 2016
On Thursday, 11 August 2016 at 21:57:06 UTC, Walter Bright wrote:
> On 8/11/2016 6:36 AM, Marc Schütz wrote:
>> 4) The DIP doesn't address mutable aliasing at all. As a consequence, the
>> example `RefCountedSlice` is unsafe:
>>
>> auto arr = RefCountedSlice!int(10);
>> auto ptr = &arr[5];
>> arr = RefCountedSlice!int(42);
>> *ptr = 1;    // use after free
>
> The idea is to have containers return references by 'return ref' or 'return scope' so the internal references can't escape the expression they're used in.

So &arr[5] would be an error. The bug can still occur when passing arr and arr[5] both by reference to a function, but that case can (in future) be solved by making RefCountedSlice an @rc object*.

* https://wiki.dlang.org/DIP77