Содержание
В функциональном программировании ссылочная прозрачность обычно определяется как факт, что выражение в программе может быть заменено его значением (или чем-либо, имеющим то же значение) без изменения результата программы. Это подразумевает, что методы всегда должны возвращать одно и то же значение для данного аргумента, не оказывая никакого другого влияния. Эта концепция функционального программирования также применима к императивному программированию и может помочь вам сделать ваш код более понятным.
Чтобы понять эту статью, вы должны знать, как писать простые классы и методы на Java. Знание того, что побочный эффект помогает, но если вы этого не сделаете, вы узнаете его по пути.
Ссылочная прозрачность
Выражение ссылочной прозрачности используется в различных областях, таких как математика, логика, лингвистика, философия и программирование. Это имеет совершенно разные значения в каждой из этих областей. Здесь мы будем иметь дело только с компьютерными программами, хотя мы покажем аналогию с математикой (простая математика, не волнуйтесь). Обратите внимание, однако, что ученые-компьютерщики не согласны со значением прозрачности ссылок в программировании. Мы рассмотрим ссылочную прозрачность, поскольку она используется функциональными программистами.
Ссылочная прозрачность в математике
В математике ссылочная прозрачность — это свойство выражений, которое может быть заменено другими выражениями, имеющими такое же значение, без какого-либо изменения результата. Рассмотрим следующий пример:
x = 2 + (3 * 4)
Мы можем заменить подвыражение (3 * 4)
любым другим выражением, имеющим такое же значение, без изменения результата (значение x
). Наиболее очевидное выражение для использования, конечно, 12
:
x = 2 + 12
Любое другое выражение, имеющее значение 12
(возможно (5 + 7)
), может быть использовано без изменения результата. Как следствие, подвыражение (3 * 4)
является ссылочно прозрачным.
Мы также можем заменить выражение 2 + 12
другим выражением, имеющим такое же значение, без изменения значения x
, поэтому оно также является прозрачным по ссылкам:
x = 14
Вы можете легко увидеть преимущества прозрачности ссылок: это позволяет рассуждать. Без этого мы не могли бы разрешить любое выражение, не рассматривая некоторые другие элементы.
Ссылочная прозрачность в программировании
В программировании ссылочная прозрачность применяется к программам. Поскольку программы состоят из подпрограмм, которые являются самими программами, это относится и к этим подпрограммам. Подпрограммы могут быть представлены, среди прочего, методами. Это означает, что метод может быть ссылочно прозрачным, в случае если вызов этого метода может быть заменен его возвращаемым значением:
int add(int a, int b) { return a + b } int mult(int a, int b) { return a * b; } int x = add(2, mult(3, 4));
В этом примере метод mult
является прозрачным по mult
поскольку любой вызов этого метода может быть заменен соответствующим возвращаемым значением. Это можно наблюдать, заменив mult(3, 4)
на 12
:
int x = add(2, 12)
Таким же образом add(2, 12)
можно заменить соответствующим возвращаемым значением 14
:
int x = 14;
Ни одна из этих замен не изменит результат программы, что бы она ни делала. Обратите внимание, что мы можем использовать любое другое выражение с таким же значением, что полезно при рефакторинге.
С другой стороны, рассмотрим следующую программу:
int add(int a, int b) { int result = a + b; System.out.println("Returning " + result); return result; }
Замена вызова метода add
на соответствующее возвращаемое значение изменит результат программы, поскольку сообщение больше не будет печататься. В этом случае это только уберет побочный эффект, но в других случаях может изменить значение, возвращаемое методом:
public static void main(String... args) { printFibs(10); } public static void printFibs(int limit) { Fibs fibs = new Fibs(); for (int i = 0; i < limit; i++) { System.out.println(fibs.next()); } } static class Fibs { private int previous = -1; private int last = 1; public Integer next() { last = previous + (previous = last); return previous + last; } }
Здесь next
метод не может быть заменен чем-либо, имеющим такое же значение, так как метод предназначен для возврата разных значений при каждом вызове.
Использование таких нереферентно прозрачных методов требует строгой дисциплины, чтобы не использовать изменяемое состояние, участвующее в вычислении. Функциональный стиль избегает таких методов в пользу ссылочно-прозрачных версий.
Ссылочная прозрачность в императивном программировании
Как императивное, так и функциональное программирование используют функции. Хотя функциональное программирование использует только функции, императивное программирование использует:
- чистые функции: методы, возвращающие значения и не имеющие других эффектов
- чистые эффекты: методы, не возвращающие ничего, кроме изменения чего-либо вне их)
- функции с побочными эффектами: методы, возвращающие значение и изменяющие что-либо
Как мы все знаем, хорошей практикой является избегать функций с побочными эффектами. Это оставляет императивных программистов с чистыми функциями и чистыми эффектами. Тогда ссылочная прозрачность является мощным инструментом для императивных программистов, который упрощает анализ их программ и их тестирование.
Резюме
Ссылочная прозрачность означает, что вызов функции может быть заменен ее значением или другим ссылочным прозрачным вызовом с тем же результатом. Это облегчает рассуждения о программах. Это также делает каждую подпрограмму независимой, что значительно упрощает модульное тестирование и рефакторинг. В качестве дополнительного преимущества, ссылочно-прозрачные программы легче читать и понимать, что является одной из причин того, почему функциональным программам нужно меньше комментариев.
Чтобы узнать больше о предмете, вы можете взглянуть на следующие документы: