LINUX.ORG.RU

История изменений

Исправление www_linux_org_ru, (текущая версия) :

TL;DR = «pure без системы эффектов малополезно, а то и бесполезно»

Ключевым фактором тут является то, что f тоже должно быть чистой функцией. Или необходимость транизитивности для pure тоже вызывает сомнения?

транзитивность тут тоже вопрос не простой; допустим, что мне нужно код transform вызывать как с чистыми функциями (тогда он чистый), так и с нечистыми (тогда он нечистый); что делать?

здраствуй, копипаста? (или макросы... ой, извините, в д их назвали миксины)

float[] transform( const float[] src, float function(float) pure f ) pure {
  float[] dst = new float[src.length];
  for (int i=0; i < src.length; ++i) {
    dst[i] = f(src[i]);
  }
  return dst;
}
float[] transformМ( const float[] src, float function(float) f ) {
  float[] dst = new float[src.length];
  for (int i=0; i < src.length; ++i) {
    dst[i] = f(src[i]);
  }
  return dst;
}

собственно, имеем те же проблемы, как и в хаскеле вместо языка программирования — монады вместо эффектов

предположим, что есть две функции f1 и f2, которые, хотя и не являются чистыми, коммутируют:

int var1=0;
int var2=0;

float f1(float x) { ++var1; return 1*x; }
float f2(float x) { ++var2; return 2*x; }

человеку очевидно, что код

	float[] input = [ 1.0, 2.0, 3.0 ];	
	float[] out1 = transformМ(input, &f1);
	float[] out2 = transformМ(input, &f2);
полностью эквивалентен коду
	float[] input = [ 1.0, 2.0, 3.0 ];	
	float[] out2 = transformМ(input, &f2);
	float[] out1 = transformМ(input, &f1);

но как насчет компилятора? пусть ему видны оба определения f1 и f2 (или даже они inline), но не видно тело transformМ, а только виден его прототип

таким образом, компятор не сможет переупорядочить (для оптимизации, скажем) эти 2 строки, хотя в принципе это возможно; кроме того, *одинаковый* бинарный код функций transform и transformМ — это именно то, что называется борьба с типизацией (tm)

Исходная версия www_linux_org_ru, :

TL;DR = «pure без системы эффектов малополезно, а то и бесполезно»

Ключевым фактором тут является то, что f тоже должно быть чистой функцией. Или необходимость транизитивности для pure тоже вызывает сомнения?

транзитивность тут тоже вопрос не простой; допустим, что мне нужно код transform вызывать как с чистыми функциями (тогда он чистый), так и с нечистыми (тогда он нечистый); что делать?

здраствуй, копипаста? (или макросы... ой, извините, в д их назвали миксины)

float[] transform( const float[] src, float function(float) pure f ) pure {
  float[] dst = new float[src.length];
  for (int i=0; i < src.length; ++i) {
    dst[i] = f(src[i]);
  }
  return dst;
}
float[] transformМ( const float[] src, float function(float) f ) {
  float[] dst = new float[src.length];
  for (int i=0; i < src.length; ++i) {
    dst[i] = f(src[i]);
  }
  return dst;
}

собственно, имеем те же проблемы, как и в хаскеле вместо языка программирования — монады вместо эффектов

предположим, что есть две функции f1 и f2, которые, хотя и не являются чистыми, коммутативны:

int var1=0;
int var2=0;

float f1(float x) { ++var1; return 1*x; }
float f2(float x) { ++var2; return 2*x; }

человеку очевидно, что код

	float[] input = [ 1.0, 2.0, 3.0 ];	
	float[] out1 = transformМ(input, &f1);
	float[] out2 = transformМ(input, &f2);
полностью эквивалентен коду
	float[] input = [ 1.0, 2.0, 3.0 ];	
	float[] out2 = transformМ(input, &f2);
	float[] out1 = transformМ(input, &f1);

но как насчет компилятора? пусть ему видны оба определения f1 и f2 (или даже они inline), но не видно тело transformМ, а только виден его прототип

таким образом, компятор не сможет переупорядочить, хотя в принципе это возможно; кроме того, *одинаковый* бинарный код функций transform и transformМ — это именно то, что называется борьба с типизацией (tm)