Проще говоря, ограничения означают, что правильных способов объединить все меньше, а первоклассные функции облегчают выделение таких вещей, как структуры цикла. Возьмем цикл из этого ответа , например:
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
iterator.remove();
}
}
Это единственный безопасный и обязательный способ в Java для удаления элемента из коллекции во время его итерации. Есть много способов, которые выглядят очень близко, но они ошибочны. Люди, не знающие об этом методе, иногда используют запутанные способы избежать проблемы, например, вместо этого перебирая копию.
Это не очень сложно сделать таким универсальным, поэтому он будет работать не только с коллекциями Strings
, но без первоклассных функций вы не можете заменить предикат (условие внутри if
), поэтому этот код имеет тенденцию копироваться и вставляться и немного изменен.
Комбинируйте первоклассные функции, которые дают вам возможность передавать предикат в качестве параметра, с ограничением неизменности, которое делает его очень раздражающим, если вы этого не делаете, и вы придумываете простые строительные блоки, как filter
, например , в этом коде Scala это делает то же самое:
list filter (!_.isEmpty)
Теперь подумайте о том, что система типов проверяет для вас во время компиляции в случае Scala, но эти проверки также выполняются динамическими системами типов при первом запуске:
list
должен быть какой-то тип, который поддерживает filter
метод, а именно коллекция.
- Элементы
list
должны иметь isEmpty
метод, который возвращает логическое значение.
- Результатом будет (потенциально) меньшая коллекция с элементами того же типа.
После того, как эти вещи были проверены, какие другие способы остаются для программиста, чтобы испортить? Я случайно забыл !
, что вызвало крайне очевидный сбой тестового случая. Это в значительной степени единственная доступная ошибка, которую я могу сделать, и я сделал это только потому, что непосредственно переводил код, проверенный на обратное условие.
Этот шаблон повторяется снова и снова. Первоклассные функции позволяют вам преобразовывать вещи в небольшие повторно используемые утилиты с точной семантикой, ограничения, такие как неизменность, дают вам стимул для этого, а проверка типов этих утилит оставляет мало места, чтобы их испортить.
Конечно, все это зависит от того, знает ли программист, что упрощающая функция, подобная этой, filter
уже существует, и может ли ее найти или осознавать преимущества ее создания самостоятельно. Попробуйте реализовать это везде, используя только хвостовую рекурсию, и вы снова окажетесь в той же лодке сложности, что и императивная версия, только хуже. То, что вы можете написать это очень просто, не означает, что простая версия очевидна.