Что означает термин ссылочная прозрачность ? Я слышал, что это описывается как «это означает, что вы можете заменить равные равными», но это выглядит как неадекватное объяснение.
285
Что означает термин ссылочная прозрачность ? Я слышал, что это описывается как «это означает, что вы можете заменить равные равными», но это выглядит как неадекватное объяснение.
Ответы:
Термин «ссылочная прозрачность» происходит от аналитической философии , отрасли философии, которая анализирует конструкции, утверждения и аргументы естественного языка, основанные на методах логики и математики. Другими словами, это самая близкая тема вне компьютерной науки к тому, что мы называем семантикой языка программирования . Философ Уиллард Куайн был ответственен за инициирование концепции ссылочной прозрачности, но это также подразумевалось в подходах Бертрана Рассела и Альфреда Уайтхеда.
По своей сути «ссылочная прозрачность» - очень простая и понятная идея. Термин «референт» используется в аналитической философии, чтобы говорить о том, на что ссылается выражение . Это примерно то же самое, что мы подразумеваем под «значением» или «обозначением» в семантике языка программирования. Используя пример Эндрю Биркетта ( сообщение в блоге ), термин «столица Шотландии» относится к городу Эдинбургу. Это простой пример «референта».
Контекст в предложении является «ссылочно-прозрачным», если замена термина в этом контексте другим термином, относящимся к той же сущности , не меняет смысла. Например
означает так же, как
Таким образом, контекст «Шотландский парламент встречается в ...» является референтно прозрачным контекстом. Мы можем заменить «столицу Шотландии» на «Эдинбург», не меняя смысла. Другими словами, контекст заботится только о том, к чему относится этот термин, и больше ничего. В этом смысле контекст «ссылочно прозрачен».
С другой стороны, в предложении
мы не можем сделать такую замену. Если бы мы это сделали, мы бы получили «Эдинбург был Эдинбургом с 1999 года», что является сумасшедшей вещью, и не передает того же значения, что и первоначальное предложение. Таким образом, может показаться, что контекст "Эдинбург был ... с 1999 года" является непрозрачным в отношении ссылок (противоположность прозрачному в отношении ссылок). По-видимому, он заботится о чем-то большем, нежели термин Что это?
Такие вещи, как «столица Шотландии», называются определенными терминами, и в течение долгого времени они не причиняли головной боли логикам и философам. Рассел и Куайн разобрались с ними, сказав, что они на самом деле не являются «ссылочными», т. Е. Ошибочно думать, что приведенные выше примеры используются для обозначения сущностей. Правильный способ понять, что «Эдинбург был столицей Шотландии с 1999 года», это сказать
Это предложение не может быть преобразовано в сумасшедшее. Задача решена! Смысл Куайна состоял в том, чтобы сказать, что естественный язык является грязным или, по крайней мере, сложным, потому что он сделан удобным для практического использования, но философы и логики должны вносить ясность, понимая их правильно. Ссылочная прозрачность - это инструмент, который используется для придания такой ясности значения .
Какое все это имеет отношение к программированию? Не очень, на самом деле. Как мы уже говорили, ссылочная прозрачность - это инструмент, который используется для понимания языка, т. Е. При назначении значения . Кристофер Стрейчи , который основал семантику языка программирования, использовал его в своем исследовании значения. Его основополагающая статья « Основные понятия в языках программирования » доступна в Интернете. Это красивая бумага, и каждый может ее прочитать и понять. Поэтому, пожалуйста, сделайте это. Вы будете очень просветленным. Он вводит термин «ссылочная прозрачность» в этом параграфе:
Использование «по существу» предполагает, что Стрейчи перефразирует его, чтобы объяснить его простыми словами. Функциональные программисты, кажется, понимают этот абзац по-своему. Есть 9 других случаев «ссылочной прозрачности» в статье, но они, кажется, не беспокоятся ни о каких других. Фактически вся статья Стрейчи посвящена объяснению значения императивных языков программирования . Но сегодня функциональные программисты утверждают, что императивные языки программирования не являются ссылочно прозрачными. Стрейчи будет превращаться в его могилу.
Мы можем спасти ситуацию. Мы сказали, что естественный язык «грязный или, по крайней мере, сложный», потому что он сделан удобным для практического использования. Языки программирования одинаковы. Они «грязные или, по крайней мере, сложные», потому что они сделаны так, чтобы их было удобно использовать на практике. Это не значит, что они должны нас смущать. Они просто должны быть поняты правильно, используя мета-язык, который является ссылочно прозрачным, чтобы у нас была ясность смысла. В статье, которую я цитировал, Стрейчи делает именно это. Он объясняет значение императивных языков программирования, разбивая их на элементарные понятия, нигде не теряя ясности. Важной частью его анализа является указание на то, что выражения в языках программирования имеют два вида «значений»,r-значения . До статьи Стрейчи это не было понято, и воцарилась путаница. Сегодня определение C упоминает об этом регулярно, и каждый программист C понимает это различие. (Понимают ли программисты на других языках это одинаково хорошо, трудно сказать.)
И Куайн, и Стрейчи были обеспокоены значением языковых конструкций, которые включают некоторую форму зависимости от контекста. Например, наш пример «Эдинбург является столицей Шотландии с 1999 года» означает тот факт, что «столица Шотландии» зависит от времени, в которое она рассматривается. Такая зависимость от контекста является реальностью, как на естественных языках, так и на языках программирования. Даже в функциональном программировании свободные и связанные переменные должны интерпретироваться с учетом контекста, в котором они появляются. Зависимость от контекста любого вида так или иначе блокирует ссылочную прозрачность. Если вы попытаетесь понять значение терминов без учета контекста, от которого они зависят, вы снова получите путаницу. Куайна интересовало значение модальной логики. Он держал этоМодальная логика была непрозрачной по ссылкам, и ее следует очистить, переведя ее в прозрачную структуру по ссылкам (например, рассматривая необходимость как доказуемость). Он в значительной степени проиграл эту дискуссию. Логики и философы одинаково сочли возможную мировую семантику Крипке совершенно адекватной. Подобная ситуация также царит с императивным программированием. Зависимость от состояния, объясняемая Стрейчи, и зависимость от запаса, объясняемая Рейнольдсом (аналогично возможной мировой семантике Крипке), вполне адекватны. Функциональные программисты мало знают об этом исследовании. Их идеи относительно ссылочной прозрачности следует воспринимать с большой долей соли.
[Дополнительное примечание: приведенные выше примеры показывают, что простая фраза, такая как «столица Шотландии», имеет несколько уровней значения. На одном уровне мы можем говорить о столице в настоящее время. На другом уровне мы могли бы говорить о всех возможных столицах, которые Шотландия могла иметь с течением времени. Мы можем «увеличить» конкретный контекст и «уменьшить», чтобы довольно легко охватить все контексты в обычной практике. Эффективность естественного языка использует нашу способность сделать это. Императивные языки программирования эффективны практически так же. Мы можем использовать переменную x в правой части присваивания (значение r ), чтобы говорить о ее значении в определенном состоянии. Или мы могли бы поговорить о его l-значениикоторый охватывает все государства. Людей редко смущают такие вещи. Однако они могут или не могут точно объяснить все уровни значения, присущие языковым конструкциям. Все такие слои значения не обязательно являются «очевидными», и это вопрос науки, чтобы изучить их должным образом. Однако неспособность обычных людей объяснять такие многоуровневые значения не означает, что они смущены ими.]
Отдельный «постскриптум», приведенный ниже, связывает это обсуждение с проблемами функционального и императивного программирования .
источник
Ссылочная прозрачность, термин, обычно используемый в функциональном программировании, означает, что при наличии функции и входного значения вы всегда будете получать один и тот же результат. То есть внешнее состояние не используется в функции.
Вот пример ссылочной прозрачной функции:
С помощью ссылочной прозрачной функции, с учетом входных данных и функции, вы можете заменить ее значением вместо вызова функции. Поэтому вместо вызова plusOne с параметром 5 мы можем просто заменить его на 6.
Еще один хороший пример - математика в целом. В математике с заданной функцией и входным значением она всегда будет отображаться на одно и то же выходное значение. f (x) = x + 1. Поэтому функции в математике являются ссылочно прозрачными.
Эта концепция важна для исследователей, потому что она означает, что когда у вас есть ссылочно-прозрачная функция, она легко поддается автоматическому распараллеливанию и кешированию.
Ссылочная прозрачность всегда используется в функциональных языках, таких как Haskell.
-
В отличие от этого существует понятие ссылочной непрозрачности. Это означает обратное. Вызов функции может не всегда давать один и тот же вывод.
Другой пример - функция-член в объектно-ориентированном языке программирования. Функции-члены обычно работают с переменными-членами и поэтому будут непрозрачными для ссылок. Функции-члены, тем не менее, могут, конечно, быть прозрачными по ссылкам.
Еще один пример - функция, которая читает текстовый файл и печатает вывод. Этот внешний текстовый файл может измениться в любое время, поэтому функция будет непрозрачной.
источник
Ссылочно-прозрачная функция - это функция, которая зависит только от ее ввода.
источник
[Это постскриптум к моему ответу от 25 марта, чтобы приблизить обсуждение к проблемам функционального / императивного программирования.]
Представление функциональных программистов о ссылочной прозрачности, кажется, отличается от стандартного понятия тремя способами:
В то время как философы / логики используют такие термины, как «ссылка», «обозначение», «designatum» и « bedeutung » (немецкий термин Фреге), функциональные программисты используют термин «значение». (Это не совсем их работа. Я замечаю, что Лэндин, Стрейчи и их потомки также использовали термин «ценность», чтобы говорить об упоминании / обозначении. Это может быть просто терминологическое упрощение, которое представили Ландин и Стрейчи, но, похоже, оно делает большая разница при использовании наивно.)
Функциональные программисты, похоже, считают, что эти «ценности» существуют внутри языка программирования, а не снаружи. При этом они отличаются как от философов, так и от семантиков языка программирования.
Кажется, они считают, что эти «ценности» должны быть получены путем оценки.
Например, статья Wikipedia о ссылочной прозрачности говорит сегодня утром:
Это полностью расходится с тем, что говорят философы / логики. Они говорят, что контекст является ссылочным или ссылочно-прозрачным, если выражение в этом контексте может быть заменено другим выражением, которое ссылается на то же самое ( базовое выражение). Кто эти философы / логики? К ним относятся Фреге , Рассел , Уайтхед , Карнап , Куайн , Церковьи бесчисленное множество других. Каждый из них - высокая фигура. Объединенная интеллектуальная сила этих логиков потрясающая, если не сказать больше. Все они единодушны в том положении, что ссылки / обозначения существуют вне формального языка, и выражения в языке могут говорить только о них. Таким образом, все, что можно сделать в языке, - это заменить одно выражение другим выражением, относящимся к той же сущности. Сами ссылки / обозначения не существуют внутри языка. Почему функциональные программисты отклоняются от этой устоявшейся традиции?
Можно предположить, что семантики языка программирования могли ввести их в заблуждение. Но они этого не сделали.
Landin :
Стой :
Птица и Вадлер :
Таким образом, в ретроспективе, попытки Ландина и Стрейчи упростить терминологию путем замены «ссылки» / «обозначения» на «значения» могли быть неразумными. Как только человек слышит о «ценности», возникает искушение подумать о процессе оценки, который ведет к нему. Не менее заманчиво думать о том, что оценка производит, как о «ценности», хотя может быть совершенно ясно, что это не означает. Вот что я понял, чтобы произошло с понятием «ссылочной прозрачности» в глазах функциональных программистов. Но «ценность», о которой говорили ранние семантики, не является результатом оценки или результата функции или любой другой вещи. Это обозначение термина.
Как только мы понимаем так называемую «ценность» выражения («ссылка» или «обозначение» в дискурсе классических философов) как сложный математический / концептуальный объект, открываются все виды возможностей.
Нежелание функциональных программистов называть такие языки «ссылочно-прозрачными» просто подразумевает, что они не хотят признавать такие сложные математические / концептуальные объекты как «значения». С другой стороны, они, кажется, совершенно готовы назвать преобразователь состояния «значением», когда он помещен в их собственный любимый синтаксис и наделен модным словом типа «монада». Я должен сказать, что они полностью противоречивы, даже если мы дадим им понять, что их идея «ссылочной прозрачности» имеет некоторую последовательность.
Немного истории может пролить свет на то, как возникли эти заблуждения. Период между 1962 и 1967 годами был очень интенсивным для Кристофера Стрейчи. В период с 1962 по 1965 год он работал неполный рабочий день в качестве помощника исследователя в Морисе Уилксе для разработки и реализации языка программирования, который стал известен как CPL. Это был императивный язык программирования, но он должен был также иметь мощные функциональные возможности языка программирования. Ландин, который был сотрудником Strachey в своей консалтинговой компании, оказал огромное влияние на взгляды Strachey на языки программирования. В знаковой статье 1965 года « Следующие 700 языков программирования » Ландин безоговорочно продвигает функциональные языки программирования (называя их денотативнымиязыки) и описывает императивные языки программирования как их "антитезу". В последующем обсуждении мы видим, что Стрейчи вызывает сомнения в сильной позиции Лэндина.
В 1965 году Стрейчи занял должность читателя в Оксфорде и, по-видимому, работал практически полный рабочий день над разработкой теории императивов и прыжков. К 1967 году он был готов с теорией, которую он преподавал в своем курсе « Основные понятия в языках программирования » в копенгагенской летней школе. Предполагалось, что конспекты лекций были опубликованы, но «к сожалению, из-за расточительного редактирования материалы так и не были реализованы; как и большая часть работы Стрейчи в Оксфорде, однако, газета имела влиятельный частный тираж». ( Мартин Кэмпбелл-Келли )
Сложность получения работ Стрейчи могла привести к распространению путаницы, когда люди полагались на вторичные источники и слухи. Но теперь, когда « Фундаментальные концепции » легко доступны в Интернете, нет необходимости прибегать к угадыванию работы. Мы должны прочитать это и решить, что имел в виду Стрейчи. В частности:
Любой разговор о «ссылочной прозрачности» без понимания различия между L-значениями, R-значениями и другими сложными объектами, которые населяют концептуальную вселенную императивного программиста, в корне ошибочен.
источник
Выражение является ссылочно прозрачным, если его можно заменить его значением, не изменяя алгоритм, что дает алгоритм, который имеет те же эффекты и выводит на тот же вход.
источник
Ссылочно-прозрачная функция - это функция, которая действует как математическая функция; при одинаковых входах он всегда будет давать одинаковые выходы. Это означает, что переданное состояние не изменяется, и что функция не имеет собственного состояния.
источник
Для тех, кто нуждается в кратком объяснении, я рискну один (но прочитайте раскрытие ниже).
Ссылочная прозрачность в языке программирования способствует эквалайзерному мышлению - чем больше у вас ссылочной прозрачности, тем легче проводить эквациональное мышление. Например, с (псевдо) определением функции,
fx = x + x,
Простота, с которой вы можете (безопасно) заменить f (foo) на foo + foo в рамках этого определения, не имея слишком много ограничений на то, где вы можете выполнить это сокращение, является хорошим показателем того, насколько ссылочная прозрачность вашего языка программирования есть.
Например, если бы foo был x ++ в смысле программирования на C, то вы не могли бы безопасно выполнить это сокращение (то есть, если бы вы выполняли это сокращение, вы не получили бы ту же программу, с которой начали).
В практических языках программирования вы не увидите идеальной ссылочной прозрачности, но функциональные программисты заботятся об этом больше, чем о большинстве (см. Haskell, где это является основной целью).
(Полное раскрытие: я функциональный программист, поэтому в качестве главного ответа вы должны взять это объяснение с небольшим количеством соли.)
источник
Если вы интересуетесь этимологией (т. Е. Почему у этой концепции именно такое название), посмотрите мой пост в блоге на эту тему. Терминология происходит от философа / логика Куайна.
источник
В 1 есть ясность двух рассматриваемых языков:
Во 2, благодаря близости объекта и метаязыка, их можно спутать.
Как разработчик языка, я считаю, что мне нужно постоянно помнить это различие.
Профессор Редди, могу я перефразировать вас так :-)
источник
Следующий ответ, я надеюсь, добавляет и уточняет спорные 1-й и 3-й ответы.
Допустим, что выражение обозначает или ссылается на некоторый референт. Однако вопрос заключается в том, можно ли эти ссылки изоморфно кодировать как часть самих выражений, называя такие выражения «значениями». Например, значения литеральных чисел являются подмножеством набора арифметических выражений, значения истинности являются подмножеством набора логических выражений и т. Д. Идея состоит в том, чтобы вычислить выражение по его значению (если оно есть). Таким образом, слово «значение» может относиться к обозначению или к выделенному элементу набора выражений. Но если между референтом и значением существует изоморфизм (биекция), мы можем сказать, что это одно и то же. (При этом нужно быть осторожным, чтобы определить ссылки и изоморфизм, что доказано областью денотационной семантики. Чтобы привести пример, упомянутый в ответах на 3-й ответ,
data Nat = Zero | Suc Nat
не соответствует ожидаемому набору натуральных чисел.)Давайте напишем
E[·]
для выражения с дырой, также известный в некоторых кругах как «контекст». Два примера контекста для C-подобных выражений:[·]+1
и[·]++
.Давайте напишем
[[·]]
для функции, которая принимает выражение (без дыры) и передает его значение (референт, обозначение и т. Д.) В некоторый универсум, обеспечивающий смысл. (Я заимствую обозначения из области денотационной семантики.)Давайте адаптируем определение Куайна несколько формально следующим образом: контекст
E[·]
является ссылочно-прозрачным, если даны любые два выраженияE1
иE2
(без пробелов) таким образом, что[[E1]] = [[E2]]
(то есть выражения обозначают / ссылаются на один и тот же референт), то это тот случай, когда[[E[E1]]] = [[E[E2]]]
(т.е. заполнение - в лунке с либоE1
илиE2
приводит к выражениям, которые также обозначают тот же референт).Правило Лейбница о замене равных на равные обычно выражается как «если
E1 = E2
тогдаE[E1] = E[E2]
», которое говорит, чтоE[·]
это функция. Функция (или, в этом отношении, программа, вычисляющая функцию) - это отображение от источника к цели, так что существует не более одного целевого элемента для каждого элемента источника. Недетерминированные функции - это неправильные числа, это либо отношения, либо функции, доставляющие множества и т. Д. Если в правлении Лейбница равенство=
является денотационным, то двойные скобки просто принимаются как должное и исключаются. Таким образом, ссылочно-прозрачный контекст - это функция. И правило Лейбница является основным компонентом эквалайзерного мышления, поэтому эквациональное мышление определенно связано с прозрачностью ссылок.Хотя
[[·]]
это функция от выражений до обозначений, она может быть функцией от выражений до «значений», понимаемых как ограниченное подмножество выражений, и[[·]]
может пониматься как оценка.Теперь, если
E1
выражение иE2
значение, мы имеем то, что, по моему мнению, подразумевают большинство людей при определении ссылочной прозрачности в терминах выражений, значений и оценки. Но, как показано в первом и третьем ответах на этой странице, это неточное определение.Проблема с контекстами, такими как
[·]++
не является побочным эффектом, но в том, что его значение не определено в C изоморфно его значению. Функции не являются значениями (ну, это указатели на функции), тогда как в функциональных языках программирования они есть. Лэндин, Стрейчи и пионеры денотационной семантики были достаточно умны в использовании функциональных миров для придания смысла.Для императивных C-подобных языков мы можем (приблизительно) предоставить семантику для выражений, используя функцию
[[·]] : Expression -> (State -> State x Value)
.Value
это подмножествоExpression
.State
содержит пары (идентификатор, значение). Семантическая функция принимает выражение и доставляет в качестве значения функцию из текущего состояния в пару с обновленным состоянием и значением. Например,[[x]]
это функция из текущего состояния для пары, первый компонент которой является текущим состоянием, а второй компонент - значением x. Напротив,[[x++]]
это функция от текущего состояния к паре, первый компонент которой является состоянием, в котором значение x увеличивается, а вторым компонентом является то же самое значение. В этом смысле контекст[·]++
является ссылочно прозрачным, если он удовлетворяет определению, данному выше.Я думаю, что функциональные программисты имеют право использовать ссылочную прозрачность в том смысле, что они естественным образом восстанавливаются
[[·]]
как функция из выражений в значения. Функции являются первоклассными значениями, и состояние также может быть значением, а не обозначением. Монада состояний является (частично) чистым механизмом для передачи (или многопоточности) состояния.источник
Обратите внимание, что это понятие «значение» происходит в сознании наблюдателя. Таким образом, одна и та же «ссылка» может означать разные вещи для разных людей. Так, например, у нас есть эдинбургская страница для устранения неоднозначности в Википедии.
Связанная проблема, которая может проявиться в контексте программирования, может быть полиморфизмом.
И, возможно, у нас должно быть название для особого случая полиморфизма (или, возможно, даже приведения), где для наших целей различные полиморфные случаи семантически эквивалентны (в отличие от простого сходства. Например, число 1 - которое может быть представлено используя целочисленный тип, или сложный тип, или любой из множества других типов - можно лечить полиморфно).
источник
Я нашел определение ссылочной прозрачности в книге « Структура и реализация компьютерных программ » (книга мастера) полезным, потому что оно дополняется объяснением того, как ссылочная прозрачность нарушается введением операции присваивания . Ознакомьтесь со следующей слайд-колодой, которую я сделал по этому вопросу: https://www.slideshare.net/pjschwarz/introduction-assignment-invalidates-the-substitution-model-of-evaluation-and-violates-referential-transparency-as- объяснены в-SICP-на-мастер-книги
источник
Ссылочная прозрачность может быть просто сформулирована как:
Например, язык программирования Haskell является чисто функциональным языком; Это означает, что он является прозрачным по ссылкам.
источник