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


285

Что означает термин ссылочная прозрачность ? Я слышал, что это описывается как «это означает, что вы можете заменить равные равными», но это выглядит как неадекватное объяснение.


1
вау, я удивляюсь, почему внезапный всплеск популярности этого вопроса ...
Клавдиу

1
@claudia: Я не могу сказать наверняка, но r / haskell получил известность, и многие чувствовали, что Uday был, хотя и довольно точным, немного посмеялся над сообществом.
Эфри

6
@efrey Джайб, возможно это было. Но когда функциональные программисты сбивают императивные языки программирования и функциональные языки с побочными эффектами (например, Lisp и ML), утверждая, что они не являются прозрачными по ссылкам, разве они не соглашаются? Разве они не должны, по крайней мере, понять свои факты прямо перед этим?
Удай Редди

2
@Claudiu Я разместил его на Haskell Reddit, а Конал написал в Твиттере. Я нашел обсуждение интересным и подумал, что оно заслуживает более широкого обсуждения. Я обратил внимание на насмешку Удея, чтобы стимулировать дискуссию. Я согласен с тем, что нам, профессионалам, иногда можно довольствоваться и нуждаться в хорошем продукте - молодец Удай за то, что предоставил его!
chrisdornan

7
@efrey. Действительно, именно поэтому я решил сослаться на Bird и Wadler (семантиков?) В моем втором посте. Знающие люди знают, что популярная концепция прозрачности ссылок является расплывчатой ​​и, возможно, непоследовательной. Но это никогда не было должным образом объяснено сообществу программистов. Надеюсь, мое письмо здесь будет иметь значение.
Удай Редди

Ответы:


362

Термин «ссылочная прозрачность» происходит от аналитической философии , отрасли философии, которая анализирует конструкции, утверждения и аргументы естественного языка, основанные на методах логики и математики. Другими словами, это самая близкая тема вне компьютерной науки к тому, что мы называем семантикой языка программирования . Философ Уиллард Куайн был ответственен за инициирование концепции ссылочной прозрачности, но это также подразумевалось в подходах Бертрана Рассела и Альфреда Уайтхеда.

По своей сути «ссылочная прозрачность» - очень простая и понятная идея. Термин «референт» используется в аналитической философии, чтобы говорить о том, на что ссылается выражение . Это примерно то же самое, что мы подразумеваем под «значением» или «обозначением» в семантике языка программирования. Используя пример Эндрю Биркетта ( сообщение в блоге ), термин «столица Шотландии» относится к городу Эдинбургу. Это простой пример «референта».

Контекст в предложении является «ссылочно-прозрачным», если замена термина в этом контексте другим термином, относящимся к той же сущности , не меняет смысла. Например

Шотландский парламент собирается в столице Шотландии.

означает так же, как

Парламент Шотландии встречается в Эдинбурге.

Таким образом, контекст «Шотландский парламент встречается в ...» является референтно прозрачным контекстом. Мы можем заменить «столицу Шотландии» на «Эдинбург», не меняя смысла. Другими словами, контекст заботится только о том, к чему относится этот термин, и больше ничего. В этом смысле контекст «ссылочно прозрачен».

С другой стороны, в предложении

Эдинбург был столицей Шотландии с 1999 года.

мы не можем сделать такую ​​замену. Если бы мы это сделали, мы бы получили «Эдинбург был Эдинбургом с 1999 года», что является сумасшедшей вещью, и не передает того же значения, что и первоначальное предложение. Таким образом, может показаться, что контекст "Эдинбург был ... с 1999 года" является непрозрачным в отношении ссылок (противоположность прозрачному в отношении ссылок). По-видимому, он заботится о чем-то большем, нежели термин Что это?

Такие вещи, как «столица Шотландии», называются определенными терминами, и в течение долгого времени они не причиняли головной боли логикам и философам. Рассел и Куайн разобрались с ними, сказав, что они на самом деле не являются «ссылочными», т. Е. Ошибочно думать, что приведенные выше примеры используются для обозначения сущностей. Правильный способ понять, что «Эдинбург был столицей Шотландии с 1999 года», это сказать

Столица Шотландии существует с 1999 года, и эта столица - Эдинбург.

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

Какое все это имеет отношение к программированию? Не очень, на самом деле. Как мы уже говорили, ссылочная прозрачность - это инструмент, который используется для понимания языка, т. Е. При назначении значения . Кристофер Стрейчи , который основал семантику языка программирования, использовал его в своем исследовании значения. Его основополагающая статья « Основные понятия в языках программирования » доступна в Интернете. Это красивая бумага, и каждый может ее прочитать и понять. Поэтому, пожалуйста, сделайте это. Вы будете очень просветленным. Он вводит термин «ссылочная прозрачность» в этом параграфе:

Одним из наиболее полезных свойств выражений является то, что Куайн называет ссылочной прозрачностью. По сути это означает, что если мы хотим найти значение выражения, которое содержит подвыражение, единственное, что нам нужно знать о подвыражении, это его значение. Любые другие особенности подвыражения, такие как его внутренняя структура, количество и характер его компонентов, порядок, в котором они оцениваются, или цвет чернил, в которых они написаны, не имеют отношения к значению основного выражение.

Использование «по существу» предполагает, что Стрейчи перефразирует его, чтобы объяснить его простыми словами. Функциональные программисты, кажется, понимают этот абзац по-своему. Есть 9 других случаев «ссылочной прозрачности» в статье, но они, кажется, не беспокоятся ни о каких других. Фактически вся статья Стрейчи посвящена объяснению значения императивных языков программирования . Но сегодня функциональные программисты утверждают, что императивные языки программирования не являются ссылочно прозрачными. Стрейчи будет превращаться в его могилу.

Мы можем спасти ситуацию. Мы сказали, что естественный язык «грязный или, по крайней мере, сложный», потому что он сделан удобным для практического использования. Языки программирования одинаковы. Они «грязные или, по крайней мере, сложные», потому что они сделаны так, чтобы их было удобно использовать на практике. Это не значит, что они должны нас смущать. Они просто должны быть поняты правильно, используя мета-язык, который является ссылочно прозрачным, чтобы у нас была ясность смысла. В статье, которую я цитировал, Стрейчи делает именно это. Он объясняет значение императивных языков программирования, разбивая их на элементарные понятия, нигде не теряя ясности. Важной частью его анализа является указание на то, что выражения в языках программирования имеют два вида «значений»,r-значения . До статьи Стрейчи это не было понято, и воцарилась путаница. Сегодня определение C упоминает об этом регулярно, и каждый программист C понимает это различие. (Понимают ли программисты на других языках это одинаково хорошо, трудно сказать.)

И Куайн, и Стрейчи были обеспокоены значением языковых конструкций, которые включают некоторую форму зависимости от контекста. Например, наш пример «Эдинбург является столицей Шотландии с 1999 года» означает тот факт, что «столица Шотландии» зависит от времени, в которое она рассматривается. Такая зависимость от контекста является реальностью, как на естественных языках, так и на языках программирования. Даже в функциональном программировании свободные и связанные переменные должны интерпретироваться с учетом контекста, в котором они появляются. Зависимость от контекста любого вида так или иначе блокирует ссылочную прозрачность. Если вы попытаетесь понять значение терминов без учета контекста, от которого они зависят, вы снова получите путаницу. Куайна интересовало значение модальной логики. Он держал этоМодальная логика была непрозрачной по ссылкам, и ее следует очистить, переведя ее в прозрачную структуру по ссылкам (например, рассматривая необходимость как доказуемость). Он в значительной степени проиграл эту дискуссию. Логики и философы одинаково сочли возможную мировую семантику Крипке совершенно адекватной. Подобная ситуация также царит с императивным программированием. Зависимость от состояния, объясняемая Стрейчи, и зависимость от запаса, объясняемая Рейнольдсом (аналогично возможной мировой семантике Крипке), вполне адекватны. Функциональные программисты мало знают об этом исследовании. Их идеи относительно ссылочной прозрачности следует воспринимать с большой долей соли.

