Useful Workarounds
It is sometimes necessary to find workarounds to bugs, compiler limitations and language design issues.
Some common use-cases which require workarounds are:
std.parallelism amap & reduce
Due to Issue 5710, you cannot use delegates with amap and reduce. This essentially limits amap & reduce to taking free functions as template parameters.
amap
The workaround for amap is to replace:
import std.parallelism;
auto result = taskPool.amap!(myDelegate)(inputRange);
With:
import std.range: chunks, zip;
import std.parallelism;
auto result = new ResultType[inputRange.length];
auto chunkSize = taskPool.defaultWorkUnitSize(inputRange.length);
auto inputChunks = inputRange.chunks(chunkSize);
auto outputChunks = result.chunks(chunkSize);
foreach (ioChunk; outputChunks.zip(inputChunks).parallel(1))
{
auto inputChunk = ioChunk[1];
auto outputChunk = ioChunk[0];
foreach (i,input; inputChunk)
outputChunk[i] = myDelegate(input);
}
Where "ResultType" is the return type of "myDelegate."
reduce
The workaround for reduce is to replace:
import std.parallelism;
auto result = taskPool.reduce!(myDelegate)(seed,inputRange);
With:
import std.range : chunks, frontTransversal, zip;
import std.algorithm : reduce;
import std.parallelism;
auto chunkSize = taskPool.defaultWorkUnitSize(inputRange.length);
auto inputChunks = inputRange.chunks(chunkSize);
auto partialResults = (new ResultType[inputChunks.length]).chunks(1);
foreach (ioChunk; partialResults.zip(inputChunks).parallel(1))
{
auto inputChunk = ioChunk[1];
auto partialResult = ioChunk[0];
partialResult[0] = reduce!(myDelegate)(seed, inputChunk);
}
auto result = partialResults.frontTransversal.reduce!(myDelegate);
Where "ResultType" is the return type of "myDelegate."