Найти тему

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

Оглавление

В функциональном программировании ссылочная прозрачность обычно означает, что выражение в коде может быть заменено результатом выполнения этого кода (или чем-либо, имеющим такое же значение), при этом результаты выполнения всего кода не изменятся. Это означает, что алгоритм всегда должен возвращать одно и то же значение для данного аргумента без какого-либо другого эффекта. Эта концепция функционального программирования также применима и к императивному программированию, и может помочь сделать код любого программиста более понятным. Мы подробно перевели статью “What Is Referential Transparency?” издания SitePoint и адаптировали примеры кода с Java (которая используется в оригинале) на JavaScript.

Ссылочная прозрачность

Термин ссылочная прозрачность используется в математике, логике, лингвистике, философии и в программировании. В каждой из этих областей он имеет совершенно разные значения. Здесь мы будем иметь дело только с компьютерными программами, хотя и покажем аналогию с математикой (но не волнуйтесь — с достаточно простой математикой). Мы рассмотрим ссылочную прозрачность, используемую функциональными программистами.

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

В математике ссылочная прозрачность — это свойство выражений, которые могут быть заменены другими выражениями, имеющими такое же значение, без какого-либо изменения результата. Рассмотрим следующий пример:

x = 2 + (3 * 4)

Мы можем заменить подвыражение (3 * 4) любым другим выражением, имеющим то же значение, при этом не изменяя результат (значение x). Наиболее очевидное выражение, которое следует использовать, конечно же 12:

x = 2 + 12

При этом мы могли использовать любое другое выражение, имеющее значение 12 (возможно (5 + 7)), не боясь изменения результата. Как следствие, часть этого выражения — (3 * 4), имеет ссылочную прозрачность.

Мы можем заменить и выражение 2 + 12 другим выражением, имеющим то же значение — так, чтобы оно оставалось ссылочно-прозрачным:

x = 14

Читайте также:
Системы типов в языке —
какие бывают и чем отличаются

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

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

const add = (a, b) => a + b;

const mult = (a, b) => a * b;

const x = add(2, mult(3, 4));

В этом примере функция mult является ссылочно-прозрачной, потому что любой ее вызов может быть заменен соответствующим возвращаемым значением. Это можно увидеть, заменив mult(3, 4) на 12:

const x = add(2, 12);

Таким же образом add(2, 12) можно заменить на возвращаемое значение 14.

const x = 14;

Эти изменения не повлияют на результат работы программы, что бы она не выполняла. Обратите внимание, что вообще мы могли бы использовать любое другое выражение, имеющее аналогичное значение — это свойство очень полезно при рефакторинге.

С другой стороны, рассмотрите следующую программу:

const add = (a, b) => {
const result = a + b;
console.log(`Returning ${result}`);
return result;
};

Замена вызова add возвращаемым значением изменит результат работы программы, поскольку сообщение больше не будет печататься с помощью console.log. В этом случае замена просто удалит побочный эффект, но в других случаях она может изменить значение, которое возвращается алгоритмом.

const getFibsNext = () => {
let previous = -1;
let last = 1;

const next = () => {
last
= previous + (previous = last);
return previous + last;
}

return next;
};

const printFibs = (limit) => {
const next = getFibsNext();
for (let i = 0; i < limit; i += 1) {
console.log(next());
}
};

printFibs(10);

Здесь функция next не может быть заменена чем-либо, даже если оно имело бы такое же значение. Это связано с тем, что эта функция предназначена для возврата абсолютно разных значений при каждом вызове.

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

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

Функции используются как в императивном, так и в функциональном (декларативном) программировании. Несмотря на то, что функциональное программирование использует только функции, в императивном программировании также используются:

— чистые функции: методы, возвращающие значения, и не имеющие других эффектов.

— чистые эффекты: методы, не возвращающие ничего, кроме изменения чего-то вне их.

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

Читайте также:
DevOps — что это такое и
почему эти практики меняют мир разработки уже сейчас

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

Итог

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

____________________________

Другие материалы о программировании читайте в блоге Хекслета.

Наука
7 млн интересуются