[Дополнительное примечание: приведенные выше примеры показывают, что простая фраза, такая как «столица Шотландии», имеет несколько уровней значения. На одном уровне мы можем говорить о столице в настоящее время. На другом уровне мы могли бы говорить о всех возможных столицах, которые Шотландия могла иметь с течением времени. Мы можем «увеличить» конкретный контекст и «уменьшить», чтобы довольно легко охватить все контексты в обычной практике. Эффективность естественного языка использует нашу способность сделать это. Императивные языки программирования эффективны практически так же. Мы можем использовать переменную x в правой части присваивания (значение r ), чтобы говорить о ее значении в определенном состоянии. Или мы могли бы поговорить о его l-значениикоторый охватывает все государства. Людей редко смущают такие вещи. Однако они могут или не могут точно объяснить все уровни значения, присущие языковым конструкциям. Все такие слои значения не обязательно являются «очевидными», и это вопрос науки, чтобы изучить их должным образом. Однако неспособность обычных людей объяснять такие многоуровневые значения не означает, что они смущены ими.]

Отдельный «постскриптум», приведенный ниже, связывает это обсуждение с проблемами функционального и императивного программирования .


10
Спасибо, но я не считаю, что существует «очевидное» экстенсиональное понятие равенства. Когда я сказал, что «столица Шотландии» относится к городу Эдинбургу, вы дважды об этом не задумывались. Но когда я начал говорить о «с 1999 года», вы внезапно осознали, что есть время. Таким образом, экстенсиональное понятие равенства может быть довольно тонким, и оно формализовано исследователями языка программирования. Люди, которые хотят иметь полное представление о равенстве экстенсий, должны изучить плоды этого исследования. Это может быть вовсе не «очевидно».
Удай Редди

5
Фантастика! Добро пожаловать в распространенные заблуждения о RT, например, связывая его с функциями . Или определение путем замены выражения его значением (как в Википедии) - как ни странно, поскольку выражения и значения - это разные вещи. Возможно, единственное место, где люди ошибаются при рассмотрении RT императивных языков, - это предположить, что эти «значения» - это простые вещи, такие как числа, а не более сложные вещи, такие как функции из магазина.
Конал

13
@sclv Что касается более широкого влияния аналитической философии на информатику, я должен сказать, что информатика, как мы ее знаем, была основана Годелем, Черчем, Клини и Тьюрингом. Эти люди были логиками и хорошо разбирались в математических и философских аспектах логики, в частности в традициях Пеано, Фреге, Рассела, Уайтхеда, Карнапа и Куайна. Первые пионеры современной информатики знали об этих связях. Но быстрый рост компьютерных наук разорвал их. Нам нужно вернуться к ним.
Удай Редди

5
Логика @sclv традиционно трактуется как наука о последствиях . Но я думаю, что это шире. Это наука об информации . Куайн, я вижу в качестве первого, кто выдвинул более широкую точку зрения. «Слово и объект» - это анализ информативности высказываний на естественном языке. Однако ни философы, ни математики никогда не проявляли активного интереса к вычислениям , что весьма озадачивает, учитывая то, что центральные вычисления были для цивилизации и науки с незапамятных времен. Нам нужно найти способы заинтересовать их.
Удай Редди

3
@Conal: Я добавил новый ответ, который усиливает вашу точку зрения. Это, вероятно, будет в нижней части страницы.
Uday Reddy

134

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

Вот пример ссылочной прозрачной функции:

int plusOne(int x)
{
  return x+1;
}

С помощью ссылочной прозрачной функции, с учетом входных данных и функции, вы можете заменить ее значением вместо вызова функции. Поэтому вместо вызова plusOne с параметром 5 мы можем просто заменить его на 6.

Еще один хороший пример - математика в целом. В математике с заданной функцией и входным значением она всегда будет отображаться на одно и то же выходное значение. f (x) = x + 1. Поэтому функции в математике являются ссылочно прозрачными.

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

Ссылочная прозрачность всегда используется в функциональных языках, таких как Haskell.

-

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

//global G
int G = 10;

int plusG(int x)
{//G can be modified externally returning different values.
  return x + G;
}

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

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


1
Просто наполовину, возможно иметь полностью ссылочно прозрачный объект со ссылочно прозрачными функциями-членами. Смотрите okmij.org/ftp/Scheme/oop-in-fp.txt
Джонатан Аркелл

1
И вот код, о котором идет речь в этой статье: okmij.org/ftp/Scheme/pure-oo-system.scm
Джонатан Аркелл

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

13
То, о чем вы говорите, - это не ссылочная прозрачность, хотя обычно ее называют таковой. Смотрите два ответа Удея и комментарии к ним. В частности, то, что вы называете «результатом», не является обозначением. Если вы замените «plusG 3» на любое другое выражение с таким же значением / обозначением, вы действительно получите программу с таким же значением, поэтому RT действительно работает на императивных языках. Выражения «3 + 10» или «13» не имеют того же значения, что и «plusG 3», потому что значение в императивных языках является функцией «store» (состояния).
Конал

1
Я только что прочитал статью о побочных эффектах и ​​изменении состояния и понял, что это как-то связано с RT. Не могли бы вы добавить примечание к нему?
Гаурав

91

Ссылочно-прозрачная функция - это функция, которая зависит только от ее ввода.


4
Вот почему это сложно в ОО-программировании, потому что объекты имеют состояние.
Крис

5
Так правильно ли говорить, что «ссылочно-прозрачный» идентичен «детерминированному» при описании функций? Если нет, в чем разница между двумя терминами?
mwolfe02

1
Это также звучит как определение «чистой» функции.
Евгений Александрович

75

[Это постскриптум к моему ответу от 25 марта, чтобы приблизить обсуждение к проблемам функционального / императивного программирования.]

Представление функциональных программистов о ссылочной прозрачности, кажется, отличается от стандартного понятия тремя способами:

  • В то время как философы / логики используют такие термины, как «ссылка», «обозначение», «designatum» и « bedeutung » (немецкий термин Фреге), функциональные программисты используют термин «значение». (Это не совсем их работа. Я замечаю, что Лэндин, Стрейчи и их потомки также использовали термин «ценность», чтобы говорить об упоминании / обозначении. Это может быть просто терминологическое упрощение, которое представили Ландин и Стрейчи, но, похоже, оно делает большая разница при использовании наивно.)

  • Функциональные программисты, похоже, считают, что эти «ценности» существуют внутри языка программирования, а не снаружи. При этом они отличаются как от философов, так и от семантиков языка программирования.

  • Кажется, они считают, что эти «ценности» должны быть получены путем оценки.

Например, статья Wikipedia о ссылочной прозрачности говорит сегодня утром:

Выражение называется прозрачным по ссылкам, если его можно заменить значением, не меняя поведения программы (другими словами, получая программу с такими же эффектами и выходными данными на одном входе).

Это полностью расходится с тем, что говорят философы / логики. Они говорят, что контекст является ссылочным или ссылочно-прозрачным, если выражение в этом контексте может быть заменено другим выражением, которое ссылается на то же самое ( базовое выражение). Кто эти философы / логики? К ним относятся Фреге , Рассел , Уайтхед , Карнап , Куайн , Церковьи бесчисленное множество других. Каждый из них - высокая фигура. Объединенная интеллектуальная сила этих логиков потрясающая, если не сказать больше. Все они единодушны в том положении, что ссылки / обозначения существуют вне формального языка, и выражения в языке могут говорить только о них. Таким образом, все, что можно сделать в языке, - это заменить одно выражение другим выражением, относящимся к той же сущности. Сами ссылки / обозначения не существуют внутри языка. Почему функциональные программисты отклоняются от этой устоявшейся традиции?

Можно предположить, что семантики языка программирования могли ввести их в заблуждение. Но они этого не сделали.

Landin :

(a) каждое выражение имеет вложенную структуру подвыражения, (b) каждое подвыражение обозначает что-то (обычно число, значение истинности или числовую функцию) , (c) то, что обозначает выражение, т. е. его «значение», зависит только от значения его подвыражений, а не о других их свойствах. [Добавлен акцент]

Стой :

Единственное, что имеет значение в выражении, - это его значение, и любое подвыражение может быть заменено любым другим равным по значению [Добавлено выделение]. Более того, значение выражения в определенных пределах одинаково, когда бы оно ни происходило ».

