Що таке референтна прозорість?


285

Що означає термін референтна прозорість ? Я чув, як це описано як "це означає, що ви можете замінити рівняння на рівні", але це здається неадекватним поясненням.


1
ух, мені цікаво, чому раптовий підйом популярності цього питання ...
Клавдіу

1
@claudia: Я не можу сказати напевно, але r / haskell отримав вітер, і багато хто вважав, що Удай, хоч і досить точний, зайняв трохи джибу в громаді.
efrey

6
@efrey Джиб, можливо, так і було. Але, коли функціональні програмісти збивають імперативні мови програмування та побічні функціональні мови (на зразок Lisp та ML), стверджуючи, що вони не є референтно прозорими, хіба вони не беруть жодної позиції? Чи повинні вони принаймні виправити свої факти перед тим, як зробити це?
Удай Редді

2
@Claudiu Я публікував його на Haskell Reddit і Conal твітнув його. Я вважав дискусію цікавою і вважав, що вона заслуговує на ширшу дискусію. Я звернув увагу на джиб Удая, щоб стимулювати дискусію. Я погоджуюсь, що нам, FPers, іноді можуть бути поступливі і потрібні гарні пропозиції - добре зроблено Uday для його надання!
chrisdornan

7
@efrey. Дійсно, саме тому я вирішив цитувати з "Птахів і Уодлерів" (семантиків?) У своїй другій публікації. Люди, які знають, знають, що популярна концепція прозорості референції є розпливчастою та, можливо, непослідовною. Але це ніколи не було належним чином пояснено програмістській спільноті. Сподіваюсь, моє написання тут змінить значення.
Удай Редді

Відповіді:


362

Термін "референтна прозорість" походить від аналітичної філософії , галузі філософії, яка аналізує природні мовні конструкції, твердження та аргументи на основі методів логіки та математики. Іншими словами, це найближчий предмет поза інформатикою до того, що ми називаємо семантикою мови програмування . Філософ Віллард Куїн відповідав за ініціювання концепції референтної прозорості, але це також було неявним у підходах Бертран Рассела та Альфреда Уайтхеда.

По суті, «референтна прозорість» - це дуже проста і чітка ідея. Термін "референт" використовується в аналітичній філософії для розмови про те, на що йдеться у виразі . Це приблизно те саме, що ми маємо на увазі під сенсом або денотацією в семантиці мови програмування. Використовуючи приклад Ендрю Біркета ( повідомлення в блозі ), термін "столиця Шотландії" відноситься до міста Едінбург. Це прямий приклад "референта".

Контекст у реченні є "референтно прозорим", якщо заміна терміна в цьому контексті іншим терміном, що відноситься до тієї ж сутності , не змінює значення. Наприклад

Парламент Шотландії збирається в столиці Шотландії.

означає те саме, що

Парламент Шотландії засідає в Единбурзі.

Отже, контекст "Парламент Шотландії збирається у ..." є референтно прозорим контекстом. Ми можемо замінити "столицю Шотландії" на "Едінбург", не змінюючи значення. По-іншому, контекст піклується лише про те, на що йдеться, і нічого іншого. Саме в цьому сенсі контекст є "референтно прозорим".

З іншого боку, у реченні

Едінбург є столицею Шотландії з 1999 року.

ми не можемо зробити таку заміну. Якби ми це зробили, ми отримали б "Едінбург був Едінбургом з 1999 року", що є дурною річчю і не має такого ж значення, як оригінальне речення. Отже, здавалося б, що контекст "Едінбург був ... з 1999 року" є референтно непрозорим (протилежним до референційно прозорого). Це, мабуть, піклується про щось більше, ніж те, що стосується цього терміна. Що це?

Такі речі, як "столиця Шотландії", називаються певними термінами, і вони довго не давали болі в голові логікам і філософам. Рассел і Квійн розібрали їх, сказавши, що вони насправді не "референтні", тобто помилково вважати, що наведені вище приклади використовуються для позначення сутностей. Правильний спосіб зрозуміти, що "Едінбург є столицею Шотландії з 1999 року" - це сказати

