История изменений
Исправление 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)