Птица и Вадлер :

значение выражения зависит только от значений составляющих его выражений (если они есть), и эти подвыражения могут быть свободно заменены другими, имеющими такое же значение [Добавлено выделение].

Таким образом, в ретроспективе, попытки Ландина и Стрейчи упростить терминологию путем замены «ссылки» / «обозначения» на «значения» могли быть неразумными. Как только человек слышит о «ценности», возникает искушение подумать о процессе оценки, который ведет к нему. Не менее заманчиво думать о том, что оценка производит, как о «ценности», хотя может быть совершенно ясно, что это не означает. Вот что я понял, чтобы произошло с понятием «ссылочной прозрачности» в глазах функциональных программистов. Но «ценность», о которой говорили ранние семантики, не является результатом оценки или результата функции или любой другой вещи. Это обозначение термина.

Как только мы понимаем так называемую «ценность» выражения («ссылка» или «обозначение» в дискурсе классических философов) как сложный математический / концептуальный объект, открываются все виды возможностей.

  • Стрейчи интерпретировал переменные в императивных языках программирования как L-значения , как упоминалось в моем ответе от 25 марта, который представляет собой сложный концептуальный объект, который не имеет прямого представления в синтаксисе языка программирования.
  • Он также интерпретировал команды на таких языках как функции состояния к состоянию, еще один пример сложного математического объекта, который не является «значением» в синтаксисе.
  • Даже вызов функции с побочным эффектом в C имеет четко определенное «значение» в качестве преобразователя состояний, который отображает состояния в пары состояний и значений (так называемая «монада» в терминологии функциональных программистов).

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

Немного истории может пролить свет на то, как возникли эти заблуждения. Период между 1962 и 1967 годами был очень интенсивным для Кристофера Стрейчи. В период с 1962 по 1965 год он работал неполный рабочий день в качестве помощника исследователя в Морисе Уилксе для разработки и реализации языка программирования, который стал известен как CPL. Это был императивный язык программирования, но он должен был также иметь мощные функциональные возможности языка программирования. Ландин, который был сотрудником Strachey в своей консалтинговой компании, оказал огромное влияние на взгляды Strachey на языки программирования. В знаковой статье 1965 года « Следующие 700 языков программирования » Ландин безоговорочно продвигает функциональные языки программирования (называя их денотативнымиязыки) и описывает императивные языки программирования как их "антитезу". В последующем обсуждении мы видим, что Стрейчи вызывает сомнения в сильной позиции Лэндина.

... DL образуют подмножество всех языков. Это интересное подмножество, но его неудобно использовать, если вы к нему не привыкли. Мы нуждаемся в них, потому что в настоящее время мы не знаем, как создавать доказательства с языками, которые включают императивы и скачки. [Добавлен акцент]

В 1965 году Стрейчи занял должность читателя в Оксфорде и, по-видимому, работал практически полный рабочий день над разработкой теории императивов и прыжков. К 1967 году он был готов с теорией, которую он преподавал в своем курсе « Основные понятия в языках программирования » в копенгагенской летней школе. Предполагалось, что конспекты лекций были опубликованы, но «к сожалению, из-за расточительного редактирования материалы так и не были реализованы; как и большая часть работы Стрейчи в Оксфорде, однако, газета имела влиятельный частный тираж». ( Мартин Кэмпбелл-Келли )

Сложность получения работ Стрейчи могла привести к распространению путаницы, когда люди полагались на вторичные источники и слухи. Но теперь, когда « Фундаментальные концепции » легко доступны в Интернете, нет необходимости прибегать к угадыванию работы. Мы должны прочитать это и решить, что имел в виду Стрейчи. В частности:

  • В разделе 3.2 он имеет дело с «выражениями», где он говорит о «ссылочной прозрачности R-значения».
  • Его раздел 3.3 посвящен «командам», в которых он говорит о «ссылочной прозрачности L-значения».
  • В разделе 3.4.5 он говорит о «функциях и процедурах» и заявляет, что «любое отклонение ссылочной прозрачности R-значения в контексте R-значения должно быть либо устранено путем разложения выражения на несколько команд и более простых выражений, либо, если это оказывается трудным, предметом комментария. "

