Что такое чистые функции
Что проверяют
Понимаете ли вы функциональные идеи в языке, который их не навязывает. В Java чистота это соглашение, компилятор её не проверяет, поэтому смотрят, отличаете ли вы отсутствие побочных эффектов от простого наблюдения, что функция ничего не печатает.
Как отвечать
Чистая функция удовлетворяет двум условиям сразу. Она детерминирована: на одних и тех же аргументах всегда даёт один результат. И она не имеет побочных эффектов: не меняет поля объекта, аргументы и статическое состояние, не пишет в файл, базу или лог.
Второе условие полезно формулировать шире: функция не должна и читать изменяемое внешнее состояние. Обращение к текущему времени, к генератору случайных чисел, к настройкам, которые можно перезагрузить на ходу, делает её нечистой, даже если сама она ничего не портит.
Отсюда практическая польза. Вызов чистой функции можно заменить её результатом, а значит доступны кэширование, ленивость, перестановка и параллельное выполнение. И тестируется она без моков: подали аргументы, сравнили результат.
static BigDecimal total(List<Item> items, BigDecimal rate) {
return items.stream()
.map(Item::price)
.reduce(BigDecimal.ZERO, BigDecimal::add)
.multiply(rate);
}Хорошая финальная мысль: чистым делают ядро с вычислениями и правилами, а работу с базой, сетью и временем выносят на края. Время и случайность в таком коде передают параметром или через абстракцию источника.
Где спотыкаются
Называют функцию чистой, потому что она возвращает значение и ничего не печатает, хотя внутри она читает статическое поле или системное время.
Возвращают ссылку на внутреннюю изменяемую коллекцию. Формально функция ничего не изменила, но вызывающий теперь может испортить состояние, и детерминированность следующего вызова кончилась.
Пишут побочные эффекты внутри операций над потоком, чаще всего накапливая результат во внешнюю коллекцию. На последовательном потоке это ещё работает, при параллельном превращается в гонку.