Чистота против ссылочной прозрачности - PullRequest
51 голосов
/ 01 февраля 2011

Термины кажутся определенными по-разному, но я всегда думал о том, что одно подразумевает другое; Я не могу вспомнить ни одного случая, когда выражение является ссылочно прозрачным, но не чистым, или наоборот.

Википедия ведет отдельные статьи для этих понятий и говорит:

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

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

С Чистые выражения :

Чистые функции необходимы для построить чистые выражения. [...] Чистый выражения часто упоминаются как быть ссылочно прозрачным.

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

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

Ответы [ 5 ]

39 голосов
/ 11 февраля 2011

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

Не могу сообщить вам, но я могу советуем вам сдаться: поскольку даже крошечные кадры теоретиков с заостренным языком не могут договориться о том, что это значит, термин "референтно прозрачный" является бесполезным .Так что не используйте его.


PS В любой теме, связанной с семантикой языков программирования, Википедия ненадежна.Я отказался от попыток исправить это;процесс в Википедии, похоже, учитывает изменения и популярное голосование за стабильность и точность.

7 голосов
/ 02 февраля 2011

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

Однако возможно иметь ссылочно прозрачные функции, которые не являются чистыми. Я могу написать функцию, которая получает int i, затем генерирует случайное число r, вычитает r из себя и помещает его в s, затем возвращает i - s. Очевидно, что эта функция нечиста, потому что она генерирует случайные числа. Тем не менее, это ссылочный прозрачный. В этом случае пример глупый и надуманный. Однако, например, в Haskell, функция id имеет тип a - > a, тогда как моя функция stupidId будет иметь тип a -> IO a, что указывает на использование побочных эффектов. Когда программист может посредством внешнего доказательства гарантировать, что его функция действительно прозрачна по ссылкам, он может использовать unsafePerformIO, чтобы убрать IO назад из типа.

4 голосов
/ 02 февраля 2011

Я несколько не уверен в ответе, который я даю здесь, но, несомненно, кто-то укажет нам направление. : -)

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

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

Так что, я думаю, мы выяснили, какими могут быть "чистота" и "побочные эффекты".

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

Надеюсь, это поможет.

1 голос
/ 24 апреля 2015

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

Из одного из слайдов:

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

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

[...] это так же, как если бы оно было чисто в первую очередь, не так ли?

Из определений, которые у нас есть, нет, это не так.

Есть ли более простой способ понять различия между чистым выражением и ссылочно-прозрачным,если есть?

Попробуйте слайды, которые я упомянул выше .

0 голосов
/ 05 декабря 2014

Я процитирую то, что Джон Митчелл написал в своей книге Концепция на языке программирования .Я не помню его построчно, но он определяет, что чистый функциональный язык должен пройти декларативный языковой тест, который:

"В рамках определенного замедления x1, ..., xn, всевхождение выражения e, содержащего только переменные x1, ..., xn, имеют одинаковое значение. "

Короче говоря, все остальные, упомянутые без побочных эффектов или без побочных эффектов (" Отсутствие "побочные эффекты).

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

Который в 1-м случае имеет место, но во 2-м случае становится слишком странным.

Случай 1: «Я видел, как Уолтер садился в свою новую машину ».

И если у Уолтера есть Centro, то мы можем заменить его в данном предложении следующим образом:

«Я видел, как Уолтер попал в его Centro »

В отличие от первого:

Дело № 2: Его звали Уильям Руфус из-за его прочитанной бороды.

Руфус означает «немного красного», и речь шла об Уильяме IV из Англии.

"Его звали Уильям IV из-за его прочитанной бороды".выглядит слишком неловко

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

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

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

...