Любой разговор о «ссылочной прозрачности» без понимания различия между L-значениями, R-значениями и другими сложными объектами, которые населяют концептуальную вселенную императивного программиста, в корне ошибочен.


10
Я думаю, что стоит подчеркнуть, что смешение этих двух понятий «ценность» (оценки против обозначений) вводит в заблуждение функциональных программистов в их критике императивных языков, где разрыв между понятиями велик.
Конал

8
то есть понятие оценки приводит к выводу, что императивные языки не являются RT, а понятие обозначения - нет.
Конал

12
Мне кажется, что, как только вы действительно полностью прижмете денотационную семантику языка, он не может не быть прозрачным по ссылкам. Так что это кажется равносильным тому, что этот термин бесполезен в отношении языков программирования.
Том Крокетт

20
Таким образом, кажется, что люди привыкли использовать термин для обозначения чего-то материально отличного от того, что имели в виду другие люди, когда использовали этот термин в прошлом. На что я говорю: добро пожаловать на английский язык.
Даниэль Пратт

17
@DanielPratt: Если функциональные программисты хотят иметь в виду побочные эффекты, то почему они называют это «ссылочной прозрачностью»? Они могут просто назвать это «побочным эффектом-свободой», что является совершенно ясной идеей. Никому не нужно будет спрашивать на stackexchange, что означает «побочный эффект-свобода». Где необходимость в том, чтобы прогонять грандиозные классические термины, которые, кажется, никто не понимает?
Удай Редди

23

Выражение является ссылочно прозрачным, если его можно заменить его значением, не изменяя алгоритм, что дает алгоритм, который имеет те же эффекты и выводит на тот же вход.


18

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


10

Для тех, кто нуждается в кратком объяснении, я рискну один (но прочитайте раскрытие ниже).

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

fx = x + x,

Простота, с которой вы можете (безопасно) заменить f (foo) на foo + foo в рамках этого определения, не имея слишком много ограничений на то, где вы можете выполнить это сокращение, является хорошим показателем того, насколько ссылочная прозрачность вашего языка программирования есть.

Например, если бы foo был x ++ в смысле программирования на C, то вы не могли бы безопасно выполнить это сокращение (то есть, если бы вы выполняли это сокращение, вы не получили бы ту же программу, с которой начали).

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

(Полное раскрытие: я функциональный программист, поэтому в качестве главного ответа вы должны взять это объяснение с небольшим количеством соли.)


3
У меня нет проблем с языками, облегчающими уравнивание. Но я бы поспорил, что это имеет какое-то отношение к "ссылочной прозрачности", как это определено классически. Во-вторых, как практический программист, я думаю, что рациональное мышление переоценено. Обоснование, которое важно на практике, связано с предусловиями, постусловиями, инвариантами и абстракцией данных. Для людей, которые полагаются на такие методы мышления, побочные эффекты, кажется, не имеют большого значения. Поэтому, хотя я согласен с вами, что побочные эффекты в выражениях - это плохая идея, они, похоже, не являются убийственным аргументом.
Удай Редди

1
@UdayReddy Просто потому, что функциональные программисты выбрали определенный метод набора ссылочной прозрачности в своих программах (устранение побочных эффектов и разработку сложной и мощной алгебры программ), или у некоторых практиков, которые, вероятно, не понимают ссылочную прозрачность, а также они думают, что это так, но это не значит, что функциональные языки программирования не способны повысить ссылочную прозрачность или что программисты и составители компиляторов функциональных языков не используют это увеличение формальной управляемости во многих хороших целях.
chrisdornan

2
Крис: Uday указал, что Strachey устранил проблему непрозрачности ссылок в семантике языка программирования, особенно для императивных языков. Таким образом, функциональные программисты не могут «набирать ссылочную прозрачность в своих программах». В качестве конкретного примера, Haskell IO не помогает с RT именно потому, что помощь RT не требуется.
Конал

