Вопросы:
- Разрушают ли генераторы парадигму функционального программирования? Почему или почему нет?
- Если да, могут ли генераторы использоваться в функциональном программировании и как?
Учтите следующее:
function * downCounter(maxValue) {
yield maxValue;
yield * downCounter(maxValue > 0 ? maxValue - 1 : 0);
}
let counter = downCounter(26);
counter.next().value; // 26
counter.next().value; // 25
// ...etc
downCounter
Метод оказывается без гражданства. Кроме того, вызов downCounter
с одним и тем же вводом всегда будет приводить к одному и тому же выводу. Однако, в то же время, звонки next()
не дают последовательных результатов.
Я не уверен, нарушают ли генераторы парадигму функционального программирования, потому что в этом примере counter
это объект генератора, и поэтому вызов next()
вызовет те же результаты, что и другой объект генератора, созданный с точно такой же maxValue
.
Кроме того, вызов someCollection[3]
массива всегда будет возвращать четвертый элемент. Аналогично, next()
четыре раза вызов объекта-генератора также всегда возвращает четвертый элемент.
Для большего контекста эти вопросы были подняты во время работы над ката программирования . Человек, который ответил на вопрос, поднял вопрос, могут ли генераторы использоваться в функциональном программировании и имеют ли они состояние.
Ответы:
Функции генератора не особо особенные. Мы можем реализовать подобный механизм самостоятельно, переписав функцию генератора в стиле обратного вызова:
Очевидно, что
downCounter
он настолько чистый и функциональный, насколько это возможно. Здесь нет проблем.Протокол генератора, используемый JavaScript, включает изменяемый объект. Это не обязательно, см. Приведенный выше код. В частности, изменяемые объекты означают, что мы теряем ссылочную прозрачность - возможность заменить выражение его значением. Хотя в моем примере всегда
counter.next().value
будет оцениваться, независимо от того, где это происходит и как часто мы повторяем это, это не относится к генератору JS - в какой-то момент это так , и это действительно может быть любое число. Это проблематично, если мы передаем ссылку на генератор в другую функцию:25
26
25
Очевидно, что генераторы поддерживают состояние и поэтому не подходят для «чистого» функционального программирования. К счастью, вам не нужно заниматься чисто функциональным программированием, и вы можете быть прагматичными. Если генераторы делают ваш код более понятным, вы должны использовать их без совести. В конце концов, JavaScript не является чисто функциональным языком, в отличие, например, от Haskell.
Кстати, в Haskell нет разницы между возвратом списка и генератора, поскольку он использует ленивую оценку:
источник