Benjamin Thaut:

give "scope" a meaning for function arguments other then lambdas E.g:

size_t count(scope int[] heystack, scope int[] needle);

Now the compiler can allocate the literal [1, 5] on the stack without any special syntax because it knows that the array literal will not be escaped.


With your suggestion this code should be accepted:

int foo(scope int[] items) @nogc {
    int total = 0;
    foreach (immutable x; items)
        total += x;
    return total;
}
void main() @nogc {
    assert(foo([1, 5, 3, 1, 5, 1, 5]) == 21);
}



While this can't be accepted because 'items' escapes the body of 'foo', so 'scope' forbids some valid code:

import std.algorithm: sum;
int foo(scope int[] items) @nogc {
    return foo.sum;
}
void main() @nogc {
    assert(foo([1, 5, 3, 1, 5, 1, 5]) == 21);
}



The []s syntax moves the control to the calling point, allowing more valid code to compile:

import std.algorithm: sum;
int foo(int[] items) @nogc {
    return foo.sum;
}
void main() @nogc {
    assert(foo([1, 5, 3, 1, 5, 1, 5]s) == 21);
}



A disadvantage of the []s syntax is that it's less safe than scope:

int[] global;
void foo() @nogc {
    bar([1, 5, 3, 1, 5, 1, 5]s);
}
void bar(int[] b) @nogc {
    global = b;
}
void main() {
    import std.stdio;
    foo();
    writeln(global);
}



But that usage of []s is not much worse than this currently accepted code, the difference is that the []s syntax makes this problem a bit less visible:

int[] global;
void foo() @nogc {
    int[7] a = [1, 5, 3, 1, 5, 1, 5];
    bar(a); // Implicit slicing.
}
void bar(int[] b) @nogc {
    global = b;
}
void main() {
    import std.stdio;
    foo();
    writeln(global);
}


(I think Jonathan M Davis suggested to disallow such implicit slicing, and require a "bar(a[]);".)


A possible way to increase the number of functions allowed by 'scope' is to allow a reference to escape if it goes into another 'scope':

int sum(scope int[] items) @nogc {
    int total = 0;
    foreach (immutable x; items)
        total += x;
    return total;
}
int foo(scope int[] items) @nogc {
    return sum(items); // Allowed.
}
void main() @nogc {
    assert(foo([1, 5, 3, 1, 5, 1, 5]) == 21); // Allowed.
}



(The problem with Scott Meyers' suggestion in the "The Last Thing D Needs" keynote is that to design a language/library feature that takes in account every other language/library part, you need a mind significantly larger than the average human one :-) ).

Bye,
bearophile

Reply via email to