LINUX.ORG.RU

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

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

Объясняй почему это деление на ноль.

Ты цитировал моё «Ну на самом деле ты можешь делать» с тремя примерами, мол «деление на ноль», но если это было не про них а просто так, то ладно (мне не очень интересно обсуждать какие-то там состояния без контекста).

Но всё равно она условна и не единственна.

С этим я не спорю — нужно различать абстрактные языки и то что лежит ближе к конкретным реализациям и вычислениям.

Только разница между ними как разница между такими стратегиями это, например, разница между ленью и строгими вычислениями (а это обычно деталь семантики, то есть стратегия не то чтобы совсем произвольная).

int sum(int x, int y) {
    puts("sum");
    return x + y;
}

int i = 0;

int f(int x) {
    printf("f [%d]\n", ++i);
    return x * x;
}

template <typename R>
using Thunk = std::function<R()>;

#define MkThunk(EXPR) [=](){ return EXPR; }

Thunk<int> lazy_sum(Thunk<int> x, Thunk<int> y) {
    puts("lazy_sum");
    return MkThunk(x() + y());
}

Thunk<int> lazy_sum_share(Thunk<int> x) {
    puts("lazy_sum_share");
    int z = x();
    return MkThunk(z + z);
}

int main() {
    printf("result = %d\n\n", sum(f(7), f(7)));
    i = 0;
    printf("result = %d\n\n", lazy_sum(MkThunk(f(7)), MkThunk(f(7)))());
    i = 0;
    printf("result = %d\n\n", lazy_sum_share(MkThunk(f(7)))());
}
/*
f [1]
f [2]
sum
result = 98

lazy_sum
f [1]
f [2]
result = 98

lazy_sum_share
f [1]
result = 98

*/

http://www.cplusplus.com/reference/future/ тоже в тему.

Однако в изначальном дереве времени нет.

Да ради бога, нет — сделаем :)

Согласен?

Да.

А что будет, если результат зависит от глобальной переменной, которая равна 0, а я её инкрементирую?

count = unsafePerformIO $ newIORef 0 возвращает ссылку (переменную, адрес — оно одно и то же, меняются значения по нему), она глобальна и мутабельна (то есть значения по ней, а не сам адрес ссылки), только больше unsafePerformIO использовать не надо (можно TH обвёртку defineGlobalVar вообще сделать), тогда изменяющие значение переменной операции будут всё равно в IO — глобальная переменная есть (один и тот же адрес который мы вытащили из IO, изменяемые данные по нему всё ещё инкапсулированы в слое IO), нарушений ссылочной прозрачности и ФП нет.

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

Объясняй почему это деление на ноль.

Ты цитировал моё «Ну на самом деле ты можешь делать» с тремя примерами, мол «деление на ноль», но если это было не про них а просто так, то ладно (мне не очень интересно обсуждать какие-то там состояния без контекста).

Но всё равно она условна и не единственна.

С этим я не спорю — нужно различать абстрактные языки и то что лежит ближе к конкретным реализациям и вычислениям.

Только разница между ними как разница между такими стратегиями это, например, разница между ленью и строгими вычислениями (а это обычно деталь семантики, то есть стратегия не то чтобы совсем произвольная).

int sum(int x, int y) {
    puts("sum");
    return x + y;
}

int i = 0;

int f(int x) {
    printf("f [%d]\n", ++i);
    return x * x;
}

template <typename R>
using Thunk = std::function<R()>;

#define MkThunk(EXPR) [=](){ return EXPR; }

Thunk<int> lazy_sum(Thunk<int> x, Thunk<int> y) {
    puts("lazy_sum");
    return MkThunk(x() + y());
}

Thunk<int> lazy_sum_share(Thunk<int> x) {
    puts("lazy_sum_share");
    int z = x();
    return MkThunk(z + z);
}

int main() {
    printf("result = %d\n\n", sum(f(7), f(7)));
    i = 0;
    printf("result = %d\n\n", lazy_sum(MkThunk(f(7)), MkThunk(f(7)))());
    i = 0;
    printf("result = %d\n\n", lazy_sum_share(MkThunk(f(7)))());
}
/*
f [1]
f [2]
sum
result = 98

lazy_sum
f [1]
f [2]
result = 98

lazy_sum_share
f [1]
result = 98

*/

http://www.cplusplus.com/reference/future/ тоже в тему.

Однако в изначальном дереве времени нет.

Да ради бога, нет — сделаем :)

Согласен?

Да.

А что будет, если результат зависит от глобальной переменной, которая равна 0, а я её инкрементирую?

count = unsafePerformIO $ newIORef 0 возвращает ссылку (адрес, переменную), она глобально и мутабельна, только больше unsafePerformIO использовать не надо (можно TH обвёртку defineGlobalVar вообще сделать), тогда изменяющие значение переменной операции будут всё равно в IO — глобальная переменная есть, нарушений ссылочной прозрачности и ФП нет.