November 09, 2021

On Tuesday, 9 November 2021 at 17:04:29 UTC, Paul Backus wrote:

>

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

Destruction commenced under the gist.

November 09, 2021

On Tuesday, 9 November 2021 at 15:54:01 UTC, jmh530 wrote:

>

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.

This is already something we're looking into it as part of the vision for D. I personally will not rest until such a library type can be written and used in @safe code. Nobody* should be calling malloc/free, just like nobody should be writing new/delete in C++14 and newer.

  • Obviously for values of "nobody" that are tiny but not exactly equal to 0.
November 09, 2021

On Tuesday, 9 November 2021 at 17:15:59 UTC, Atila Neves wrote:

>

This is already something we're looking into it as part of the vision for D. I personally will not rest until such a library type can be written and used in @safe code. Nobody* should be calling malloc/free, just like nobody should be writing new/delete in C++14 and newer.

  • Obviously for values of "nobody" that are tiny but not exactly equal to 0.

Au contraire. EVERYBODY should be calling malloc/free or any other allocators, including the GC. No matter how hard you try, you CANNOT abstract the machine and remain a systems language at the same time. If you don't want to be worrying about such things, there are other, higher level, languages.

It's the calling of such APIs that must be made @safe. Walter is attempting just that with @live. Incidentally, if THAT is made possible, you will be able to have the cake and eat it too.

BTW, at the moment, "safety" of GC is a lie. Because it can run arbitrary unsafe code within a @safe function.

November 09, 2021
On Tue, Nov 09, 2021 at 05:26:32PM +0000, Stanislav Blinov via Digitalmars-d wrote:
> On Tuesday, 9 November 2021 at 17:15:59 UTC, Atila Neves wrote:
> 
> > This is already something we're looking into it as part of the vision for D. I personally will not rest until such a library type can be written and used in @safe code. Nobody* should be calling malloc/free, just like nobody should be writing new/delete in C++14 and newer.
> > 
> > 
> > * Obviously for values of "nobody" that are tiny but not exactly equal to 0.
> 
> Au contraire. EVERYBODY should be calling malloc/free or any other allocators, including the GC. No matter how hard you try, you CANNOT abstract the machine and remain a systems language at the same time. If you don't want to be worrying about such things, there are other, higher level, languages.

I think Atila's point is that *by default* you should be able to write high-level D code without needing to call malloc/free, but when necessary, you can do so *and* still take advantage of the high-level abstractions of the language (e.g., maintain @safe-ty, etc.).


> It's the calling of such APIs that must be made @safe.
[...]

IMO, that's not possible. In general code that calls malloc/free it's not possible to prove anything @safe. The only way you can do this in a waterproof way is to implement the equivalent of GC tracing at *compile-time* so that every call to free() can be proven to happen exactly once for every call to malloc(). This is obviously impossible.

In general, it's a mistake to mark malloc/free as @safe or pure, it's the wrong semantics and will only lead to trouble down the road.


T

-- 
Marketing: the art of convincing people to pay for what they didn't need before which you fail to deliver after.
November 09, 2021

On Tuesday, 9 November 2021 at 17:26:32 UTC, Stanislav Blinov wrote:

>

On Tuesday, 9 November 2021 at 17:15:59 UTC, Atila Neves wrote:

>

This is already something we're looking into it as part of the vision for D. I personally will not rest until such a library type can be written and used in @safe code. Nobody* should be calling malloc/free, just like nobody should be writing new/delete in C++14 and newer.

  • Obviously for values of "nobody" that are tiny but not exactly equal to 0.

Au contraire. EVERYBODY should be calling malloc/free or any other allocators, including the GC. No matter how hard you try, you CANNOT abstract the machine and remain a systems language at the same time. If you don't want to be worrying about such things, there are other, higher level, languages.

Could you please explain why you'd rather do that instead of using the equivalent of C++'s std::{vector, unique_ptr, shared_ptr} and Rust's std::{vector, unique_ptr, shared_ptr}? I cannot myself imagine why anyone would want to.

I think that C++'s greatest gift to the world was the destructor. We have those too! Let's use them.

>

It's the calling of such APIs that must be made @safe.

I think the focus should be in making it possible to write the types I mentioned above in a @safe manner.

My advice is that unless you have a very good reason not to, just use the GC and call it a day.

November 09, 2021

On Tuesday, 9 November 2021 at 18:33:01 UTC, Atila Neves wrote:

>

On Tuesday, 9 November 2021 at 17:26:32 UTC, Stanislav Blinov wrote:

>

On Tuesday, 9 November 2021 at 17:15:59 UTC, Atila Neves wrote:

>

This is already something we're looking into it as part of the vision for D. I personally will not rest until such a library type can be written and used in @safe code. Nobody* should be calling malloc/free, just like nobody should be writing new/delete in C++14 and newer.

  • Obviously for values of "nobody" that are tiny but not exactly equal to 0.

Au contraire. EVERYBODY should be calling malloc/free or any other allocators, including the GC. No matter how hard you try, you CANNOT abstract the machine and remain a systems language at the same time. If you don't want to be worrying about such things, there are other, higher level, languages.

Could you please explain why you'd rather do that instead of using the equivalent of C++'s std::{vector, unique_ptr, shared_ptr} and Rust's std::{vector, unique_ptr, shared_ptr}? I cannot myself imagine why anyone would want to.

