1 day ago

On Saturday, 10 May 2025 at 03:52:34 UTC, Walter Bright wrote:

>

On 5/4/2025 11:52 PM, Dukc wrote:

>

You have to admit this makes our checker, as it currently stands, unusable for what many of us consider the primary purpose of a borrow checker.

The borrow checker works on functions marked with @live. Just like safe checks are only on functions marked @safe. Both are usable.

No aknowledgement of the langauge shortcoming multiple people have to pointed out again and again. You're still talking as it wasn't there.

I have hard time believing a successful programming language designer wouldn't just get it. Instead, I'm assuming you have a marketing philosophy that tells you to avoid admitting things like this because it'd be more important to show faith in the language and inspire confidence in it.

Maybe this sort of thinking has it's place when we're at news.ycombinator.com and the topic is about merits of the language in general. But this is largely a design discussion, and the participants are largely those who are already committed to the language. Discussions like this can't move forward without common understanding of the problem.

It is true that there could still be someone who searches for "D borrow checker" or something, lands on this discussion and goes for Rust instead when there's a confirmation our borrow checker doesn't do the same things. But hiding problems here runs into what I see as a far greater risk: The debators, who want to improve the language, or see it improving, will get frustated if they don't see the leadership treating their input seriously, which will lead to loss of morale and contributors if it goes too far. So please don't treat these issues with a "fake it till you make it" - attitude.