2
@chrisdornan: Извините за мой первый комментарий выше. Мне самому было трудно разобрать то, что я пытался сказать в первых двух предложениях :-( Но вот объяснение. Рассмотрим двухуровневое или многоуровневое исчисление этапов. Каждый оператор этапов является ссылочно-непрозрачным. , оператор цитаты. Однако вы можете выполнять эквациональные рассуждения на каждом этапе совершенно нормально. Таким образом, каждый референциально непрозрачный оператор устанавливает границы для эквациональных рассуждений. Но у вас все еще есть эквациональные рассуждения в этих границах.
Uday Reddy

1
@chrisdomain: Более того, очень немногие люди хотели бы быть сторонниками прозрачности, чтобы изгнать таких операторов. Эти операторы чрезвычайно полезны. Программирование без них путем постановки вручную было бы утомительным, подверженным ошибкам и уродливым. И постановка вручную не купила бы вам более уравновешенных рассуждений, чем вы имели ранее. Таким образом, запрещение хороших программных устройств в пуристической погоне за эквациональным мышлением было бы равносильно отрезанию носа, чтобы насолить лицу.
Uday Reddy

8

Если вы интересуетесь этимологией (т. Е. Почему у этой концепции именно такое название), посмотрите мой пост в блоге на эту тему. Терминология происходит от философа / логика Куайна.


4
  1. Denotational-семантика основана на языках моделирования путем создания доменов, которые составляют денотируемые значения .
  2. Функциональные программисты используют термин « значение» для описания сходимости вычислений, основанных на правилах переписывания языка, т.е. его операционная семантика.

В 1 есть ясность двух рассматриваемых языков:

  • моделируемый объектный язык
  • язык моделирования, метаязык

Во 2, благодаря близости объекта и метаязыка, их можно спутать.

Как разработчик языка, я считаю, что мне нужно постоянно помнить это различие.

Профессор Редди, могу я перефразировать вас так :-)

В контексте функционального программирования и семантики, термин Ссылочная прозрачность не референциально прозрачным.


1
Ха ха Спасибо за объяснение. Проблема также в том, что функциональные программисты действуют так, как будто они имеют общее понятие «прозрачности ссылок», которое применимо ко всем языкам программирования . Но это зависит от их понятия «ценность», которая может иметь или не иметь смысла для других языков. Чтобы претендовать на общую теорию «ссылочной прозрачности», им необходимо создать общую теорию «стоимости». Это отсутствует до сих пор.
Удай Редди

4

Следующий ответ, я надеюсь, добавляет и уточняет спорные 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-й» и «3-й» ответы являются ответами UdayReddy «25 марта» и «postscript» соответственно. Ординалы не являются хорошим способом ссылки на ответы в SO. Мало того, что голоса и приемы могут меняться с течением времени, есть несколько вариантов выбора.
Philipxy

2

Обратите внимание, что это понятие «значение» происходит в сознании наблюдателя. Таким образом, одна и та же «ссылка» может означать разные вещи для разных людей. Так, например, у нас есть эдинбургская страница для устранения неоднозначности в Википедии.

Связанная проблема, которая может проявиться в контексте программирования, может быть полиморфизмом.

И, возможно, у нас должно быть название для особого случая полиморфизма (или, возможно, даже приведения), где для наших целей различные полиморфные случаи семантически эквивалентны (в отличие от простого сходства. Например, число 1 - которое может быть представлено используя целочисленный тип, или сложный тип, или любой из множества других типов - можно лечить полиморфно).


0

Я нашел определение ссылочной прозрачности в книге « Структура и реализация компьютерных программ » (книга мастера) полезным, потому что оно дополняется объяснением того, как ссылочная прозрачность нарушается введением операции присваивания . Ознакомьтесь со следующей слайд-колодой, которую я сделал по этому вопросу: https://www.slideshare.net/pjschwarz/introduction-assignment-invalidates-the-substitution-model-of-evaluation-and-violates-referential-transparency-as- объяснены в-SICP-на-мастер-книги


0

Ссылочная прозрачность может быть просто сформулирована как:

  • Выражение, всегда оценивающее один и тот же результат в любом контексте [1] ,
  • Функция, если заданы одни и те же параметры дважды, должна давать один и тот же результат дважды [2] .

Например, язык программирования Haskell является чисто функциональным языком; Это означает, что он является прозрачным по ссылкам.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.