У Шотландії є столиця з 1999 року, а столиця - Едінбург.

Це речення не можна перетворити на горіхове. Проблема вирішена! Суть Квіне полягала в тому, що природна мова є безладною або, принаймні, складною, оскільки вона робиться зручною для практичного використання, але філософи та логіки повинні внести ясність, розуміючи їх правильно. Референтна прозорість - це інструмент, який слід використовувати для досягнення такої чіткості сенсу .

Яке все це стосується програмування? Насправді не дуже. Як ми говорили, референтна прозорість - це інструмент, який слід використовувати в розумінні мови, тобто при призначенні значення . Крістофер Страчі , який заснував сферу семантики мови програмування, використав це у своєму дослідженні смислу. Його основоположний документ " Основні поняття в мовах програмування " доступний в Інтернеті. Це гарна папір, і кожен може її прочитати і зрозуміти. Отже, будь ласка, зробіть це. Ви будете сильно просвітлені. Він вводить у цьому параграфі термін "референтна прозорість":

Однією з найбільш корисних властивостей виразів є те, що викликається контрольною прозорістю Quine. По суті це означає, що якщо ми хочемо визначити значення виразу, що містить під-вираження, єдине, що нам потрібно знати про підвираз, - це його значення. Будь-які інші особливості підвиразу, такі як його внутрішня структура, кількість та характер його компонентів, порядок їх оцінювання або колір чорнила, яким вони написані, не мають значення для значення основної вираз.

Використання "по суті" говорить про те, що Страчі перефразовує це, щоб пояснити це простими словами. Функціональні програмісти, схоже, розуміють цей параграф по-своєму. У роботі є ще 9 випадків "референсної прозорості", але вони, схоже, не турбують жодного з інших. Насправді вся робота Страчі присвячена поясненню значення імперативних мов програмування . Але сьогодні функціональні програмісти стверджують, що імперативні мови програмування не є відносно прозорими. Страчі повернувся б у могилі.

Ми можемо врятувати ситуацію. Ми говорили, що мова природи "безладна, або, принаймні, складна", тому що вона робиться зручною для практичного використання. Мови програмування однакові. Вони "безладні, або принаймні складні", оскільки вони зроблені зручними для практичного використання. Це не означає, що вони повинні нас бентежити. Їх просто потрібно розуміти правильно, використовуючи мета-мову, яка є референтно прозорою, щоб ми мали чіткість сенсу. У роботі, яку я цитував, Страчі робить саме це. Він пояснює значення імперативних мов програмування, розбиваючи їх на елементарні поняття, ніколи не втрачаючи ясності. Важливою частиною його аналізу є вказівка ​​на те, що вирази в мовах програмування мають два види "значень",r-значення . Перед паперами Страчі це не зрозуміло, і плутанина панувала вищою. Сьогодні визначення C згадує це звичайно, і кожен програміст на C розуміє цю відмінність. (Чи однаково добре це розуміють програмісти на інших мовах, важко сказати.)

І Куін, і Страчі переймалися значенням мовних конструкцій, які передбачають певну форму залежності від контексту. Наприклад, наш приклад "Едінбург є столицею Шотландії з 1999 року" означає факт, що "столиця Шотландії" залежить від часу, в який вона розглядається. Така контекстна залежність є реальністю як для природних мов, так і для мов програмування. Навіть у функціональному програмуванні вільні та зв'язані змінні слід інтерпретувати відповідно до контексту, в якому вони опиняються. Контекстна залежність будь-якого виду блокує референтну прозорість так чи інакше. Якщо ви спробуєте зрозуміти значення термінів без огляду на контексти, від яких вони залежать, ви знову закінчитеся з замішанням. Квіне переймався значенням модальної логіки. Він тримав цемодальна логіка була референційно непрозорою, і її слід очистити, переклавши її у референтно прозорий каркас (наприклад, зважаючи на необхідність як доказовість). Він значною мірою програв цю дискусію. Логіки і філософи так само вважали можливу світову семантику Крипке абсолютно адекватною. Аналогічна ситуація склалася і з імперативним програмуванням. Залежність від держави, пояснювана Страчі, і залежність від магазинів, пояснювана Рейнольдсом (таким чином, як і можлива світова семантика Крипке), є цілком адекватними. Функціональні програмісти не знають багато з цього дослідження. Їх ідеї щодо референсної прозорості слід сприймати з великим зерном солі.

