Comments 18
У меня только один контр-аргумент — против чистоты функций обычно играет производительность. (см. «garbage collector friendly javascript»)
0
Сначала называем сложным и неудобным DI (который в реальном мире, а не академических примерах выполняется автоматом), а потом наворачиваем километры других абстракций, которые делают «чисто» и удобно… Ну ок.
Про производительность тоже лучше умолчать.
Про производительность тоже лучше умолчать.
+5
На середине статьи были мысли примерно такие же. "Открыто новое достижение: 95% функций — чистые!", "в JS нет глобальных моков?!".
Но потом с раздела "Зачем это всё?" автор объясняет, как чистые функции помогают при дебаге. Мне это показалось довольно убедительным и полезным. Если рассуждать дальше, то появляются вопросы по сравнению приложения, написаного на чистых функциях, и приложения, написаного с качественным ООП:
- насколько дебаг проще?
- какое сравнение трудозатрат на дальней дистанции?
- чему проще научить, и какой подход проще внедрить, с учетом того, что в большинстве ЯП нет проверки чистоты функций?
- что выгоднее для бизнеса?
0
Странно всё это. На сколько я понимаю концепция состоит не в том чтобы отложить вычисления с побочными эффектами, а в том чтобы отделить их.
Если тебе нужно что-то из IO достань его, а потом положи в чистую функцию.
Если тебе нужно что-то из IO достань его, а потом положи в чистую функцию.
+2
Это одно и то же. Чтобы их отложить — их надо отделить, а чтобы их отделить — их надо отложить.
-1
Нет это не одно и тоже. Всё что вычисляется в монаде IO имеет доступ к побочным эффектам ввода-вывода.
сравните
и
сравните
c<-getChar
c'<-return.toUpper $ c
putChar c'
и
c<-getChar
let c'=toUpper c
putChar c'
+1
И что же вы хотите этим сказать? И при чем тут откладывание и отделение?
-1
Если вы выполняете вычисление в монаде, то оно имеет доступ к побочным эффектам этой монады.
В первом варианте при вычислении c' может произойти всё что угодно, поскольку оно выполняется в IO (надеюсь то, что на месте return.to Upper может быть любое вычисление вида IO Char понятно).
Если вы засунете калбек с типом IO a глубоко внутрь вычисления и захотите там достать из него a, то у Вас всё вычисление будет в монаде IO, и гарантировать что там кроме Вашего калбека больше ничего не произошло вы не сможете.
Таким образом внутрь чистого вычисления, чтобы оно оставалось чистым, можно передавать только иммутабельные аргументы.
В первом варианте при вычислении c' может произойти всё что угодно, поскольку оно выполняется в IO (надеюсь то, что на месте return.to Upper может быть любое вычисление вида IO Char понятно).
Если вы засунете калбек с типом IO a глубоко внутрь вычисления и захотите там достать из него a, то у Вас всё вычисление будет в монаде IO, и гарантировать что там кроме Вашего калбека больше ничего не произошло вы не сможете.
Таким образом внутрь чистого вычисления, чтобы оно оставалось чистым, можно передавать только иммутабельные аргументы.
0
То есть, если мы решили отделить «чистые» вычисления от «нечистых», альтернативы методу внедрения зависимостей нет?
+1
Об этом я не подумал. Но, можно ещё внедрять зависимости наоборот. Вставлять калбеки из чистых функций в монадические вычисления. Тогда, если дело ограничивается return.f, то можно давать некоторые гарантии. Но, как только вы заменили сигнатуру f с возвращающей a на IO а, так сразу возможен биг бадамум.
0
Это все понятно. Но где в этих примерах разница между откладыванием и отделением?
0
Ну как бы оборачивая ф-цию с побочными эффектами в thunk(отложенная ф-ция) мы получаем:
1.чистую фунцию;
2.отделяем ф-цию c эффектами от чистых, так как ее не получится просто так вызвать не
дергая ф-цию обертку.
Принцип разделяй и властвуй в полном смысле тут работает.
Вот и все жульничество как пишет автор.
Где то читал что монада IO в Haskelle реализована через thunk-и, ссылку не могу найти к сожалению.
1.чистую фунцию;
2.отделяем ф-цию c эффектами от чистых, так как ее не получится просто так вызвать не
дергая ф-цию обертку.
Принцип разделяй и властвуй в полном смысле тут работает.
Вот и все жульничество как пишет автор.
Где то читал что монада IO в Haskelle реализована через thunk-и, ссылку не могу найти к сожалению.
0
Интересно было почитать
Отвечаю на опрос: пользуюсь концепциями функционального программирования в своих проектах
Отвечаю на опрос: пользуюсь концепциями функционального программирования в своих проектах
+1
Кладем чистые функции в чистые ES-модули, и где все сайд эффекты — зависимости модуля, и радостно мокаем все эти внешние зависимости в ноль, получая возможность тестировать конечный код в реальном вакууме, не теряя статический анализ и типизацию.
+1
Здравствуйте, что-то не работает join
Вроде вот такая конструкция работает, или как правильно? Спасибо.
join(x) {
return f(x);
}
</code>
он возвращает значение и как бы уже цепочка после него работать не будет.
<source lang="javascript">
const userBioHTML = Effect.of(window)
.map(x => x.myAppConf.selectors['user-bio'])
.map($)
.join()
.map(x => x.innerHTML);
Вроде вот такая конструкция работает, или как правильно? Спасибо.
join(x) {
const j = this.runEffects(x);
return Effect(() => j);
},
0
Перечитал, подумал, ещё раз перечитал, взял карандаш.
Это не IO. Это — Reader.
Это не IO. Это — Reader.
0
Читаю переводы статей от компании RUVDS, и кажется, что там настолько хорошо построили производственный процесс, что все само работает, ничего не ломается, и есть время на то, чтобы переводить статьи )
Эта статья, имхо, хорошая. TL;DR: «глобальное состояние сложно держать в уме и сложно отлаживать; функциональное программирование — это подход, который позволяет разложить глобальное состояние программы на маленькие и поэтому _понятные_ фрагменты»
Эта статья, имхо, хорошая. TL;DR: «глобальное состояние сложно держать в уме и сложно отлаживать; функциональное программирование — это подход, который позволяет разложить глобальное состояние программы на маленькие и поэтому _понятные_ фрагменты»
0
Sign up to leave a comment.
Борьба с грязными побочными эффектами в чистом функциональном JavaScript-коде