December 04, 2014
> Errors for scope violations are only reported in @safe code.

Why? If I've explicitly designated a reference as scope, why should it be ignored in un-@safe code?
December 04, 2014
On Thursday, 4 December 2014 at 11:21:27 UTC, Marc Schütz wrote:
>> Errors for scope violations are only reported in @safe code.
>
> Why? If I've explicitly designated a reference as scope, why should it be ignored in un-@safe code?

Agreed, it should also work for any other code with some function to cast away scope.

ref T unscope(scope ref T t) @system
{
    auto p = &t;
    return *p;
}
December 04, 2014
On Thursday, 4 December 2014 at 09:25:11 UTC, Walter Bright wrote:
> http://wiki.dlang.org/DIP69
>
Great stuff.

Will this be possible, it's a fairly important use-case.

scope ref T setVal(scope ref T t)
{
    t.val = 12;
    return t;
}

Another question, how would a reference counted pointer take advantage of scope, i.e. avoid the increment/decrement when being passed to a function?
One solution would be to add a function that returns a scoped reference to the underlying value.
    struct RefCounted(T)
    {
        scope ref T borrow() { return *p; }
    }
Will it be possible to deduce, that the lifetime of that scoped value is tied to the smart pointer?
December 04, 2014
I am not expert in such things, but here are few comments and questions.

> Errors for scope violations are only reported in @safe code.

This seems acceptable only if the compiler switch "-scope" implies functions to be @safe by default and @system on request, because currently lot of D programmers don't apply annotations like @safe to their D code. Opt-in safety doesn't work well (and in D we still have the problems caused by null pointers and references).

- - - - - - - - - -

Also consider an annotation like "!scope" or "@escape" for the opposite purpose.

- - - - - - - - - -

>Delegates currently defensively allocate closures with the GC. Few actually escape, and with scope only those that actually escape need to have the closures allocated.<

So there's no need for extra annotations to make delegates @nogc in most cases?

- - - - - - - - - -

Regarding array literals, some people proposed a syntax for fixed-size arrays to avoid heap-allocations (the "s" after the array literal):

void foo(int[2]) {}
void bar(int[]) {}
void main() @nogc {
    foo([1, 2]s);
    bar([1, 2]s);
}


Is DIP69 able to infer those arrays can be both stack-allocated? Is the "s" annotations still useful?

- - - - - - - - - -

Regarding the benefits, is escape analysis going to be used to allocate _automatically_ some small dynamic arrays and classes/structs on the stack instead of heap?

And is escape analysis going to automatically give hints to the GC to deallocate faster GC-allocated memory that doesn't escape?

void foo() {
    // Both dynamic arrays don't escape foo

    // Automatically stack allocated.
    auto a = new int[3];

    // Heap-allocated but deterministically
    // deleted at the end of foo scope.
    auto b = new int[10_000];
}

- - - - - - - - - -

Bye,
bearophile
December 04, 2014
On Thursday, 4 December 2014 at 09:25:11 UTC, Walter Bright wrote:
> http://wiki.dlang.org/DIP69

How inout fits the picture? It has some scope semantics too.
Section about expressions suggests you will tack scoping carefully, but then why would you need return by ref tricks, which don't rely on scope tracking and hence look hackable?
December 04, 2014
On Thursday, 4 December 2014 at 09:25:11 UTC, Walter Bright wrote:
> http://wiki.dlang.org/DIP69
>
> Despite its length, this is a fairly simple proposal. It adds the missing semantics for the 'scope' storage class in order to make it possible to pass a reference to a function without it being possible for it to escape.

Looks pretty solid, but I have one question based on the following two statements:

1) "Scope is inferred for function parameters if not specified, under the same circumstances as pure, nothrow, @nogc and safety are inferred."
2) "Scope is covariant, meaning it can be added to overriding functions."

How would this be handled in the current proposal?

class C
{
  int bar(ref T); // <-- inferred to be scope
}

class D : C
{
  override int bar(ref T); // <-- inferred to be NOT scope (but cannot remove scope when overriding)
}
December 04, 2014
>
> How would this be handled in the current proposal?
>
> class C
> {
>   int bar(ref T); // <-- inferred to be scope
> }
>
> class D : C
> {
>   override int bar(ref T); // <-- inferred to be NOT scope (but cannot remove scope when overriding)
> }

Attribute inference only works for function literals and template functions. So no inference is done for both methods. Template methods can not be overwritten.
December 04, 2014
"Walter Bright"  wrote in message news:m5p99m$luk$1@digitalmars.com...

> http://wiki.dlang.org/DIP69
>
> Despite its length, this is a fairly simple proposal. It adds the missing semantics for the 'scope' storage class in order to make it possible to pass a reference to a function without it being possible for it to escape.
>
> This, among other things, makes a ref counting type practical. It also makes it more practical to use other storage allocation schemes than garbage collection.
>
> It does not make scope into a type constructor, nor a general type-annotation system.
>
> It does not provide an ownership system, though it would complement one.

This looks really good.  Nice work. 

December 04, 2014
On 12/4/14 4:24 AM, Walter Bright wrote:
> http://wiki.dlang.org/DIP69
>
> Despite its length, this is a fairly simple proposal. It adds the
> missing semantics for the 'scope' storage class in order to make it
> possible to pass a reference to a function without it being possible for
> it to escape.
>
> This, among other things, makes a ref counting type practical. It also
> makes it more practical to use other storage allocation schemes than
> garbage collection.
>
> It does not make scope into a type constructor, nor a general
> type-annotation system.
>
> It does not provide an ownership system, though it would complement one.

"There can be at most one owner for any piece of data."

This doesn't seem right. For GC data, the GC owns the data, that is true. But for Ref-counted data, there is more than one owner, and only when all the owners disown the data can it be destroyed.

I think there is a disconnect here, you can't say *nobody* owns the data, and if you say one variable owns the data, which one is it?

Continuing to read...

-Steve
December 04, 2014
On 12/4/14 4:24 AM, Walter Bright wrote:
> http://wiki.dlang.org/DIP69
>
> Despite its length, this is a fairly simple proposal. It adds the
> missing semantics for the 'scope' storage class in order to make it
> possible to pass a reference to a function without it being possible for
> it to escape.
>
> This, among other things, makes a ref counting type practical. It also
> makes it more practical to use other storage allocation schemes than
> garbage collection.
>
> It does not make scope into a type constructor, nor a general
> type-annotation system.
>
> It does not provide an ownership system, though it would complement one.

"Scope affects:

    local variables allocated on the stack"

...

"scope int i;       // scope is ignored because integers are not references and so are not views"

I think I understand what you are trying to say -- the (big S) Scope of a local variable cannot escape, but it serves no purpose to declare a local int as (keyword) scope, since it's not going to be assigned any references.

But it reads contradictory.

-Steve