Creating immutable arrays in @safe code

Dennis dkorpel at gmail.com
Fri Jul 16 20:19:32 UTC 2021


I like passing around immutable data, but I don't like creating 
it. Here are some toy examples to illustrate:

```D
immutable(int)[] positive(int[] input) @safe
{
     return input.filter!(x => x > 0).array;
}
```

> Error: cannot implicitly convert expression 
> `array(filter(input))` of type `int[]` to `immutable(int)[]`

So we need to tell the compiler the data is unique, but that's 
not `@safe`:

```D
immutable(int)[] positive(int[] input) @safe
{
     return input.filter!(x => x > 0).array.assumeUnique();
}
```

> Error: `@safe` function `positive` cannot call `@system` 
> function `assumeUnique`

I can use `.idup` instead of `assumeUnique()` in `@safe` code, 
but that makes a redundant copy. We could mark the function 
`@trusted`, but I don't want `@trusted` functions all over my 
code, so I thought I'd make a little helper function:
```D
auto iarray(R)(R range)
{
     auto result = range.array;
     return (() @trusted => result.assumeUnique)();
}
```
And I got plenty of use out of it so far. Maybe something like 
that already exists in Phobos, but I couldn't find it. It has its 
limits however:

```D
immutable(int)[] sortedPositive(int[] input) @safe
{
     return input.filter!(x => x > 0).iarray.sort.release;
}
```

That doesn't work because you can't sort an immutable array, so 
we're back to:

```D
immutable(int)[] sortedPositive(int[] input) @trusted
{
     return input.filter!(x => x > 
0).array.sort.release.assumeUnique();
}
```

I could make another primitive (`iarraySort`), but I wonder if 
there are more convenient ways to create immutable data in 
general?


More information about the Digitalmars-d-learn mailing list