publicclassPrimeGenerator{publicstaticboolean[] crossedOut;publicstaticint[] result;publicstaticint[]generatePrimes(int maxValue){if(maxValue < 2){returnnewint[0];}else{
uncrossIntegersUpTo(maxValue);
crossOutMultiples();
putUncrossedIntegersIntoResult();return result;}}privatestaticvoiduncrossIntegersUpTo(int maxValue){
crossedOut =newboolean[maxValue + 1];for(int i = 2; i < crossedOut.length; i++)
crossedOut[i]=false;}privatestaticvoidcrossOutMultiples(){int limit = determineIterationLimit();for(int i = 2; i <= limit; i++){if(notCrossed(i))
crossOutMultiplesOf(i);}}privatestaticintdetermineIterationLimit(){double iterationLimit = Math.sqrt(crossedOut.length);return(int)iterationLimit;}privatestaticvoidcrossOutMultiplesOf(int i){for(int multiple = 2*i; multiple < crossedOut.length; multiple += i)
crossedOut[multiple]=true;}privatestaticbooleannotCrossed(int i){return crossedOut[i]==false;}privatestaticvoidputUncrossedIntegersIntoResult(){
result =newint[numberOfUncrossedIntegers()];for(int j = 0, i = 2; i < crossedOut.length; i++){if(notCrossed(i))
result[j++]= i;}}privatestaticintnumberOfUncrossedIntegers(){int count = 0;for(int i = 2; i < crossedOut.length; i++)if(notCrossed(i))
count++;return count;}}
In both cases, Martin has transformed thread-safe, nearly pure functions into thread-unsafe functions. Even worse, while the former example can be used on multiple threads by having each thread instantiate a local instance of GuessStatisticsMessage, the latter example, due to its use of static member variables, cannot be used on multiple threads without some form of locking.
While I agree that Martin’s examples are more readable, it seems to me that there may be a fundamental tension between object-oriented programming and thread safety, and this tension does not exist in functional programming.