Статьи

Что такое ссылочная прозрачность?

В функциональном программировании ссылочная прозрачность обычно определяется как факт, что выражение в программе может быть заменено его значением (или чем-либо, имеющим то же значение) без изменения результата программы. Это подразумевает, что методы всегда должны возвращать одно и то же значение для данного аргумента, не оказывая никакого другого влияния. Эта концепция функционального программирования также применима к императивному программированию и может помочь вам сделать ваш код более понятным.

Чтобы понять эту статью, вы должны знать, как писать простые классы и методы на 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 метод не может быть заменен чем-либо, имеющим такое же значение, так как метод предназначен для возврата разных значений при каждом вызове.

Использование таких нереферентно прозрачных методов требует строгой дисциплины, чтобы не использовать изменяемое состояние, участвующее в вычислении. Функциональный стиль избегает таких методов в пользу ссылочно-прозрачных версий.

Ссылочная прозрачность в императивном программировании

Как императивное, так и функциональное программирование используют функции. Хотя функциональное программирование использует только функции, императивное программирование использует:

  • чистые функции: методы, возвращающие значения и не имеющие других эффектов
  • чистые эффекты: методы, не возвращающие ничего, кроме изменения чего-либо вне их)
  • функции с побочными эффектами: методы, возвращающие значение и изменяющие что-либо

Как мы все знаем, хорошей практикой является избегать функций с побочными эффектами. Это оставляет императивных программистов с чистыми функциями и чистыми эффектами. Тогда ссылочная прозрачность является мощным инструментом для императивных программистов, который упрощает анализ их программ и их тестирование.

Улитка, достигающая ссылочной прозрачности

Резюме

Ссылочная прозрачность означает, что вызов функции может быть заменен ее значением или другим ссылочным прозрачным вызовом с тем же результатом. Это облегчает рассуждения о программах. Это также делает каждую подпрограмму независимой, что значительно упрощает модульное тестирование и рефакторинг. В качестве дополнительного преимущества, ссылочно-прозрачные программы легче читать и понимать, что является одной из причин того, почему функциональным программам нужно меньше комментариев.

Чтобы узнать больше о предмете, вы можете взглянуть на следующие документы: