August 13, 2016
On Friday, 12 August 2016 at 21:36:20 UTC, Andrei Alexandrescu wrote:
> Can you please give examples of cases that are (a) unlikely to be supported with reasonable effort, and (b) likely to cause problems in usability? Thanks! -- Andrei

Anythign that work with a linkedlist or a tree structure.
August 13, 2016
On Friday, 12 August 2016 at 12:29:21 UTC, Andrei Alexandrescu wrote:
> On 8/12/16 6:12 AM, deadalnix wrote:
>> 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.
>
> You committed to author a proposal a few months back. Did you make progress on that? -- Andrei

The comment I made in 2014 on this very DIP came with a proposal of what to change in it (namely, computing lifetime differently for r and l values, as to get the lowest possible lifetime when reading and the largest possible one when writing).

You have the detail in your inbox for close to 2 years now.

August 13, 2016
On 08/13/2016 03:25 AM, deadalnix wrote:
> On Friday, 12 August 2016 at 12:29:21 UTC, Andrei Alexandrescu wrote:
>> On 8/12/16 6:12 AM, deadalnix wrote:
>>> 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.
>>
>> You committed to author a proposal a few months back. Did you make
>> progress on that? -- Andrei
>
> The comment I made in 2014 on this very DIP came with a proposal of what
> to change in it (namely, computing lifetime differently for r and l
> values, as to get the lowest possible lifetime when reading and the
> largest possible one when writing).
>
> You have the detail in your inbox for close to 2 years now.

Thanks. Do you have a date or title of the thread? -- Andrei

August 13, 2016
On Saturday, 13 August 2016 at 14:35:09 UTC, Andrei Alexandrescu wrote:
>> You have the detail in your inbox for close to 2 years now.
>
> Thanks. Do you have a date or title of the thread? -- Andrei

In the very thread that ended up with DIP1000 .

I suggested various changes int he DIP, which I'm copying bellow. You can read it in context digging around the 26/11/2014 .

Copying the proposed changes to DIP 1000:
=========================================

Ok, resurrecting the thread, I'd like to propose another way to specify this. The end result should be very close but should provide a simpler/clearer mental model.

Every expression has now has a lifetime associated with it, and can be marked as "scope". It is only possible to assign b to a if b has a lifetime equal or greater than a's.

An infinite lifetime is a lifetime greater or equal than any other lifetime. Expression of infinite lifetime are:
 - literals
 - GC heap allocated objects
 - statics and enums.
 - rvalues of type that do not contain indirections.
 - non scope rvalues.

Dereference share the lifetime of the dereferenced expression (ie infinite lifetime unless the expression is scope). Address of expression shared the lifetime of the base expression, and in addition gain the scope flag.

Comment: Using these rule, we basically define any indirection being of infinite lifetime by default, and we propagate the lifetime when scope. The addition of the scope flag for address of is necessary to disallow taking address->dereference to yield an infinite lifetime.