[Додаткова примітка: Наведені вище приклади ілюструють, що проста фраза, наприклад "столиця Шотландії", має багатозначне значення. На одному рівні ми можемо говорити про столицю в поточний час. На іншому рівні ми можемо говорити про всі можливі столиці, які Шотландія могла б мати з часом. Ми можемо "збільшити масштаб" конкретного контексту і "зменшити масштаб", щоб загальнодоступно охопити всі контексти в звичайній практиці. Ефективність природної мови використовує нашу здатність до цього. Імперативні мови програмування ефективні майже однаково. Ми можемо використовувати змінну x у правій частині призначення (значення r ), щоб поговорити про її значення в певному стані. Або ми можемо говорити про його l-значенняякий охоплює всі держави. Люди рідко плутаються у таких речах. Однак вони можуть або не можуть точно пояснити всі шари значення, притаманні мовним конструкціям. Усі такі шари значень не обов'язково є "очевидними", і наука належним чином їх вивчати. Однак незрозумілість простих людей пояснювати такі шаруваті смисли не означає, що вони їх плутають.]

Окремий "постскрипт" нижче стосується цієї дискусії з питаннями функціонального та імперативного програмування .


10
Дякую, але я не вважаю, що існує "очевидне" розширення поняття рівності. Коли я сказав, що "столиця Шотландії" відноситься до міста Едінбург, ти не думав про це двічі. Але коли я почав говорити про "з 1999 року", ви раптом зрозуміли, що є час. Отже, розширене поняття рівності може бути досить тонким і воно формалізується дослідниками мови програмування. Люди, які хочуть мати ідеальне розуміння рівності розширення, повинні вивчити плоди цього дослідження. Це може бути зовсім не очевидним.
Удай Редді

5
Фантастичний! Вітальне полегшення поширених помилок щодо RT, наприклад, прив’язування його до функцій . Або визначення шляхом заміни виразу на його значення (як у Вікіпедії) - як не дивно, оскільки вирази та значення - це різні речі. Можливо, одне місце, де люди помиляються, розглядаючи RT-ність імперативних мов, - це припускати, що ці "значення" - це прості речі, як числа, а не більш складні речі, як функції магазину.
Конал

13
@sclv Що стосується більш широкого впливу аналітичної філософії на інформатику, то слід сказати, що комп'ютерні науки, як ми це знаємо, були засновані Годель, Церквою, Кліном та Тьюрінгом. Ці люди були логіками, і вони добре знали як математичний, так і філософський аспекти логіки, зокрема традиції Пеано, Фреге, Рассела, Уайтхеда, Карнапа та Квіна. Перші піонери сучасної інформатики знали зв'язки. Але швидке зростання інформатики їх розірвало. Нам потрібно повернутися до них.
Удай Редді,

5
@sclv Логіка традиційно трактується як наука про наслідки . Але я думаю, що це ширше. Це наука про інформацію . Квіне, я вважаю першим, хто висунув ширший погляд. "Слово і об'єкт" - це аналіз інформаційного змісту висловлювань на природній мові. Однак ні філософи, ні математики ніколи не захоплювались обчисленнями , що викликає здивування, враховуючи те, як центральні обчислення були для цивілізації та науки споконвіку. Нам потрібно знайти способи зацікавити їх.
Удай Редді,

3
@Conal: Я додав нову відповідь, яка посилює вашу думку. Напевно, це буде внизу сторінки.
Удай Редді

134

Референтна прозорість, термін, який зазвичай використовується у функціональному програмуванні, означає, що задавши функцію та вхідне значення, ви завжди отримаєте однаковий вихід. Тобто немає жодного зовнішнього стану, який використовується у функції.

Ось приклад еталонної прозорої функції:

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

Завдяки прозорій прозорій функції, заданій входом та функцією, ви можете замінити її значенням, а не викликати функцію. Тож замість виклику плюсOne з параметром 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" не має того самого значення, як "плюсG 3", оскільки значення в імперативних мовах є функцією "магазину" (держави).
Конал

1
Я просто прочитав статтю про побічні ефекти та зміну стану і зрозумів, що це має щось спільне з RT. Чи можете ви додайте до нього примітку?
Гаурав

91

Референтно прозора функція - це функція, яка залежить лише від її вкладу.


4
Ось чому важко в програмуванні OO, оскільки об'єкти мають стан.
Крис

5
Тож чи правильно сказати, що "референційно прозорий" є ідентичним "детермінованим" при описі функцій? Якщо ні, то яка різниця між двома термінами?
mwolfe02

1
Це також звучить як визначення "чистої" функції.
Євген А.

75

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

Ідея функціональних програмістів про референтну прозорість, схоже, відрізняється від стандартного поняття трьома способами:

  • Тоді як філософи / логіки використовують такі терміни, як "посилання", "денотація", "позначення" та " бідеутунг " (німецький термін Фреге), функціональні програмісти використовують термін "значення". (Це не зовсім їхня справа. Я зауважую, що Ландін, Страчі та їхні нащадки також використовували термін "цінність", щоб поговорити про посилання / позначення. Це може бути просто термінологічне спрощення, яке запровадили Ландін і Страчі, але, здається, це зробити велика різниця при наївному використанні.)

  • Функціональні програмісти, здається, вважають, що ці "значення" існують всередині мови програмування, а не зовні. Роблячи це, вони відрізняються як від філософів, так і від семантиків мови програмування.

  • Вони, здається, вважають, що ці "цінності" повинні бути отримані шляхом оцінки.

Наприклад, стаття у Вікіпедії про референтну прозорість говорить сьогодні вранці:

Кажуть, що вираз є референтно прозорим, якщо його можна замінити його значенням, не змінюючи поведінку програми (іншими словами, отримуючи програму, яка має однакові ефекти та виводить на один і той же вхід).

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

Можна припустити, що семантики мови програмування могли ввести їх в оману. Але вони цього не зробили.

Ландін :

(a) кожне вираження має структуру вкладеного субэкспресії; (b) кожний підвираз позначає щось (як правило, число, значення істини або числову функцію) ; (c) річ, яку позначає вираз, тобто його "значення", залежить лише від значення його підвиразів, а не за іншими їх властивостями. [Додано наголос]

Проживання :

Єдине, що має значення щодо виразу, - це його значення, і будь-який підвираз може бути замінений будь-яким іншим рівним за значенням [Доданий наголос]. Більше того, значення виразу в певних межах є однаковим, коли воно відбувається ".

Птах і ватник :

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

Отже, з ретроспективою, зусилля Ландіна та Страчея щодо спрощення термінології шляхом заміни "посилання" / "позначення" на "значення" могли бути шкідливими. Як тільки хтось почує «цінність», виникає спокуса продумати процес оцінки, який веде до цього. Не менш спокусливо вважати те, що оцінювання виробляє як "значення", хоча може бути цілком зрозуміло, що це не позначення. Це те, що мені здається, трапилося з концепцією "референтної прозорості" в очах функціональних програмістів. Але "цінність", про яку говорили ранні семантики, не є результатом оцінки або результату функції чи будь-якого подібного. Це позначення терміна.

Як тільки ми розуміємо так звану "цінність" виразу ("посилання" чи "позначення" в дискурсі класичних філософів) як складний математичний / концептуальний об'єкт, відкриваються всілякі можливості.

  • Страчі інтерпретував змінні в імперативних мовах програмування як L-значення , про що говорилося у моїй відповіді від 25 березня, що є складним концептуальним об'єктом, що не має прямого представлення в синтаксисі мови програмування.
  • Він також інтерпретував команди такими мовами, як функції "держава-стан", інший екземпляр складного математичного об'єкта, який не є "значенням" у синтаксисі.
  • Навіть побічний виклик функції в C має чітко визначене "значення" як трансформатора стану, який відображає стани на пари станів і значень (так звана "монада" в термінології функціональних програмістів).

Небажання функціональних програмістів називати такі мови "референтно прозорими" лише означає, що вони неохоче визнають такі складні математичні / концептуальні об'єкти, як "значення". З іншого боку, вони виглядають абсолютно бажаючими називати трансформатор стану «значенням», коли він вкладається у власний улюблений синтаксис і одягається з кайфовим словом, як «монада». Я мушу сказати, що вони абсолютно непослідовні, навіть якщо ми їм це надаємо, що їхня ідея "референтної прозорості" має певну узгодженість.

Трохи історії можуть кинути трохи світла на те, як виникли ці плутанини. Період між 1962 і 1967 роками був дуже інтенсивним для Крістофера Страчі. У 1962-65 роках він взяв неповну роботу на посаді асистента з Морісом Вілкс, щоб розробити та впровадити мову програмування, яка стала відомою як CPL. Це була необхідна мова програмування, але повинна була мати потужні можливості функціональної мови програмування. Ландін, який був співробітником Strachey в його консультаційній компанії, мав величезний вплив на погляд Страчі на мови програмування. У знаковому документі 1965 року " Наступні 700 мов програмування " Лендін безперечно просуває функціональні мови програмування (називаючи їх денотативнимимови) та описує імперативні мови програмування як їх "антитезу". Під час дискусії, що випливає, ми виявляємо, що Страчі викликає сумніви у сильній позиції Ландіна.

... DL-файли утворюють підмножину всіх мов. Вони цікаві підмножини, але такі, які незручно використовувати, якщо ви до цього не звикли. Вони потрібні нам, оскільки на даний момент ми не знаємо, як побудувати докази з мов, які включають імперативи та стрибки. [Додано наголос]

У 1965 році Страчі зайняв посаду читача в Оксфорді і, здається, працював по суті повний робочий день над розробкою теорії імперативів і стрибків. До 1967 року він був готовий до теорії, яку викладав у своєму курсі " Основні поняття в мовах програмування " в копенгагенській літній школі. Записки до лекції повинні були бути опубліковані, але "на жаль, через редагування дилатації, судочинство так і не здійснилося; як і велика частина роботи Страчі в Оксфорді, однак газета мала впливовий приватний тираж". ( Мартін Кемпбелл-Келлі )

Труднощі отримання творів Страчі можуть призвести до поширення плутанини, коли люди покладаються на вторинні джерела та чують слова. Але тепер, коли « Фундаментальні поняття » легко доступні в Інтернеті, немає необхідності вдаватися до здогадки про роботу. Ми повинні прочитати його і скласти власну думку про те, що мав на увазі Страчі. Зокрема:

  • У розділі 3.2 він розглядає "вирази", де йдеться про "прозорість референс-значення".
  • У його розділі 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
Кріс: Удей зазначав, що Страчі усунув проблему референтної непрозорості в семантиці мови програмування, особливо для імперативних мов. Тож функціональні програмісти не можуть "набирати референтну прозорість у своїх програмах". В якості конкретного прикладу, Haskell IO - це не допомога з RT саме тому, що допомога RT не потрібна.
Конал

2
@chrisdornan: Вибачте за мій перший коментар вище. Мені самому було складно пояснити те, що я намагався сказати в перших двох реченнях :-( Але, ось пояснення. Розгляньте дворівневе чи багаторівневе вичислювальне числення. Кожен оператор постановки є непрозорим. Це насправді Оператор котирування. Однак ви можете зробити міркування з рівняннями на кожному етапі ідеально чудовими. Отже, кожен референтно-непрозорий оператор встановив межі для еквівалентних міркувань. Але ви все ще маєте рівняння в цих межах
Uday Reddy,

1
@chrisdomain: Більше того, дуже мало людей хотіли б бути референс-прозорими пуристами, щоб вигнати таких операторів інсценування. Ці оператори надзвичайно корисні. Програмування без них, виконуючи постановку вручну, було б втомливим, схильним до помилок і некрасивим. І, якщо робити постановку вручну, ви не придбаєте для вас більш раціональних міркувань, ніж те, що ви мали раніше. Отже, забороняти гарні пристрої програмування в пуристській гонитві за еквівалентними міркуваннями було б як відрізати ніс, щоб виплюнути обличчя.
Удай Редді

8

Якщо вас цікавить етимологія (тобто чому ця концепція має саме таку назву), подивіться у моєму дописі на цю тему. Термінологія походить від філософа / логіка Квіне.


4
  1. Денотаційно-семантика заснована на мовах моделювання шляхом побудови доменів, що складають позначаються значення .
  2. Функціональні програмісти використовують термін значення для опису конвергенції обчислень на основі правил перезапису мови, тобто. її оперативна семантика.

У 1 є чіткість двох розглянутих мов:

  • той, що моделюється, мова об'єкта
  • мова моделювання, мета мова

У 2, завдяки близькості об’єкта та метамов, їх можна переплутати.

Як мовний реалізатор, я вважаю, що мені потрібно постійно пам’ятати цю відмінність.

Тож проф. Редді, я можу вас перефразовувати таким чином :-)

У контекстах функціонального програмування та семантики термін " Референтна прозорість" не є референтно прозорим.


1
Ха-ха. Дякую за пояснення. Проблема також полягає в тому, що функціональні програмісти діють так, ніби вони мають загальне поняття "референтна прозорість", яке застосовується до всіх мов програмування . Але це залежить від їхнього поняття "цінності", яке може або не може мати сенсу для інших мов. Щоб стверджувати загальну теорію "референтної прозорості", їм потрібно виробити загальну теорію "значення". Цього поки що немає.
Удай Редді

4

Наступна відповідь, яку я сподіваюсь, доповнює і кваліфікує суперечливу першу та третю відповіді.

Дозвольмо, що вираз позначає або посилається на якогось референта. Однак питання полягає в тому, чи можна цих референтів кодувати ізоморфно як частину самих виразів, називаючи такі вирази "значеннями". Наприклад, значення буквальних чисел - це підмножина набору арифметичних виразів, значення істини - це підмножина набору булевих виразів і т. Д. Ідея полягає в оцінці виразу за його значенням (якщо воно має його). Отже, слово 'value' може позначати позначення або виділений елемент набору виразів. Але якщо між референтом і значенням існує ізоморфізм (біекція), ми можемо сказати, що вони однакові. (Сказане, треба бути обережним у визначенні референтів та ізоморфізму, як це доведено полем денотаційної семантики. Наводити приклад, згаданий у відповідях на 3-ю відповідь,data Nat = Zero | Suc Nat не відповідає, як очікувалося, набору натуральних чисел.)

Напишемо E[·]вираз із діркою, яка також відома в деяких кварталах як «контекст». Два приклади контексту для C-подібних виразів є [·]+1і [·]++.

Запишемо [[·]]для функції, яка приймає вираз (без дірки) і передає його значення (референт, позначення тощо) у деякому всесвітньому сенсі. (Я запозичую позначення з області денотаційної семантики.)

Давайте адаптуємо визначення Квіна дещо формально таким чином: контекст E[·] є референтно прозорим iff з урахуванням будь-яких двох виразів E1і E2(жодних дірок там) таким, що [[E1]] = [[E2]](тобто вирази позначають / посилаються на той самий референт), то це саме так [[E[E1]]] = [[E[E2]]](тобто заповнення -в отворі з або E1або E2призводить до виразів, які також позначають той самий референт).

Правило Лейбніца про заміну рівнянь на рівні дорівнює, як правило, виражається як "якби E1 = E2тоді E[E1] = E[E2]", що говорить, що E[·]це функція. Функція (або з цього приводу програма, що обчислює функцію) - це зіставлення від джерела до цілі, щоб було максимум один цільовий елемент для кожного вихідного елемента. Недетерміновані функції - це помилки, вони є або відношеннями, і функціями, що доставляють набори, і т. Д. Якщо в правилі Лейбніца рівність =є денотаційною, то подвійні дужки просто сприймаються як належне і відмічаються. Отже, референтно прозорий контекст є функцією. А правило Лейбніца є головним інгредієнтом еквівалентних міркувань, тому еквівалентне міркування, безумовно, пов'язане з еталонною прозорістю.

Хоча [[·]]це функція від виразів до позначень, вона може бути функцією від виразів до 'значень', що розуміються як обмежений підмножина виразів, і [[·]]їх можна розуміти як оцінку.

Тепер, якщо E1це вираження і E2є цінністю, ми маємо на увазі те, що, на мою думку, має на увазі більшість людей під час визначення референтної прозорості з точки зору виразів, значень та оцінки. Але як показано на 1-й та 3-й відповідях на цій сторінці, це неточне визначення.

Проблема з такими контекстами, як [·]++не побічний ефект, а в тому, що його значення не визначено в C ізоморфно його значенню. Функції не є значеннями (ну, покажчики на функції є), тоді як у мовах функціонального програмування вони є. Ландін, Страчі та піонери денотаційної семантики були досить розумні у використанні функціональних світів для надання сенсу.

Для імперативних С-подібних мов ми можемо (приблизно) надати семантику виразам за допомогою функції [[·]] : Expression -> (State -> State x Value).

Valueє підмножиною Expression. Stateмістить пари (ідентифікатор, значення). Семантична функція приймає вираз і передає як своє значення функцію від поточного стану до пари з оновленим станом і значенням. Наприклад, [[x]]це функція від поточного стану до пари, першим компонентом якої є поточний стан, а другий компонент - значення x. Навпаки, [[x++]]це функція від поточного стану до пари, першим компонентом якої є стан, у якому значення х збільшується, а другий компонент - саме це значення. У цьому сенсі контекст [·]++є референтно прозорим, якщо він відповідає визначеному вище визначенню.

Я думаю, що функціональні програмісти мають право використовувати референтну прозорість у тому сенсі, що вони, природно, відновлюються [[·]]як функція від виразів до значень. Функції - це першокласні значення, і стан також може бути значенням, а не позначенням. Державна монада - це частково чистий механізм передачі (або нанизування) штату.


Імовірно, відповіді "1-го" та "3-го" - це відповіді UdayReddy "25 березня" та "постскрипт" відповідно. Порядки не є хорошим способом посилатися на відповіді в ТА. Голоси та акцепти можуть не тільки змінюватися з часом, але й є кілька варіантів замовлень.
philipxy

2

Зауважимо, що це поняття «значення» - це те, що відбувається у свідомості спостерігача. Таким чином, одна і та ж «довідка» може означати різні речі для різних людей. Так, наприклад, у нас у Вікіпедії є сторінка Едінбургського розбору.

Пов'язаним питанням, яке може з'явитися в контексті програмування, може бути поліморфізм.

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


0

Я визнав визначення референтної прозорості у книзі " Структура та реалізація комп'ютерних програм " (Книга майстра) корисним, оскільки воно доповнюється поясненням того, як референтна прозорість порушується введенням операції призначення . Ознайомтесь із наступним слайдом, який я зробив з цього приводу: https://www.slideshare.net/pjschwarz/introducing-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.