Що означає термін референтна прозорість ? Я чув, як це описано як "це означає, що ви можете замінити рівняння на рівні", але це здається неадекватним поясненням.
Що означає термін референтна прозорість ? Я чув, як це описано як "це означає, що ви можете замінити рівняння на рівні", але це здається неадекватним поясненням.
Відповіді:
Термін "референтна прозорість" походить від аналітичної філософії , галузі філософії, яка аналізує природні мовні конструкції, твердження та аргументи на основі методів логіки та математики. Іншими словами, це найближчий предмет поза інформатикою до того, що ми називаємо семантикою мови програмування . Філософ Віллард Куїн відповідав за ініціювання концепції референтної прозорості, але це також було неявним у підходах Бертран Рассела та Альфреда Уайтхеда.
По суті, «референтна прозорість» - це дуже проста і чітка ідея. Термін "референт" використовується в аналітичній філософії для розмови про те, на що йдеться у виразі . Це приблизно те саме, що ми маємо на увазі під сенсом або денотацією в семантиці мови програмування. Використовуючи приклад Ендрю Біркета ( повідомлення в блозі ), термін "столиця Шотландії" відноситься до міста Едінбург. Це прямий приклад "референта".
Контекст у реченні є "референтно прозорим", якщо заміна терміна в цьому контексті іншим терміном, що відноситься до тієї ж сутності , не змінює значення. Наприклад
Парламент Шотландії збирається в столиці Шотландії.
означає те саме, що
Парламент Шотландії засідає в Единбурзі.
Отже, контекст "Парламент Шотландії збирається у ..." є референтно прозорим контекстом. Ми можемо замінити "столицю Шотландії" на "Едінбург", не змінюючи значення. По-іншому, контекст піклується лише про те, на що йдеться, і нічого іншого. Саме в цьому сенсі контекст є "референтно прозорим".
З іншого боку, у реченні
Едінбург є столицею Шотландії з 1999 року.
ми не можемо зробити таку заміну. Якби ми це зробили, ми отримали б "Едінбург був Едінбургом з 1999 року", що є дурною річчю і не має такого ж значення, як оригінальне речення. Отже, здавалося б, що контекст "Едінбург був ... з 1999 року" є референтно непрозорим (протилежним до референційно прозорого). Це, мабуть, піклується про щось більше, ніж те, що стосується цього терміна. Що це?
Такі речі, як "столиця Шотландії", називаються певними термінами, і вони довго не давали болі в голові логікам і філософам. Рассел і Квійн розібрали їх, сказавши, що вони насправді не "референтні", тобто помилково вважати, що наведені вище приклади використовуються для позначення сутностей. Правильний спосіб зрозуміти, що "Едінбург є столицею Шотландії з 1999 року" - це сказати
У Шотландії є столиця з 1999 року, а столиця - Едінбург.
Це речення не можна перетворити на горіхове. Проблема вирішена! Суть Квіне полягала в тому, що природна мова є безладною або, принаймні, складною, оскільки вона робиться зручною для практичного використання, але філософи та логіки повинні внести ясність, розуміючи їх правильно. Референтна прозорість - це інструмент, який слід використовувати для досягнення такої чіткості сенсу .
Яке все це стосується програмування? Насправді не дуже. Як ми говорили, референтна прозорість - це інструмент, який слід використовувати в розумінні мови, тобто при призначенні значення . Крістофер Страчі , який заснував сферу семантики мови програмування, використав це у своєму дослідженні смислу. Його основоположний документ " Основні поняття в мовах програмування " доступний в Інтернеті. Це гарна папір, і кожен може її прочитати і зрозуміти. Отже, будь ласка, зробіть це. Ви будете сильно просвітлені. Він вводить у цьому параграфі термін "референтна прозорість":
Однією з найбільш корисних властивостей виразів є те, що викликається контрольною прозорістю Quine. По суті це означає, що якщо ми хочемо визначити значення виразу, що містить під-вираження, єдине, що нам потрібно знати про підвираз, - це його значення. Будь-які інші особливості підвиразу, такі як його внутрішня структура, кількість та характер його компонентів, порядок їх оцінювання або колір чорнила, яким вони написані, не мають значення для значення основної вираз.
Використання "по суті" говорить про те, що Страчі перефразовує це, щоб пояснити це простими словами. Функціональні програмісти, схоже, розуміють цей параграф по-своєму. У роботі є ще 9 випадків "референсної прозорості", але вони, схоже, не турбують жодного з інших. Насправді вся робота Страчі присвячена поясненню значення імперативних мов програмування . Але сьогодні функціональні програмісти стверджують, що імперативні мови програмування не є відносно прозорими. Страчі повернувся б у могилі.
Ми можемо врятувати ситуацію. Ми говорили, що мова природи "безладна, або, принаймні, складна", тому що вона робиться зручною для практичного використання. Мови програмування однакові. Вони "безладні, або принаймні складні", оскільки вони зроблені зручними для практичного використання. Це не означає, що вони повинні нас бентежити. Їх просто потрібно розуміти правильно, використовуючи мета-мову, яка є референтно прозорою, щоб ми мали чіткість сенсу. У роботі, яку я цитував, Страчі робить саме це. Він пояснює значення імперативних мов програмування, розбиваючи їх на елементарні поняття, ніколи не втрачаючи ясності. Важливою частиною його аналізу є вказівка на те, що вирази в мовах програмування мають два види "значень",r-значення . Перед паперами Страчі це не зрозуміло, і плутанина панувала вищою. Сьогодні визначення C згадує це звичайно, і кожен програміст на C розуміє цю відмінність. (Чи однаково добре це розуміють програмісти на інших мовах, важко сказати.)
І Куін, і Страчі переймалися значенням мовних конструкцій, які передбачають певну форму залежності від контексту. Наприклад, наш приклад "Едінбург є столицею Шотландії з 1999 року" означає факт, що "столиця Шотландії" залежить від часу, в який вона розглядається. Така контекстна залежність є реальністю як для природних мов, так і для мов програмування. Навіть у функціональному програмуванні вільні та зв'язані змінні слід інтерпретувати відповідно до контексту, в якому вони опиняються. Контекстна залежність будь-якого виду блокує референтну прозорість так чи інакше. Якщо ви спробуєте зрозуміти значення термінів без огляду на контексти, від яких вони залежать, ви знову закінчитеся з замішанням. Квіне переймався значенням модальної логіки. Він тримав цемодальна логіка була референційно непрозорою, і її слід очистити, переклавши її у референтно прозорий каркас (наприклад, зважаючи на необхідність як доказовість). Він значною мірою програв цю дискусію. Логіки і філософи так само вважали можливу світову семантику Крипке абсолютно адекватною. Аналогічна ситуація склалася і з імперативним програмуванням. Залежність від держави, пояснювана Страчі, і залежність від магазинів, пояснювана Рейнольдсом (таким чином, як і можлива світова семантика Крипке), є цілком адекватними. Функціональні програмісти не знають багато з цього дослідження. Їх ідеї щодо референсної прозорості слід сприймати з великим зерном солі.
[Додаткова примітка: Наведені вище приклади ілюструють, що проста фраза, наприклад "столиця Шотландії", має багатозначне значення. На одному рівні ми можемо говорити про столицю в поточний час. На іншому рівні ми можемо говорити про всі можливі столиці, які Шотландія могла б мати з часом. Ми можемо "збільшити масштаб" конкретного контексту і "зменшити масштаб", щоб загальнодоступно охопити всі контексти в звичайній практиці. Ефективність природної мови використовує нашу здатність до цього. Імперативні мови програмування ефективні майже однаково. Ми можемо використовувати змінну x у правій частині призначення (значення r ), щоб поговорити про її значення в певному стані. Або ми можемо говорити про його l-значенняякий охоплює всі держави. Люди рідко плутаються у таких речах. Однак вони можуть або не можуть точно пояснити всі шари значення, притаманні мовним конструкціям. Усі такі шари значень не обов'язково є "очевидними", і наука належним чином їх вивчати. Однак незрозумілість простих людей пояснювати такі шаруваті смисли не означає, що вони їх плутають.]
Окремий "постскрипт" нижче стосується цієї дискусії з питаннями функціонального та імперативного програмування .
Референтна прозорість, термін, який зазвичай використовується у функціональному програмуванні, означає, що задавши функцію та вхідне значення, ви завжди отримаєте однаковий вихід. Тобто немає жодного зовнішнього стану, який використовується у функції.
Ось приклад еталонної прозорої функції:
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;
}
Іншим прикладом є функція-член в об'єктно-орієнтованій мові програмування. Функції члена зазвичай функціонують на змінних своїх членів, і тому вони були б непрозорими. Функції членів, хоча, звичайно, можуть бути референтно прозорими.
Ще один приклад - це функція, яка читає з текстового файлу та друкує вихід. Цей зовнішній текстовий файл може змінюватися в будь-який час, тому функція буде референтно непрозорою.
Референтно прозора функція - це функція, яка залежить лише від її вкладу.
[Це постскрипт на мою відповідь від 25 березня, намагаючись наблизити дискусію до проблем функціонального / імперативного програмування.]
Ідея функціональних програмістів про референтну прозорість, схоже, відрізняється від стандартного поняття трьома способами:
Тоді як філософи / логіки використовують такі терміни, як "посилання", "денотація", "позначення" та " бідеутунг " (німецький термін Фреге), функціональні програмісти використовують термін "значення". (Це не зовсім їхня справа. Я зауважую, що Ландін, Страчі та їхні нащадки також використовували термін "цінність", щоб поговорити про посилання / позначення. Це може бути просто термінологічне спрощення, яке запровадили Ландін і Страчі, але, здається, це зробити велика різниця при наївному використанні.)
Функціональні програмісти, здається, вважають, що ці "значення" існують всередині мови програмування, а не зовні. Роблячи це, вони відрізняються як від філософів, так і від семантиків мови програмування.
Вони, здається, вважають, що ці "цінності" повинні бути отримані шляхом оцінки.
Наприклад, стаття у Вікіпедії про референтну прозорість говорить сьогодні вранці:
Кажуть, що вираз є референтно прозорим, якщо його можна замінити його значенням, не змінюючи поведінку програми (іншими словами, отримуючи програму, яка має однакові ефекти та виводить на один і той же вхід).
Це абсолютно не відповідає тому, що кажуть філософи / логіки. Вони кажуть, що контекст є референтним або референтно прозорим, якщо вираз у цьому контексті можна замінити іншим виразом, що стосується тієї ж речі ( основний вираз). Хто ці філософи / логіки? До них належать Фреге , Рассел , Уайтхед , Карнап , Квін , Церкваі незліченна кількість інших. Кожен з них - це вища фігура. Поєднана інтелектуальна сила цих логіків, щонайменше, руйнує землю. Усі вони одностайні у позиції, що референти / позначення існують поза формальною мовою, а вирази всередині мови можуть говорити лише про них. Отже, все, що можна зробити в межах мови, - це замінити один вираз іншим виразом, що відноситься до тієї ж сутності. Самі референти / позначення не існують в межах мови. Чому функціональні програмісти відхиляються від цієї усталеної традиції?
Можна припустити, що семантики мови програмування могли ввести їх в оману. Але вони цього не зробили.
Ландін :
(a) кожне вираження має структуру вкладеного субэкспресії; (b) кожний підвираз позначає щось (як правило, число, значення істини або числову функцію) ; (c) річ, яку позначає вираз, тобто його "значення", залежить лише від значення його підвиразів, а не за іншими їх властивостями. [Додано наголос]
Єдине, що має значення щодо виразу, - це його значення, і будь-який підвираз може бути замінений будь-яким іншим рівним за значенням [Доданий наголос]. Більше того, значення виразу в певних межах є однаковим, коли воно відбувається ".
значення виразу залежить лише від значень складових виразів (якщо такі є), і ці підвираження можуть вільно замінюватися іншими, що мають те саме значення [Доданий наголос].
Отже, з ретроспективою, зусилля Ландіна та Страчея щодо спрощення термінології шляхом заміни "посилання" / "позначення" на "значення" могли бути шкідливими. Як тільки хтось почує «цінність», виникає спокуса продумати процес оцінки, який веде до цього. Не менш спокусливо вважати те, що оцінювання виробляє як "значення", хоча може бути цілком зрозуміло, що це не позначення. Це те, що мені здається, трапилося з концепцією "референтної прозорості" в очах функціональних програмістів. Але "цінність", про яку говорили ранні семантики, не є результатом оцінки або результату функції чи будь-якого подібного. Це позначення терміна.
Як тільки ми розуміємо так звану "цінність" виразу ("посилання" чи "позначення" в дискурсі класичних філософів) як складний математичний / концептуальний об'єкт, відкриваються всілякі можливості.
Небажання функціональних програмістів називати такі мови "референтно прозорими" лише означає, що вони неохоче визнають такі складні математичні / концептуальні об'єкти, як "значення". З іншого боку, вони виглядають абсолютно бажаючими називати трансформатор стану «значенням», коли він вкладається у власний улюблений синтаксис і одягається з кайфовим словом, як «монада». Я мушу сказати, що вони абсолютно непослідовні, навіть якщо ми їм це надаємо, що їхня ідея "референтної прозорості" має певну узгодженість.
Трохи історії можуть кинути трохи світла на те, як виникли ці плутанини. Період між 1962 і 1967 роками був дуже інтенсивним для Крістофера Страчі. У 1962-65 роках він взяв неповну роботу на посаді асистента з Морісом Вілкс, щоб розробити та впровадити мову програмування, яка стала відомою як CPL. Це була необхідна мова програмування, але повинна була мати потужні можливості функціональної мови програмування. Ландін, який був співробітником Strachey в його консультаційній компанії, мав величезний вплив на погляд Страчі на мови програмування. У знаковому документі 1965 року " Наступні 700 мов програмування " Лендін безперечно просуває функціональні мови програмування (називаючи їх денотативнимимови) та описує імперативні мови програмування як їх "антитезу". Під час дискусії, що випливає, ми виявляємо, що Страчі викликає сумніви у сильній позиції Ландіна.
... DL-файли утворюють підмножину всіх мов. Вони цікаві підмножини, але такі, які незручно використовувати, якщо ви до цього не звикли. Вони потрібні нам, оскільки на даний момент ми не знаємо, як побудувати докази з мов, які включають імперативи та стрибки. [Додано наголос]
У 1965 році Страчі зайняв посаду читача в Оксфорді і, здається, працював по суті повний робочий день над розробкою теорії імперативів і стрибків. До 1967 року він був готовий до теорії, яку викладав у своєму курсі " Основні поняття в мовах програмування " в копенгагенській літній школі. Записки до лекції повинні були бути опубліковані, але "на жаль, через редагування дилатації, судочинство так і не здійснилося; як і велика частина роботи Страчі в Оксфорді, однак газета мала впливовий приватний тираж". ( Мартін Кемпбелл-Келлі )
Труднощі отримання творів Страчі можуть призвести до поширення плутанини, коли люди покладаються на вторинні джерела та чують слова. Але тепер, коли « Фундаментальні поняття » легко доступні в Інтернеті, немає необхідності вдаватися до здогадки про роботу. Ми повинні прочитати його і скласти власну думку про те, що мав на увазі Страчі. Зокрема:
Будь-які розмови про "референтну прозорість" без розуміння різниці між L-значеннями, R-значеннями та іншими складними об'єктами, які заповнюють концептуальну світобудову імперативного програміста, принципово помиляються.
Референтно прозора функція - це функція, подібна до математичної функції; з однаковими входами, він завжди буде виробляти однакові виходи. Це означає, що стан, що передається, не модифікується, і що функція не має власного стану.
Для тих, хто потребує стислого пояснення, я ризикую (але прочитайте його нижче).
Референсна прозорість в мові програмування сприяє екваціональному міркуванню - чим більше референтна прозорість, тим легше робити екваціональне міркування. Наприклад, з визначенням (псевдо) функції,
fx = x + x,
простота, з якою ви можете (безпечно) замінити f (foo) на foo + foo в рамках цього визначення, не маючи занадто багато обмежень щодо того, де можна виконати це зменшення, є хорошим показником того, наскільки референтна прозорість вашої мови програмування має.
Наприклад, якщо foo був x ++ у сенсі програмування на C, тоді ви не могли б виконати це зменшення безпечно (тобто, якщо ви виконували б це зменшення, ви не отримали б ту ж програму, з якою ви почали).
У практичних мовах програмування ви не побачите ідеальної прозорості, але функціональні програмісти дбають про це більше, ніж більшість (див. Haskell, де це головна мета).
(Повне розкриття інформації: я функціональний програміст, тому, на початку відповіді, ви повинні сприймати це пояснення із зерном солі.)
Якщо вас цікавить етимологія (тобто чому ця концепція має саме таку назву), подивіться у моєму дописі на цю тему. Термінологія походить від філософа / логіка Квіне.
У 1 є чіткість двох розглянутих мов:
У 2, завдяки близькості об’єкта та метамов, їх можна переплутати.
Як мовний реалізатор, я вважаю, що мені потрібно постійно пам’ятати цю відмінність.
Тож проф. Редді, я можу вас перефразовувати таким чином :-)
У контекстах функціонального програмування та семантики термін " Референтна прозорість" не є референтно прозорим.
Наступна відповідь, яку я сподіваюсь, доповнює і кваліфікує суперечливу першу та третю відповіді.
Дозвольмо, що вираз позначає або посилається на якогось референта. Однак питання полягає в тому, чи можна цих референтів кодувати ізоморфно як частину самих виразів, називаючи такі вирази "значеннями". Наприклад, значення буквальних чисел - це підмножина набору арифметичних виразів, значення істини - це підмножина набору булевих виразів і т. Д. Ідея полягає в оцінці виразу за його значенням (якщо воно має його). Отже, слово '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 - яке може бути представлене з використанням цілого типу, або складного типу, або будь-якого з безлічі інших типів - можна лікувати поліморфно).
Я визнав визначення референтної прозорості у книзі " Структура та реалізація комп'ютерних програм " (Книга майстра) корисним, оскільки воно доповнюється поясненням того, як референтна прозорість порушується введенням операції призначення . Ознайомтесь із наступним слайдом, який я зробив з цього приводу: https://www.slideshare.net/pjschwarz/introducing-assignment-invalidates-the-substitution-model-of-evaluation-and-violates-referential-transparency-as- пояснила-в-sicp-чарівнику-книгу
Прозорість посилань може бути проставлена як:
Наприклад, мова програмування Haskell є чистою функціональною мовою; це означає, що він референтно прозорий.