3 days ago
On 5/4/2025 11:03 AM, Dukc wrote:
> Like I wrote above, you can only depend on `@live` for `@safe`ty if you use it everywhere.
It doesn't have to be all or nothing in order to be useful. Just like we use @safe on some functions, and @system on others.
3 days ago
On 05/05/2025 8:50 AM, Walter Bright wrote:
> The point of the borrow checker is to ensure there is exactly one point of origin for a pointer and exactly one point of termination for it.

Hang on, that isn't the point of it at all.

A borrow checker has got the _side effect_ of only having one entry and exit point for an object.

But the _objective_ is to loosen the restrictions that an _ownership transfer system_ imposes on the type system whilst keeping its guarantees.

We do not have an ownership transfer system in D. Therefore we cannnot have a borrow checker.

What we do have is a liveliness analysis with guaranteed modelability, and we do have a use for that, @restrict.

Enforcing @restrict could be an incredibly useful tool to those who do data processing with simd, right now they are doing this by hand.

2 days ago

On Sunday, 4 May 2025 at 22:12:25 UTC, Walter Bright wrote:

>

On 5/4/2025 11:03 AM, Dukc wrote:

>

Like I wrote above, you can only depend on @live for @safety if you use it everywhere.

>

It doesn't have to be all or nothing in order to be useful. Just like we use @safe on some functions, and @system on others.

If you mean useful as a linting tool, maybe.

But Rust's borrow checker lets you to write safe code that would have to be unsafe without the checker.

The D borrow checker doesn't. Everything that can be @safe with the borrow checker can be @safe without, unless you commit to never use @safe without @live. If you think this isn't the case, try writing a code counterexample. I don't think you can do it.

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.

1 day ago

On Monday, 5 May 2025 at 06:52:09 UTC, Dukc wrote:

>

[snip]

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.

It might be helpful to example where Rust's version of some code let's you prove something is safe with the borrow checker, but D's version doesn't.

1 day ago

On Tuesday, 6 May 2025 at 14:48:27 UTC, jmh530 wrote:

>

It might be helpful to example where Rust's version of some code let's you prove something is safe with the borrow checker, but D's version doesn't.

You're right. Have a look at my post earlier on this thread:

>

On Tuesday, 29 April 2025 at 17:12:41 UTC, Walter Bright wrote:

>

So I implemented a borrow checker for D, and it is enabled by adding the @live annotation for a function, which turns on the borrow checker for that function. There are no syntax or semantic changes to the language, other than laying on a borrow checker.

There's a difference.

In Rust, as I understand it, if you have a function like

fn free(ptr: MyCustomPointer)
{   // ...
}

it is 100% safe to use. The compiler will not let you double-free or use after free, unless you use the unsafe block to do so.

But you can't have

@trusted void free(MyCustomPointer ptr)
{   // ...
}

in D because it would be unsafe to use from a non-@live function.

If we had a way to say that "this function can be called from @safe, if and only if it's usage is guarded with @live" then it would be equal to the Rust borrow checker.

22 hours ago
On Sunday, 4 May 2025 at 11:02:27 UTC, Paul Backus wrote:
> On Saturday, 3 May 2025 at 19:22:20 UTC, Walter Bright wrote:
>> In Rust you can use "unsafe" to avoid the borrow checker.
>
> Also, this is not true, which you would know if you had read literally anything about unsafe Rust:
>
>> You can take five actions in unsafe Rust that you can’t in safe Rust, which we call unsafe superpowers. Those superpowers include the ability to:
>>
>> * Dereference a raw pointer
>> * Call an unsafe function or method
>> * Access or modify a mutable static variable
>> * Implement an unsafe trait
>> * Access fields of a union
>>
>> It’s important to understand that unsafe doesn’t turn off the borrow checker or disable any other of Rust’s safety checks
>
> Source: https://doc.rust-lang.org/book/ch20-01-unsafe-rust.html
>
> This page is the first result on Google for "unsafe rust". The fact that you got this wrong shows very clearly that you have not done your homework on this topic.