Instead? Not instead. Together with. It's all well and fine to rely on proven library solutions. But I'd rather a D or C++ programmer, when faced with necessity, be able to write their allocations correctly, and not hide under a rug because Herb'n'Scott tell 'em that's "bad practice".

We already have at least two (three?) generations of programmers who literally have no clue where memory comes from. If we keep this up, in a couple decades "nobody" (your definition of nobody) would be able to write you a better malloc for your next generation of platforms and hardware.

Take a peek in the learn section. Person asks how to translate a simple C program into D. Buncha answers that all amount to "allocate craptons of memory for no reason". At least one from a very well known D educator. Only no one even mentions any allocations at all. Why even talk about it, right? That array just sort of happens out of nowhere...

>

I think that C++'s greatest gift to the world was the destructor. We have those too! Let's use them.

Yeah, we have them. And the GC may call them. Any time you allocate it may call them. Even if they aren't pure or safe. But hey, that's OK between friends.

> >

It's the calling of such APIs that must be made @safe.

I think the focus should be in making it possible to write the types I mentioned above in a @safe manner.

My advice is that unless you have a very good reason not to, just use the GC and call it a day.

Who, using a SYSTEMS language, should not have a reason to care about their memory? I can think of literally just one case: needing a quick script and being too lazy to switch to something other than D just for that.

November 09, 2021
On Tuesday, 9 November 2021 at 18:16:03 UTC, H. S. Teoh wrote:

> I think Atila's point is that *by default* you should be able to write high-level D code without needing to call malloc/free, but when necessary, you can do so *and* still take advantage of the high-level abstractions of the language (e.g., maintain @safe-ty, etc.).

Oh, I understand the sentiment, I really do. That we need more out-of-the-box tried and true robust containers is not in question - hence the premise of this very topic by Andrei. It's this constant desire to "abstract away" the very things that you literally *need* to operate on that puzzles me. Hey, raw pointers are bad, don't use! Hey, "new" is bad, don't call! Well if you're not using raw pointers and you aren't calling "new", there's Python. Or something. You don't get to keep the performance, and power, of low level languages, if you desperately abstract everything away. "Zero-cost" abstractions aren't a thing, it's a buzzword myth.

>
>> It's the calling of such APIs that must be made @safe.
> [...]
>
> IMO, that's not possible. In general code that calls malloc/free it's not possible to prove anything @safe. The only way you can do this in a waterproof way is to implement the equivalent of GC tracing at *compile-time* so that every call to free() can be proven to happen exactly once for every call to malloc(). This is obviously impossible.

Could be possible for allocators that don't need a free() for every malloc(). At least, I think it could be:

while (true)
{
    auto a = alloc.allocate(1);
    auto b = alloc.allocate(100500);
    // ...

    // if here you can prove that nothing escaped, the call is safe.
    // which means `allocate` needs to paint the result somehow.
    alloc.freeAll();
}

Yip, that is, effectively, manual GC.

> In general, it's a mistake to mark malloc/free as @safe or pure, it's the wrong semantics and will only lead to trouble down the road.

But if you can express ownership in the language, it should be possible to make at least a @safe interface to them.

November 09, 2021
On Tue, Nov 09, 2021 at 07:57:21PM +0000, Stanislav Blinov via Digitalmars-d wrote:
> On Tuesday, 9 November 2021 at 18:16:03 UTC, H. S. Teoh wrote:
[...]
> > > It's the calling of such APIs that must be made @safe.
> > [...]
> > 
> > IMO, that's not possible. In general code that calls malloc/free it's not possible to prove anything @safe. The only way you can do this in a waterproof way is to implement the equivalent of GC tracing at *compile-time* so that every call to free() can be proven to happen exactly once for every call to malloc(). This is obviously impossible.
> 
> Could be possible for allocators that don't need a free() for every
> malloc().

Yes, but then you're back to malloc/free (well, the C version of it) being inherently @system, and there is no way you can make them @safe.


[...]
> > In general, it's a mistake to mark malloc/free as @safe or pure, it's the wrong semantics and will only lead to trouble down the road.
> 
> But if you can express ownership in the language, it should be possible to make at least a @safe interface to them.

To be able to express ownership to the extent that you can do this, is basically equivalent to importing Rust into D. Is that really what we want to do?


T

-- 
It is widely believed that reinventing the wheel is a waste of time; but I disagree: without wheel reinventers, we would be still be stuck with wooden horse-cart wheels.
November 09, 2021
On 09.11.21 18:26, Stanislav Blinov wrote:
> 
> It's the calling of such APIs that must be made @safe. Walter is attempting just that with @live.

This is not true.

> Incidentally, if THAT is made possible, you will be able to have the cake and eat it too.

But we are on the same page here.
November 10, 2021

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

>

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.

Pedantic note, but as far as I can tell, this is a point that is often missed when discussing D: What you want isn't to avoid the GC, it is to avoid leaking.

You absolutely categorically want to allocate using the GC. If you don't, then you can't store anything that is managed by the GC within the vector, or you risk seeing it collected by the GC while it is still live.

What you do not want is to leak. Because leaking is what eventually leads to a GC cycle, which is actually what you want to avoid.