November 11, 2019
On Monday, 11 November 2019 at 11:17:26 UTC, Jonathan M Davis wrote:
> D's strings _worse_ than C++'s strings. Sure, we'd still be able to get substrings more efficiently than C++ can, but not being able to append to a string makes it a pretty terrible string. At least C++'s strings can do that efficiently.

C++17 differentiate between the owner of the string:

https://en.cppreference.com/w/cpp/string/basic_string

And the "borrowed" slice of a string:

https://en.cppreference.com/w/cpp/string/basic_string_view

In C++20 this is extended to contiguous buffers with std::span.

November 11, 2019
On Monday, November 11, 2019 5:15:23 AM MST Dukc via Digitalmars-d wrote:
> On Monday, 11 November 2019 at 11:51:09 UTC, Jonathan M Davis
>
> wrote:
> > IMHO, the ability to append to a dynamic array without caring whether it's backed by GC-allocated memory, malloc-ed memory, stack allocated memory, or whatever is a huge benefit.
>
> Yeah... And I definitely think all of these should continue to exist with the possible exception of malloced memory.
>
> > Right now, you can pass a dynamic array that isn't backed by the GC to a function, and it all just works even if the function needs to do a reallocation to make the array large enough. Doing so is not necessarily a bug and allows you to use non-GC allocated memory where appropriate while still being able to grow the array, and it does so without the code having to care about what kind of memory is currently backing the dynamic array.
>
> But chances are that if you grow a malloced slice bu GC, you cause a memory leak, and that's what Walter is trying to solve. On the other hand, there should be a way for the caller to explicitly allow a function to grow a GC-allocated slice, without touching the function, and my idea does not solve that. I dunno...

Whether you risk causing a memory leak or not doesn't really have anything to do with whether reallocations can occur. The code needs to be aware of when the malloc-ed memory is definitely no longer used and then manually free it. It's certainly true that the lack of reference counting makes it harder to write code that uses slices of malloc-ed memory, but having slices of malloc-ed memory poses exactly the same risks of keeping those slices around too long whether ~= works on them or not. You either write the code in a way that you know when the slices are no longer used so that you know when you can free the memory, or you don't slice non-GC-allocated memory.

- Jonathan M Davis



November 11, 2019
On Monday, 11 November 2019 at 11:26:49 UTC, Nicholas Wilson wrote:
> is functional identical, thus any issues present in 2 are also present in 1. The suggestion that doing so in a loop would create more garbage is false as it is functionally identical.

There is a difference: a = a ~ b is guaranteed to make a copy while a ~= b might just use spare capacity of the memory that slice `a` refers to.

https://dlang.org/spec/arrays.html#array-concatenation

This is what the dead/alive example is supposed to express.
It is still true however that the rationale is not very convincing.
The first example indeed doesn't show any benefits of the DIP:

```
int[] slice = cast(int*)malloc(10 * int.sizeof)[0 .. 10];
slice = slice ~ 1; // now guaranteed to make a copy
free(slice.ptr); // Still oops
```

The following claim in the DIP is also unsubstantiated:

> This change is a necessary part of D evolving towards being memory safe without using
> a GC.

I would like to see an example of memory corruption in `@safe` code that can happen because of slice appending.

November 11, 2019
On Monday, 11 November 2019 at 10:27:26 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review for DIP 1025, "Dynamic Arrays Only Shrink, Never Grow":

These changes are becoming too big for a production language. They appear to be driven by the reasonable desire to fully separate D from the GC and add a stronger model for memory safety but with this extent of change would be more appropriate for a test version of D to develop the whole rather than piecemeal and potentially release as a D3.0 if the changes become sufficiently major when taken together.


November 11, 2019
On Monday, 11 November 2019 at 10:27:26 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review for DIP 1025, "Dynamic Arrays Only Shrink, Never Grow":
>
> https://github.com/dlang/DIPs/blob/1b525ec4c914c06bc286c1a6dc93bf1533ee56e4/DIPs/DIP1025.md
>
> [snip]


In that first example, the following
int[] slice = cast(int*)malloc(10 * int.sizeof)[0 .. 10];
doesn't actually compile.

You would compile it as
auto slice = cast(int*)malloc(10 * int.sizeof)[0 .. 10];

So actually
auto slice = cast(int*)malloc(10 * int.sizeof)[0 .. 10];
slice ~= 1;
generates an error because you can't append an int to an int*.

November 11, 2019
On Monday, 11 November 2019 at 13:25:35 UTC, jmh530 wrote:
> In that first example, the following
> int[] slice = cast(int*)malloc(10 * int.sizeof)[0 .. 10];
> doesn't actually compile.
>
> You would compile it as
> auto slice = cast(int*)malloc(10 * int.sizeof)[0 .. 10];

It should probably just be

int[] slice = (cast(int*)malloc(10 * int.sizeof))[0 .. 10];


Since the type certainly should be int[], and it will compile.
November 11, 2019
Prior art fails to mention @nogc, which already prohibits these operations in D today. So does -betterC. These work without breaking nearly every D module I have ever seen for marginal benefit at best.
November 11, 2019
On Monday, 11 November 2019 at 13:33:35 UTC, Adam D. Ruppe wrote:
> Prior art fails to mention @nogc, which already prohibits these operations in D today. So does -betterC. These work without breaking nearly every D module I have ever seen for marginal benefit at best.

The "marginal benefit at best" depends. If the goal is to move away from the GC and make using D without the GC the priority, as seems to be the case based on this and other recent work, the benefit is not marginal. Some communication about the overall goal here would be nice. Is there even a plan?
November 11, 2019
On Monday, 11 November 2019 at 14:02:36 UTC, bachmeier wrote:
> If the goal is to move away from the GC and make using D without the GC the priority,

This already works - and you can statically enforce it on a per-function level by @nogc. Or on a per-type basis with a trivial wrapper struct (except null doesn't implicitly construct - we should fix THAT). Or on a per-project basis with -betterC.

All this proposal does is break code that hasn't opted into those existing options.

> Some communication about the overall goal here would be nice. Is there even a plan?

I agree with this regardless though.
November 11, 2019
On 2019-11-11 13:33:35 +0000, Adam D. Ruppe said:

> Prior art fails to mention @nogc, which already prohibits these operations in D today. So does -betterC. These work without breaking nearly every D module I have ever seen for marginal benefit at best.

Yes, that's a very good point and gives one everything to manually manage memory and be sure the GC doesn't jump in.

If a mixed memory management model is used, the programmer needs to understand the side-effects and what happens if the GC jumps in and take full responsibility.

So, I don't like this change at all. KISS.

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster