I like passing around immutable data, but I don't like creating it. Here are some toy examples to illustrate:
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
:
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:
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:
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:
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?