On Tuesday, 29 November 2022 at 18:59:46 UTC, DLearner wrote:
To me, it appears that there are really two (_entirely separate_) concepts:

A. Supporting the useful concept of variable length (but otherwise entirely conventional) arrays; B. Supporting a language feature that acts as a window to an array, through which that array can be manipulated.

And currently these two concepts are combined.

Suggestion: it would be clearer if the two concepts were separated: 1. Convert 'int[] VarArr;' so it produces a straightforward _value-type_ variable array, called 'VarArr'; 2. Implement a new concept 'int slice Window;' to produce an object of type 'int slice', called 'Window'. 'Window' is a 'slice' into an int array, not an array itself or even a variable.

Opinions?

I have implemented that in [styx](https://gitlab.com/styx-lang/styx).

1. You have the type for dynamic arrays, called TypeRcArray, syntax is `Type[+]` 2. You have the type for slices (what you describe as a window), syntax is `Type[]` but it is mostly obtained using expressions, e.g `mySlice = myRcArray[lo .. hi]` or
`myStaticArray[lo .. hi]` or `myPointer[lo .. hi]`.

This sounded like a good idea but it [has appeared very quickly](https://styx-lang.gitlab.io/styx/type.html#noteonlifetime) that slices are not so useful, especially when management is based on reference counting because then slices requires a form of management too. Here is why:

Main caracteristics of a slice are

- they cannot modify the identity of their sources. The identity of the source is what makes the integrity of a dynamic array, what makes their references countable. So it is the content pointer and the length. In consequence you cannot change the length of the source, you can only reduce the view. You can change the elements in the view. - the length and the pointer are cached as a value on the stack while for a dynamic array this is stored before that data, on the heap.

Problems start happening when you escape a slice

```d
struct S
{
    var s32[] memberSlice;
}

function f(var S s): auto
{
    var s32[+] a = (new s32[+])(2);

    // problem 1 : `s` lifetime > `a` lifetime
s = (a[]).tupleof; // note: tuples are used in pace of struct literals

    // problem 2
    return a[1 .. $]; // a is automatically decref'd on return
                      // so the caller pulls a dead heap block.
}
```

Essentially slices are only useful to be consumed locally, typically

```d
while mySlice.length do
{
   slice = slice[1..$];
}
```

And that's it. So at first glance slices are some cool, simplified, functionally stripped down arrays but they introduce new problems, at least when management of dynamic arrays is based on reference counting. Those new problems can only be solved using lifetime analysis (so a compile-time check... still better than runtime ref counting however).

Reply via email to