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?
Permalink
Reply