Д. Тернер, Эддисон-Уэсли, 1990 Прочтите этот пост на испанском языке
Модульность и удобочитаемость являются двумя наиболее важными характеристиками кода для достижения высокого качества и удобства обслуживания кода, но написание модульного кода создает необходимость в “клеевом коде”, который иногда включает побочные эффекты и снижает удобочитаемость. Функциональное программирование использует функции высокого порядка и ленивую оценку, чтобы улучшить или даже избежать этого “склеивания кода” и гарантировать читаемость с помощью ссылочной прозрачности.
Ссылочная прозрачность
Функция FP разделяет их определение с математической концепцией следующим образом: “Отношение набора входных данных к набору возможных выходных данных, где каждый входной сигнал связан ровно с одним выходом”, следовательно, побочных эффектов нет!. Кроме того, это позволяет нам заменять вызов функции возвращаемым значением без необходимости просматривать весь контекст функции и создавать более повторно используемые и простые в тестировании “модули”.
Функции Высокого Порядка
Если функция возвращает другую функцию или имеет функции в качестве входных данных, она считается функцией высокого порядка, ее также называют первоклассным гражданином в более программном подходе.
Используя функции высокого порядка, мы можем определить некоторые абстрактные модели поведения, которые применяются к нескольким типам данных и требуют меньше “склеивающего кода”.
Функция foldLeft коллекций в VAR является простым примером того, как это работает:
В примерах используется библиотека JAVA называемый ВАВР
public static void main(String[] args) { Listlist = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9); Integer r = list.foldLeft(0, Integer::sum); // 45 } //source code of VAVR default U foldLeft(U zero, BiFunction super U, ? super T, ? extends U> f) { Objects.requireNonNull(f, "f is null"); U xs = zero; for (T x : this) { xs = f.apply(xs, x); } return xs; }
Ленивая Оценка
Поскольку у нас нет информации о побочных эффектах, можно написать определение значения, не оценивая их до выполнения во время выполнения, и не задумываться о бесконечных возможных последствиях, создаваемых побочными эффектами.
Отличным примером этой функции является функция квадратного корня, которая использует “бесконечный” список кандидатов и выбирает первое значение для передачи требуемой точности.
public static Function1nextCandidate(Double n){ /** * Sequence of candidates for the square root according to Newton-Raphson */ return Function1.of((previous) -> (previous + (n / previous)) / 2d); } public static Double squareRoot(Double n){ Stream s = Stream.iterate(1d, nextCandidate(n)); Double epsilon = 0.0001d; // precision required return s.takeUntil(candidate -> Math.abs((candidate * candidate) - n) < epsilon).last(); } public static void main(String[] args) { System.out.println(squareRoot(25d)); // 5.000023178253949 }
В предыдущем примере также показан другой пример функций высокого порядка, представленных следующим кандидатом, которые имеют функцию в качестве выходных данных.
Не стесняйтесь комментировать свой опыт работы с функциональным программированием в комментариях.
Это мой первый пост на английском языке и первый из серии резюме статей, поэтому я ценю отзывы о стиле написания, содержании, других статьях для чтения и рекомендуемых тегах для серии:)
Оригинал: “https://dev.to/gustavo94/digest-of-papers-why-functional-programming-matters-253f”