Walter's admission that he has not written even a single line of Rust code raises a similar concern. Reading Rust documentation is necessary but not sufficient for acquiring a real understanding of the borrow checker (would you get into a self-driving car having software written by someone who doesn't drive?). I've written about 10000 lines of working Rust code, so while I would not claim to be the world's preeminent expert on the language, I've been in the trenches with it. You cannot learn from reading a book what this taught me.

This also strikes me as an instance of gluing yet another wart onto this language.
11 hours ago

On Tuesday, 6 May 2025 at 20:12:18 UTC, Dukc wrote:

>

On Tuesday, 6 May 2025 at 14:48:27 UTC, jmh530 wrote:

>

It might be helpful to example where Rust's version of some code let's you prove something is safe with the borrow checker, but D's version doesn't.

You're right. Have a look at my post earlier on this thread:

>

On Tuesday, 29 April 2025 at 17:12:41 UTC, Walter Bright wrote:

>

So I implemented a borrow checker for D, and it is enabled by adding the @live annotation for a function, which turns on the borrow checker for that function. There are no syntax or semantic changes to the language, other than laying on a borrow checker.

There's a difference.

In Rust, as I understand it, if you have a function like

fn free(ptr: MyCustomPointer)
{   // ...
}

it is 100% safe to use. The compiler will not let you double-free or use after free, unless you use the unsafe block to do so.

But you can't have

@trusted void free(MyCustomPointer ptr)
{   // ...
}

in D because it would be unsafe to use from a non-@live function.

If we had a way to say that "this function can be called from @safe, if and only if it's usage is guarded with @live" then it would be equal to the Rust borrow checker.

Ah, I remember that. Thanks.

Just to be clear, the @trusted function you provide could be called by an @safe function, but your point is that it may actually be unsafe to do so. The real goal is to enable more code to actually be safe, not to just slap @trusted on things.

The examples in the @live spec don't reference @safe. But it does have an example of a non-@live release function that is called by an @live test function that prevents use after free.

I can think of a few different ways forward (by no means limited to just this)

  1. Do @safe inference on @live functions. I assume a body is needed on @live functions (Rust requires a body unless a trait or extern function, and extern is only allowed in unsafe code). So that might be good idea on its own merits.

That being said, it doesn't really help you if the @live function is calling an @system function. Also, @live functions can call non-@live functions (although for an @safe @live function all the functions called by it need to be @safe/@trusted too), so it wouldn't necessarily be a transitive inference all the way down (i.e. it hits the first unattributed function and becomes @system).

  1. Enhance the @safe definition so that an @safe @live function can call an @system function so long as the function it calls abides by certain restrictions. Obviously, the spec would need to clearly state what the restrictions are. One limitation would be that to verify that a @system function abides by these restrictions would require having the function body.

  2. Add a @safeiflive attribute such that the function is @safe if called by a @live function and @system otherwise. As above, the team would need to pin down exactly what is allowed. After all, why couldn't it just be marked @safe? What @safe restrictions could be relaxed if @live is being enforced. Would require some thought, I imagine, but probably useful to think about. The downside is that it's more attributes.

  3. Add @trustediflive, similar to above such that it is @trusted if called by a @live function and @system otherwise. Let's the user make the decision, more flexible. I think @trustediflive is kind of in line with what you were suggesting.

2 hours ago
On 5/7/25 16:47, jmh530 wrote:
> 
> I can think of a few different ways forward (by no means limited to just this)

Well, the big issue here is that @live is still not transitive. A function attribute is not really the right way to go about this anyway. Aliasing is a property of a pointer, not a function.
22 minutes ago
On Wednesday, 7 May 2025 at 23:21:12 UTC, Timon Gehr wrote:
> On 5/7/25 16:47, jmh530 wrote:
>> 
>> I can think of a few different ways forward (by no means limited to just this)
>
> Well, the big issue here is that @live is still not transitive. A function attribute is not really the right way to go about this anyway. Aliasing is a property of a pointer, not a function.

And this is exactly what Rust does with the borrowed/raw pointer distinction. Walter how can you claim to have studied the Rust spec yet miss and/or disregard this fundamental detail? And do not bring up that extremely outdated and irrelevant example of near/far pointers in DOS.
1 2 3 4 5 6
Next ›   Last »