1 day ago
On 5/10/2025 5:10 AM, Manu wrote:
> Okay, so then why should `scope` need `@safe`? 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`...?

Because in @system code, you can do whatever you want. But to signal to the caller that it is `scope`, add the attribute to the parameter list. It's up to the programmer to live up to that promise.

@system could should really be minimized in a properly designed program. That's why we're moving to safe by default.
1 day ago
On 11/05/2025 3:34 AM, Walter Bright wrote:
>     If you do write it, you have clearly and unambiguously indicated
>     that you DO want escape analysis, so it should happen. I can't see
>     any reason a second unrelated attribute should be required in
>     conjunction to make the first one work... you write |scope| thinking
>     it will be effective, and then by not writing (or forgetting to
>     write) the other thing, your code is now lying to you. You won't
>     know this until you are bitten by the escape bug that you were
>     trying to prevent; making the sutuation actually /worse/ than
>     useless, because when you're trying to track down your bug, you will
>     see the attribute, and continue looking elsewhere. |scope| should
>     work when you write it; period. If that is to say that writing |
>     scope| infers the other attribute, whatever... but it's not a
>     reasonable situation where |scope| silently does nothing and
>     confuses or misleads the author.
> 
> It does work when you write it. The "second unrelated attribute" (which I assume is the "return" attribute) is necessary to indicate if the scope'd pointer returns or not. Not having the |return| attribute means the following code is impossible to write:
> 
> |int* = foo(scope int* a) { return a; } // error: `a` is escaping via return! scope int* p = ...; scope int* q = foo(p);|

There is also the mess with ``return ref`` vs ``return``, that can be written as ``return scope`` and ``scope return``.

These both have the same escape set, just a different relationship strength.

This is of course one of the worst design decisions the D community has ever implemented with full regret by all parties involved! :)

This is also a good time to remember that DIP1000 only understands no escape, escape into return value OR this pointer. No multiple output support, which severely limits its capabilities.

1 day ago
On 11/05/2025 12:51 AM, Timon Gehr wrote:
> If this is really your perspective, it is better to just drop borrow checking as a direction. It seems your design constraints are self- contradictory assuming that utility is one of them. The current design does not incentivize people to use it, it just makes it not very useful.

I'm inclined to suggest @live is still savable, tie it to @restrict and it'll be useful to people doing SIMD type data processing.

However that isn't borrow checking, that is something new that I don't think is in the literature currently.

1 day ago
On 11/05/2025 6:06 AM, Dukc wrote:
> I have hard time believing a successful programming language designer wouldn't just get it. Instead, I'm assuming you have a marketing philosophy that tells you to avoid admitting things like this because it'd be more important to show faith in the language and inspire confidence in it.

There is no need for this language.

Everything that I have seen and know about Walter strongly suggests that he doesn't understand where we are diverging.

It may not be helping that to solve this involves slower DFA's and the addition of a type qualifier.

I can prove that the former doesn't need to be the default (and I am trying to do so by implementing it).

1 day ago
1. `scope` is not part of the type. It is a storage class, not a type modifier. The only type modifiers are immutable, const, shared and inout. Those are pervasively handled throughout the compiler's dealings with types. Making a new pointer type would be a huge effort *in addition* to all the other work needed to make a borrow checker.

2. We have a lot of experience with transitive attributes. There's a lot of resistance to using them because of this. Just look at all the complaints about `nogc` being transitive. Personally, I find `const` being transitive as a serious impediment to using `const` in the dmd source code. One of the big problems is it doesn't work with the Visitor pattern. (There are a couple cases where `const` is just cast away, shame on me.)

3. I'm well aware that ideally @live would be sounder if it is transitive. I disagree with the notion that it is useless if it is not. I am 98% sure that if @live was made transitive, it would be instantly useless because nobody is going to be willing to make an existing program or library pass the borrow checker. (It took enormous effort for Rust to convince people they had to throw their existing code away and recode it from scratch to use the borrow checker.) Much of the existing code would have to be thrown out. Making a perfect borrow checker is the enemy of making a practical, useful one.

4. Making dip1000 transitive made it impractical to use in existing code.

5. dip1000 makes it an error to assign a scope pointer to multiple indirections (because scope isn't a type modifier).

6. When an @live function calls another function, a `scope` parameter is a borrow, and a non-scope parameter is an ownership transfer.

7. Compiling an @live function is slow because of the DFA. Making it transitive would make it apply to the whole program, which would then compile as slow as Rust.

1 day ago
On Saturday, 10 May 2025 at 20:27:16 UTC, Richard (Rikki) Andrew Cattermole wrote:
> On 11/05/2025 6:06 AM, Dukc wrote:
>> I have hard time believing a successful programming language designer wouldn't just get it. Instead, I'm assuming you have a marketing philosophy that tells you to avoid admitting things like this because it'd be more important to show faith in the language and inspire confidence in it.
>
> There is no need for this language.
>
> Everything that I have seen and know about Walter strongly suggests that he doesn't understand where we are diverging.

That reminds me I haven't watched Groundhog Day for a while.
1 day ago
On 5/10/2025 6:07 AM, Derek Fawcus wrote:
> D itself already has 3 different types of pointer: references, pointers, arrays/slices.

Plus `this`, lazy, delegates, associative arrays and class references.

They were part of the initial design of D, the language grew up around them.

They've also made for making dip1000 very complex to implement.

Trying to fold in a new pointer type is a huge change.

(If I was doing a do-over for D, I'd look hard at dumping about half of those. I tried to get rid of lazy a few years ago, but got a lot of pushback on it.)

Microsoft's Managed C++ has regular pointers and gc pointers, distinguished with different syntax. It was a failure in the marketplace.



1 day ago
On 5/10/2025 11:06 AM, Dukc wrote:
> No aknowledgement of the langauge shortcoming multiple people have to pointed out again and again. You're still talking as it wasn't there.

I've acknowledged it several times, and pointed out the problems with the proposed solutions (transitivity, new pointer types).

Rust is a one-note language. Everything revolves around the borrow checker. That does not work with D, which is a polyglot language. A borrow checker has to fit in with the rest of the language. Of course that means compromise. Compromise doesn't mean it's useless.

1 day ago
On 5/10/2025 1:17 PM, Richard (Rikki) Andrew Cattermole wrote:
> There is also the mess with ``return ref`` vs ``return``, that can be written as ``return scope`` and ``scope return``.

That came about because of the existence of `ref`. Consider `ref int* p`. How do you model the scope-ness of the reference and the scope-ness of the pointer?


> These both have the same escape set, just a different relationship strength.

Strength??


> This is of course one of the worst design decisions the D community has ever implemented with full regret by all parties involved! :)

The concept behind it works fine. The trouble comes with the complexity of all the pointer constructions, like the invisible use of `this` references.


> This is also a good time to remember that DIP1000 only understands no escape, escape into return value OR this pointer.

That's sufficient to prevent an escaping pointer to the stack. It's quite solid. If you disagree, post a code snippet demonstrating it.


> No multiple output support, which severely limits its capabilities.

It does not severely limit it. Even the Rust manual says it's a rare case. It's a minor inconvenience that can be refactored away.