6 hours ago

On Saturday, 10 May 2025 at 12:10:48 UTC, Manu wrote:

>

Okay, so then why should scope need @safe?

The escape checker can only maintain its invariants in @safe code, because in @system code, anything goes. scope pointers can be laundered by casting to size_t and back for example. Now you could argue that the same holds for const and immutable, but we still do the checks in @system code for linting purposes, requiring an explicit cast() to remove const. I'm not against scope checking in @system code per se, but there are some differences that make it more complicated. There is currently no cast(notscope) for example.

>

It's an additional attribute added in its own right; there's no apparent value to requiring a SECOND attribute's presence in order to make the first attribute take effect. scope should work when you write scope. If you don't want scope checking, don't write scope...?

While there's in theory a single meaning of scope, in practice, the attribute is used for different things:

  1. Document the lifetime of a variable
  2. Let the compiler enforce that lifetime
  3. Turn GC allocations of classes / arrays into stack allocations
  4. Run class destructors deterministically

While those usually align, different people put a different aspect first. For example, some consider scope to be basically C#'s stackalloc and believe the programmer is straight up asking to overflow the stack here:

void main()
{
    scope int[] arr = new int[32_000_000];
}

https://github.com/dlang/dmd/issues/20770#issuecomment-2615115810

Others may just care about running a class destructor. Now what happens if we enable scope checking everywhere?

void main() @system
{
    scope Object o = new Object();
    const h = o.toHash();
    // Error: scope variable `o` calling non-scope member function `Object.toHash()`
}

Oops, that method is not marked scope. class methods rarely escape their this pointer, but since it is possible to override methods, scope can't be inferred, requiring annoying and ugly scope annotations everywhere.

A similar issue can happen with ImportC:

import glfw;

void copy(scope const(char)[] str) @trusted
{
    assert(str.length > 0 && str[$ - 1] == '\0');
    glfwSetClipboardString(window, str.ptr);
}

I've read the documentation of glfw which says glfwSetClipboardString copies the input string, but I can't annotate the parameter in glfw.h with scope because it doesn't exist in C.

Finally, mechanical scope checking has false positives:

void f(ref scope S ctx)
{
    const old = ctx;
    g(ctx);
    ctx = old; // Error: scope variable `old` assigned to `ref` variable `ctx` with longer lifetime

}

Some of these are bugs / limitations which can be improved, but in general it's impossible to do perfect scope checking (Rice's theorem). Even your example of assigning a scope pointer to a global variable can be valid if you manually restrict read access to that global to the current scope using @system variables and the right @trusted code.

Now like I said, I'm not against the idea per se. I have recently debugged a use-after-free bug from returning a scope array in code that I didn't mark @safe yet, which would have been caught immediately otherwise. But the considerations are:

  • Code breakage
  • Different expectations of scope from different people
  • Nuisance with scope classes
  • Passing scope pointers to C functions
  • False positive errors
  • "Trust me, this parameter scope"
5 hours ago
On Sunday, 11 May 2025 at 20:43:52 UTC, Paul Backus wrote:
> [snip]
>
> The reason for the negativity is that people do not want "a borrow checker." What they want is more powerful safety analysis. A borrow checker is merely one possible means of achieving that goal.
>
> In business terms, this is a failure of "product-market fit." You are supplying something that there is no demand for. Even if it works perfectly, nobody is going to buy it.

Agreed.

But I think "what people want" and "what's the goal here" are two different kinds of questions. What people want is more powerful safety analysis. But the reason why Walter started working on this was that he saw safety as becoming a bigger issue in programming languages, most notably with Rust gaining traction, and wanted to help D compete on that basis. So I think one thing that has Walter frustrated is that he wants to be able to say D has a borrow checker when someone asks, but the actual users don't want something unless it actually enables the more powerful safety analysis.

And at the same time, people are frustrated with half-baked implementations of things. At least if Walter stops working on @live, then it wouldn't have been made a part of the language.

But at the end of the day, I think there are a lot of people who are on board with more powerful safety analysis, provided it is done right.
4 hours ago

On Monday, 12 May 2025 at 11:52:47 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

On 12/05/2025 11:16 PM, Manu wrote:
We should disallow it for @system functions, they do not interact with any static analysis in any way.

scope on a @system function parameter is not only useful as a form of documentation, it actually also affects the caller:

