Главная | Все статьи | Код

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

Время чтения статьи ~5 минут
Что такое ссылочная прозрачность в программировании? главное изображение

В функциональном программировании ссылочная прозрачность обычно означает, что выражение в коде может быть заменено результатом выполнения этого кода (или чем-либо, имеющим такое же значение), при этом результаты выполнения всего кода не изменятся. Это означает, что алгоритм всегда должен возвращать одно и то же значение для данного аргумента без какого-либо другого эффекта. Эта концепция функционального программирования также применима и к императивному программированию, и может помочь сделать код любого программиста более понятным. Мы подробно перевели статью “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 — что это такое и почему эти практики меняют мир разработки уже сейчас

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

Итог

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

Аватар пользователя Svet Ivanov
Svet Ivanov 22 января 2021
21
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Django
10 месяцев
с нуля
Старт 25 апреля
профессия
от 6 183 ₽ в месяц
Ручное тестирование веб-приложений
4 месяца
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 25 апреля
профессия
от 5 025 ₽ в месяц
новый
Сбор, анализ и интерпретация данных
9 месяцев
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 25 апреля
профессия
от 5 840 ₽ в месяц
Создание веб-приложений со скоростью света
5 месяцев
c опытом
Старт 25 апреля
профессия
от 9 900 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 25 апреля
профессия
от 6 300 ₽ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 25 апреля
профессия
новый
Автоматизированное тестирование веб-приложений на JavaScript
8 месяцев
c опытом
в разработке
Старт 25 апреля
профессия
Верстка с использованием последних стандартов CSS
5 месяцев
с нуля
Старт в любое время