November 09, 2021

On Tuesday, 9 November 2021 at 11:56:50 UTC, Atila Neves wrote:

>

It might just be my biases but I think this is a more useful nut to crack. And the only way to crack it is to some sort of ownership system, since there's no way currently in D to have a compile-time guarantee that there's only one alias left.

Great mind think alike. i was considering rebooting this challenge dropping the RC part altogether. Just reimplement slices such as they behave like the builtin ones is enough of a challenge already.

November 09, 2021

On Tuesday, 9 November 2021 at 11:56:50 UTC, Atila Neves wrote:

>

I'll hijack this thread with a slide from my DConf Online 2020 talk, because with the current language it's impossible for a library writer to write a useful @safe vector struct:

scope v = vector(1, 2, 3, 4);
scope s = v[];
v ~= 5;  // could reallocate here
s[3] = 42;  // oops

Hm, if the vector had a reference count and would crash if appended to when the count is non-zero?

Functions like these could also solve the thing if only called from @live:

AppendableVector setupAppending(Vector*);
Vector stopAppending(AppendableVector*);

Obviously, you could not slice an AppendableVector, and we're not proposing that average application code should be @live so not a very good solution.

>

I initialy "solved" this with @trusted, but fortunately somebody on the forums pointed out I was being an idiot.

If that makes anybody idiot, I doubt there are many normal-minded programmers. Let alone geniuses.

November 09, 2021
On Tuesday, 9 November 2021 at 11:19:38 UTC, deadalnix wrote:
> Yes. In addition, it is worth mentioning that many functional programming languages are using reference counting internally. It is so that they can do copy on write instead of copying everything all the time for no reason.

Functional programming language design and implementation can be useful to think about, yes.

The main point is that if you say "built in" then you are allowed to do things that seemingly break the rules, but only if you can imagine a corresponding simple hypothetical implementation that shows that the type system invariants actually are upheld.

One such hypothetical implementation could be to pass in a "reference tracker database" as a hidden parameter in all function calls and use that for acquire/release/destruction.

This is impractical, but if that is sufficient to uphold all invariants, then you only have to prove that an efficient implementation is equivalent to the hypothetical implementation.

I think.

November 09, 2021

On Tuesday, 9 November 2021 at 15:26:24 UTC, Dukc wrote:

>

On Tuesday, 9 November 2021 at 11:56:50 UTC, Atila Neves wrote:

>

I'll hijack this thread with a slide from my DConf Online 2020 talk, because with the current language it's impossible for a library writer to write a useful @safe vector struct:

scope v = vector(1, 2, 3, 4);
scope s = v[];
v ~= 5;  // could reallocate here
s[3] = 42;  // oops

Hm, if the vector had a reference count

Then it wouldn't be a vector.

>

Functions like these could also solve the thing if only called from @live:

AppendableVector setupAppending(Vector*);
Vector stopAppending(AppendableVector*);

Obviously, you could not slice an AppendableVector, and we're not proposing that average application code should be @live so not a very good solution.

The main point of vector is that one can append to it without using the GC. I guess that "this thing has a length only known at runtime that won't change and doesn't use the GC" is useful too, but not nearly as much as being able to append.

November 09, 2021

On Tuesday, 9 November 2021 at 15:37:13 UTC, Atila Neves wrote:

>

[snip]

The main point of vector is that one can append to it without using the GC. I guess that "this thing has a length only known at runtime that won't change and doesn't use the GC" is useful too, but not nearly as much as being able to append.

Regardless, the limitations of the language and the solutions brought up have been discussed on the forums for years. Getting some kind of pathway forward is really what is needed. Breaking the problem that Andrei brings up into a smaller one, i.e. writing a @safe appendable vector that works as much like a built-in one, is a useful start.

November 09, 2021

On Tuesday, 9 November 2021 at 15:26:24 UTC, Dukc wrote:

>

Functions like these could also solve the thing if only called from @live:

void foo(void*) @safe @nogc pure nothrow @live @doYouStillRememberWhatTheFunctionNameIs
{}

How many more attributes do we need before we realize that is not the way to write ANY code?

November 09, 2021
On 09.11.21 17:12, Stanislav Blinov wrote:
> On Tuesday, 9 November 2021 at 15:26:24 UTC, Dukc wrote:
> 
>> Functions like these could also solve the thing if only called from `@live`:
> 
> void foo(void*) @safe @nogc pure nothrow @live @doYouStillRememberWhatTheFunctionNameIs
> {}
> 
> How many more attributes do we need before we realize that is not the way to write ANY code?
It's uniquely bad in the case of @live, as ownership/borrowing of arguments and return values is not actually a property of the function.
November 09, 2021

On Tuesday, 9 November 2021 at 16:12:25 UTC, Stanislav Blinov wrote:

>

How many more attributes do we need before we realize that is not the way to write ANY code?

I don't know, but you have them in C++ too unfortunately.

November 09, 2021
On Tuesday, 9 November 2021 at 16:30:41 UTC, Timon Gehr wrote:

> It's uniquely bad in the case of @live, as ownership/borrowing of arguments and return values is not actually a property of the function.

Really? I thought @live wasn't unique. I mean, uh:

```
auto ref inout(T) thing(T)(auto ref return scope inout T delegate(ref return scope T) nothrow @nogc pure [1] dg...) return scope pure @nogc @safe nothrow;
```

'Tis of course off-topic to this discussion, but jeebuz, this has to end somewhere!
November 09, 2021

On Tuesday, 9 November 2021 at 06:32:40 UTC, tsbockman wrote:

>

On Tuesday, 9 November 2021 at 03:43:01 UTC, Paul Backus wrote:

>

On Tuesday, 9 November 2021 at 01:14:24 UTC, tsbockman wrote:

>

With current language semantics, the destructor (and any other similar operations, such as reassignment) of the reference type must be @system to prevent misuse of the destructor in @safe code.
https://issues.dlang.org/show_bug.cgi?id=21981

The solution to this problem is to introduce some way of telling the compiler, "this destructor is @safe to call automatically at the end of the object's scope, but @system to call early or manually."

I believe it is also possible to make this @safe by doing borrow checking at runtime, although it would introduce some overhead, and make the API less ergonomic.

How? All of the runtime borrow checking schemes that I have considered turn out to have the same fundamental problems as reference counting, when examined closely.

Here's a basic sketch of the scheme I had in mind: https://gist.github.com/run-dlang/d1982a29423b2cb545bc9fa452d94c5e

It's entirely possible I've overlooked something and this is actually unsound. As Andrei says: "destroy!"