void f(scope int[]) @nogc;

void g() @nogc
{
    f([1, 2]);
}

Remove scope, it no longer compiles.

4 hours ago
On 13/05/2025 2:50 AM, Nick Treleaven wrote:
> On Monday, 12 May 2025 at 11:52:47 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> On 12/05/2025 11:16 PM, Manu wrote:
>> We should disallow it for @system functions, they do not interact with any static analysis in any way.
> 
> `scope` on a `@system` function parameter is not only useful as a form of documentation, it actually also affects the caller:
> 
> ```d
> void f(scope int[]) @nogc;
> 
> void g() @nogc
> {
>      f([1, 2]);
> }
> 
> ```
> Remove `scope`, it no longer compiles.

I'm aware.

In this scenario that function would need to be made ``@trusted``.

4 hours ago
On Monday, 12 May 2025 at 14:58:08 UTC, Richard (Rikki) Andrew Cattermole wrote:
> On 13/05/2025 2:50 AM, Nick Treleaven wrote:
>> ```d
>> void f(scope int[]) @nogc;
>> 
>> void g() @nogc
>> {
>>      f([1, 2]);
>> }
>> 
>> ```
>> Remove `scope`, it no longer compiles.
>
> I'm aware.
>
> In this scenario that function would need to be made ``@trusted``.


But what if it doesn't have a safe interface - e.g. it writes an unsafe value to a global? It cannot be `@trusted`.
4 hours ago
On 13/05/2025 3:03 AM, Nick Treleaven wrote:
> On Monday, 12 May 2025 at 14:58:08 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> On 13/05/2025 2:50 AM, Nick Treleaven wrote:
>>> ```d
>>> void f(scope int[]) @nogc;
>>>
>>> void g() @nogc
>>> {
>>>      f([1, 2]);
>>> }
>>>
>>> ```
>>> Remove `scope`, it no longer compiles.
>>
>> I'm aware.
>>
>> In this scenario that function would need to be made ``@trusted``.
> 
> 
> But what if it doesn't have a safe interface - e.g. it writes an unsafe value to a global? It cannot be `@trusted`.

Then strictly speaking it shouldn't be ``scope``.

Otherwise for codegen only changes, a new attribute in core.attributes would be needed.

Of course we could always leave it as is, and accept that its pragmatic.

4 hours ago
On Monday, 12 May 2025 at 08:26:28 UTC, Walter Bright wrote:
> On 5/11/2025 2:01 PM, claptrap wrote:
>> Might help to find a way to figure it out sooner tho, maybe some kind of proposal system where people could critique it before you waste your time doing all that work?
>
> Presenting a working solution is more effective than a proposal.

More effective at demonstrating the idea, not at all effective at avoiding time wasted on stuff nobody wants though, which was *actually* my point.
3 hours ago
On Monday, 12 May 2025 at 13:45:04 UTC, jmh530 wrote:
> But I think "what people want" and "what's the goal here" are two different kinds of questions. What people want is more powerful safety analysis. But the reason why Walter started working on this was that he saw safety as becoming a bigger issue in programming languages, most notably with Rust gaining traction, and wanted to help D compete on that basis.

Here, you say that the goal of @live is to compete with Rust on safety.

> So I think one thing that has Walter frustrated is that he wants to be able to say D has a borrow checker when someone asks, but the actual users don't want something unless it actually enables the more powerful safety analysis.

Here, you say that the goal of @live is "to be able to say D has a borrow checker."

The problem is that these are not the same goal. Walter's work on @live has (arguably) succeeded in advancing goal #2, but it has done nothing to advance goal #1.

Personally, I believe that goal #1 is much more important than goal #2, and that spending effort to pursue #2 while ignoring #1 is a mistake. If Walter disagrees, I can accept that, although I would like to at least see him make the positive case for why goal #2 is worth pursuing on its own.
1 hour ago
On 5/12/2025 2:24 AM, Manu wrote:
> __gshared int* g;
> void test(scope int* x)
> {
>      g = x;
> }

Need to add @safe. Unadorned functions are @system.
58 minutes ago
On 5/12/2025 3:55 AM, Manu wrote:
> So, if it only works with @safe, I repeat again; WHY?

So you can break the rules in @system code.

We are trying to move towards @safe by default, but the new editions feature is needed first.