Variables delcarations (including parameters) have the lifetime of the block they are declared in (2 pitfalls here, I don't have good solution, and the original spec do not as well : #1 destructor, finally, scope statement and #2 closures). Use of these variables shared the lifetime of the variable, unless they qualify for infinite lifetime. Parameter's lifetime are unordered, meaning smaller than infinite, greater than the function's scope, but not equal to each other nor greater/smaller than each others.

Working from there, I'd like to define properly the pitfalls #1 and #2 . These are the great absent from what is discussed so far.

const scope works for Rust, but isn't gonna fly for D. That is a good idea, but not worth the cost.

I'd like to discuss the pro and cons of such a definition (compared to rust for instance):
 - We can't specify explicit lifetime for parameters. I'm not sure how limiting it is. This is something we can extend toward anyway in the future, so I suggest we put that asside for now.
 - We can't define lifetime of indirections explicitly. This clearly limit the expressiveness compared to Rust, but I it allow for scope to be a storage class rather than a type qualifier, and I think this is a winner when looking at the complexity / expressiveness ratio.
 - In D, mutability and burrowing are decoupled, which i think is a plus compared to Rust. That prevent us to go for things like the proposed const scope, but simply the concept of both mutabilities and burrowing in D, while allowing some pattern that aren't easy to get in Rust (multiple writable reference to one object in a single thread for instance, is trivial in D).

Maybe I'm convincing myself, but I think we have a winner here.

Andrei, what do you have in mind when you say scope should be the default ? I do think this is a sensible default, but I fail to see how this is gonna translate with existing code in a nice manner.
August 13, 2016
On 08/13/2016 12:16 PM, deadalnix wrote:
> I suggested various changes int he DIP, which I'm copying bellow.

That's the spirit. Thanks. -- Andrei
August 14, 2016
On 08/10/2016 11:36 PM, Dicebot wrote:
> http://forum.dlang.org/post/pqsiqmkxenrwxoruzaml@forum.dlang.org

I am still uncertain myself about the proposal, mostly because can't completely grasp rules for returning as scope. My litmus test example is very simple (for desired semantics):

```
struct Container
{
    int data;

    static struct Range
    {
        int* pdata;
        // range methods skipped for clarity ..
    }

    Range asRange ( )
    {
        return Range(&this.data);
    }
}

void main ( )
{
    Container container;

    import std.stdio;
    writeln(container.asRange()); // case 1, OK

    scope r = container.asRange(); // case 2, OK
    auto r = container.asRange(); // case 3, not OK
}
```

It looks like
(https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md#scope-function-returns)
I can annotate `scope Range asRange ( )` to force result into rvalue and
make case 1 and case 3 work as desired but there is no way to express
lifetime relation between returned struct and host container so that
case 2 will work.

If it is indeed correct, I am going to call it a complete showstopper. Any scope proposal is of interest to me only if it can be used to implement some form of borrowship semantics (even awkwardly looking) on top - everything else is a nice addition to have but in no way justifies added language weight.

Note that section
https://github.com/dlang/DIPs/blob/master/DIPs/DIP1000.md#owning-containers
explain similar example (but with refcounting instead of stack
allocation) but it does not show semantics at call site and is either
subject to same limitation (can't store result of `opIndex`) or
contradicts previous spec.



August 14, 2016
Two another more nitpicky comments:

1) Deprecation process proposal right now says this:

- remove -scope, issue warning when errors are detected
- replace warnings with deprecation messages

PLEASE FOR THE SAKE OF ALL DEAR NEVER EVER DO THIS

Deprecations must always come first. Warnings may or may not follow later but any deprecation process must mandatory start with deprecation message, not exceptions and no excuses.

2) Ignoring `scope` for variables with no indirections.

The fact that DMD is extremely accepting when it comes to nonsense declarations/attributes has been is notable contribution to harming learning curve. It often tricks new developers into thinking that their code is checked for something when in fact compiler simply silently skips extra annotations.

Instead, nonsense application of `scope` to data with no indirections should be deprecated completely as part of overall deprecation process for implementing the proposal.



August 14, 2016
On 8/14/2016 7:42 AM, Dicebot wrote:
> 2) Ignoring `scope` for variables with no indirections.
>
> The fact that DMD is extremely accepting when it comes to nonsense
> declarations/attributes has been is notable contribution to harming
> learning curve. It often tricks new developers into thinking that their
> code is checked for something when in fact compiler simply silently
> skips extra annotations.
>
> Instead, nonsense application of `scope` to data with no indirections
> should be deprecated completely as part of overall deprecation process
> for implementing the proposal.

The difficulty with that is dealing with generic types.

August 14, 2016
On 8/14/2016 12:39 PM, Walter Bright wrote:
> On 8/14/2016 7:42 AM, Dicebot wrote:
>> 2) Ignoring `scope` for variables with no indirections.
>>
>> The fact that DMD is extremely accepting when it comes to nonsense
>> declarations/attributes has been is notable contribution to harming
>> learning curve. It often tricks new developers into thinking that their
>> code is checked for something when in fact compiler simply silently
>> skips extra annotations.
>>
>> Instead, nonsense application of `scope` to data with no indirections
>> should be deprecated completely as part of overall deprecation process
>> for implementing the proposal.
>
> The difficulty with that is dealing with generic types.

Consider another case:

  struct S {
    int i;
    int* p;
  }

  scope S s;

  return s.i; // ok
  return s.p; // error!

The 'scope' only applies to the indirection parts of a type. Therefore,

  scope int i;

should not be an error.
August 14, 2016
On 8/14/2016 7:42 AM, Dicebot wrote:
> Two another more nitpicky comments:
>
> 1) Deprecation process proposal right now says this:
>
> - remove -scope, issue warning when errors are detected
> - replace warnings with deprecation messages
>
> PLEASE FOR THE SAKE OF ALL DEAR NEVER EVER DO THIS
>
> Deprecations must always come first. Warnings may or may not follow
> later but any deprecation process must mandatory start with deprecation
> message, not exceptions and no excuses.

Hmm, but we've always done warning => deprecation => error