Czym jest przejrzystość referencyjna?

Co oznacza termin przejrzystość odniesienia? Słyszałem, że to opisane jako "oznacza, że można zastąpić równych z równymi", ale to wydaje się niewystarczające Wyjaśnienie.

Author: Brian R. Bondy, 2008-10-17

12 answers

Termin "przejrzystość referencjalna" pochodzi od filozofii analitycznej , gałęzi filozofii, która analizuje konstrukcje języka naturalnego, twierdzenia i argumenty oparte na metodach logiki i matematyki. Innymi słowy, jest to najbliższy przedmiot poza informatyką do tego, co nazywamy semantyką języka programowania . Filozof Willard Quine był odpowiedzialny za zapoczątkowanie pojęcia przejrzystości referencjalnej, ale było to również ukryte w podejście Bertranda Russella i Alfreda Whiteheada.

W swej istocie "przejrzystość odniesienia" jest bardzo prostą i jasną ideą. Termin "referent" jest używany w filozofii analitycznej do mówienia o rzeczy, do której odnosi się wyrażenie. Jest to mniej więcej to samo co to, co rozumiemy przez" Znaczenie "lub" denotację " w semantyce języka programowania. Na przykładzie Andrew Birketta (blog post) termin "stolica Szkocji" odnosi się do miasta Edynburg. To jest prosty przykład "referenta".

Kontekst w zdaniu jest "referencyjnie przejrzysty", jeśli zastąpienie terminu w tym kontekście innym terminem, który odnosi się do tego samego podmiotu nie zmienia znaczenia. Na przykład

Szkocki Parlament zbiera się w stolicy Szkocji.

Oznacza to samo co

Szkocki Parlament zbiera się w Edynburgu.

Tak więc kontekst " spotyka się Szkocki Parlament ..."is a przejrzysty kontekst odniesienia. Możemy zastąpić słowo " stolica Szkocji "słowem " Edynburg"bez zmiany znaczenia. Innymi słowy, kontekst dba tylko o to, do czego odnosi się termin i nic więcej. To jest sens, w którym kontekst jest " referencyjnie przejrzysty."

Natomiast w zdaniu

Edynburg jest stolicą Szkocji od 1999 roku.

Nie możemy zrobić takiego zastępstwa. Gdyby tak było, dostalibyśmy " Edynburg jest od 1999 roku", co jest szaloną rzeczą do powiedzenia i nie przekazuje tego samego znaczenia co pierwotne zdanie. Wydaje się więc, że kontekst " Edynburga był ... od 1999 roku " jest referencjalnie nieprzezroczyste (przeciwieństwo referencjalnie przejrzyste). Najwyraźniej dba o coś więcej niż to, do czego odnosi się ten termin. O co chodzi?

Rzeczy takie jak "stolica Szkocji" nazywane są definitywnymi terminami i nie dawały chudego bólu głowy logików i filozofów od dawna. Russell i Quine posortowali je mówiąc, że nie są one w rzeczywistości "referencjalne", tj. błędem jest myślenie, że powyższe przykłady są używane do odniesienia się do Bytów. Właściwy sposób, aby zrozumieć "Edynburg jest stolicą Szkocji od 1999 roku", to powiedzieć

[[0]}Szkocja posiada stolicę od 1999 roku, a stolicą jest Edynburg.

Tego zdania nie da się przekształcić w wariackie. Problem rozwiązany! The point of Quine miał powiedzieć, że język naturalny jest niechlujny, a przynajmniej skomplikowany, ponieważ jest wygodny w praktycznym użyciu, ale filozofowie i logicy powinni przynieść jasność, rozumiejąc je we właściwy sposób. Przejrzystość referencyjna jest narzędziem służącym do zapewnienia takiej jasności znaczenia .

Co to wszystko ma wspólnego z programowaniem? Właściwie to niewiele. Jak już powiedzieliśmy, przejrzystość referencyjna jest narzędziem, które można wykorzystać w zrozumieniu języka, tj. w przypisanie znaczenia . Christopher Strachey, który założył dziedzinę semantyki języka programowania, wykorzystał ją w swoich badaniach nad znaczeniem. Jego fundamentalna praca "Fundamental concepts in programming languages" jest dostępna w Internecie. Jest to piękny papier i każdy może go przeczytać i zrozumieć. Więc, proszę, zrób to. Będziecie o wiele oświeceni. Wprowadza termin "przejrzystość odniesienia" w tym ustępie:

Jeden z najbardziej przydatnych właściwościami wyrażeń jest to, że wywołane przez Quine referential przejrzystość. W istocie oznacza to, że jeśli chcemy znaleźć wartość wyrażenia, które zawiera sub-wyrażenie, jedyne co musimy wiedzieć o sub-wyrażeniu to jego wartość. Wszelkie inne cechy podrozdziału, takie jak jego struktura wewnętrzna, liczba i charakter jego składników, kolejność ich oceny lub kolor tuszu w którym są zapisane, są nieistotne dla wartości główne wyrażenie.

Użycie "w istocie" sugeruje, że Strachey parafrazuje to, aby wyjaśnić to w prostych słowach. Programiści funkcjonalni zdają się rozumieć ten akapit na swój sposób. W artykule jest 9 innych przypadków" referencyjnej przejrzystości", ale nie wydają się przejmować żadną z pozostałych. W rzeczywistości cała praca Strachey ' a poświęcona jest wyjaśnieniu znaczenia imperatywnych języków programowania . Ale dziś funkcjonalne programiści twierdzą, że imperatywne języki programowania sąa nie referencjalnie przejrzyste. Strachey przewraca się w grobie.

Możemy uratować sytuację. Powiedzieliśmy, że język naturalny jest "niechlujny, a przynajmniej skomplikowany", ponieważ jest wygodny w praktycznym użyciu. Języki programowania są takie same. Są one "niechlujne, a przynajmniej skomplikowane", ponieważ są wygodne w praktycznym użyciu. To nie znaczy, że muszą nas zdezorientować. Po prostu muszą być rozumiane we właściwy sposób, używając meta-języka, który jest referencyjnie przejrzysty, abyśmy mieli jasność znaczenia. W artykule, który cytowałem, Strachey robi dokładnie to. Wyjaśnia znaczenie imperatywnych języków programowania, dzieląc je na elementarne pojęcia, nigdy nie tracąc nigdzie jasności. Ważną częścią jego analizy jest zwrócenie uwagi, że wyrażenia w językach programowania mają dwa rodzaje "wartości", zwanych l-wartości i R-wartości . Przed przekazem Stracheya nie było to zrozumiałe i zamęt panował nade wszystko. Obecnie definicja C wspomina o niej rutynowo i każdy programista C rozumie to rozróżnienie. (Trudno powiedzieć, czy programiści w innych językach rozumieją to równie dobrze.)

Zarówno Quine, jak i Strachey zajmowali się znaczeniem konstrukcji językowych, które wiążą się z pewną formą zależności kontekstowej. Na przykład, nasz przykład "Edynburg był stolicą Scotland since 1999 "oznacza, że" stolica Szkocji " zależy od czasu, w którym jest rozważana. Taka zależność kontekstowa jest rzeczywistością, zarówno w językach naturalnych, jak i w językach programowania. Nawet w programowaniu funkcyjnym Zmienne wolne i związane należy interpretować w odniesieniu do kontekstu, w którym się pojawiają. Zależności kontekstowe dowolnego rodzaju blokują przezroczystość odniesienia w jakiś czy inny sposób. Jeśli próbujesz zrozumieć znaczenie pojęć bez względu na w kontekstach, od których zależą, znowu skończyłbyś z zamieszaniem. Quine zajmował się znaczeniem logiki modalnej. Uważał, że[77]}logika modalna jest nieprzezroczysta i powinna zostać oczyszczona przez przełożenie jej na przejrzystą strukturę (np. przez uznanie konieczności za wiarygodność). W dużej mierze przegrał tę debatę. Logicy i filozofowie uznali możliwą semantykę świata Kripkego za całkowicie adekwatną. Podobna sytuacja panuje również z programowanie imperatywne. Zależność od państwa wyjaśniona przez Stracheya i zależność od sklepu wyjaśniona przez Reynoldsa (w sposób podobny do możliwej semantyki świata Kripke' a) są doskonale odpowiednie. Programiści funkcjonalni niewiele wiedzą o tych badaniach. Ich idee dotyczące przejrzystości odniesienia należy traktować z dużą dozą soli.

[dodatkowa uwaga: powyższe przykłady ilustrują, że proste wyrażenie, takie jak" stolica Szkocji", ma wiele poziomów znaczenia. Na jednym poziomie możemy mów o stolicy w obecnym czasie. Na innym poziomie możemy mówić o wszystkich możliwych stolicach, które Szkocja mogła mieć z biegiem czasu. Możemy "przybliżyć" konkretny kontekst i "pomniejszyć", aby objąć wszystkie konteksty dość łatwo w normalnej praktyce. Efektywność języka naturalnego wykorzystuje naszą zdolność do tego. Imperatywne języki programowania są wydajne w bardzo podobny sposób. Możemy użyć zmiennej x po prawej stronie assignment (the R-value ) to talk about its value in a specific state. Lub możemy mówić o jego l-wartość , która obejmuje wszystkie stany. Ludzie rzadko są zdezorientowani takimi rzeczami. Mogą jednak, ale nie muszą, być w stanie dokładnie wyjaśnić wszystkie warstwy znaczeniowe związane z konstrukcjami językowymi. Wszystkie takie warstwy znaczeniowe niekoniecznie są "oczywiste" i właściwe ich zbadanie jest kwestią nauki. Jednak nieartykułowanie zwykłych ludzi do wyjaśniania takich warstw znaczenia nie oznaczają, że są one zdezorientowane co do nich.]

osobny "postscript" poniżej odnosi tę dyskusję do zagadnień programowania funkcyjnego i imperatywnego .

 313
Author: Uday Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-13 09:11:09

Referential transparency, termin powszechnie używany w programowaniu funkcyjnym, oznacza, że biorąc pod uwagę funkcję i wartość wejściową, zawsze otrzymasz to samo wyjście. Oznacza to, że nie ma zewnętrznego stanu używanego w funkcji.

Oto przykład referencjalnej funkcji transparentnej:

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

Z referencjalną funkcją transparentną, biorąc pod uwagę wejście i funkcję, można zastąpić ją wartością zamiast wywoływać funkcję. Więc zamiast wywoływać plusOne z parametr 5, możemy zastąpić go 6.

Innym dobrym przykładem jest matematyka w ogóle. W matematyce, biorąc pod uwagę funkcję i wartość wejściową, zawsze będzie mapować do tej samej wartości wyjściowej. f (x) = x + 1. Dlatego funkcje w matematyce są referencjalnie przejrzyste.

Ta koncepcja jest ważna dla badaczy, ponieważ oznacza, że gdy masz referencyjnie przejrzystą funkcję, nadaje się do łatwej automatycznej równoległości i buforowania.

Referencjalna przezroczystość jest używana zawsze w językach funkcyjnych, takich jak Haskell.

--

Istnieje natomiast pojęcie nieprzezroczystości referencjalnej. Oznacza to coś przeciwnego. Wywołanie funkcji nie zawsze może wygenerować to samo wyjście.

//global G
int G = 10;

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

Innym przykładem jest funkcja member w obiektowym języku programowania. Funkcje prętowe Zwykle operują na zmiennych prętowych i dlatego są nieprzezroczyste. Funkcje członka, choć może kurs powinien być przejrzysty.

Kolejnym przykładem jest funkcja, która odczytuje dane z pliku tekstowego i drukuje dane wyjściowe. Ten zewnętrzny plik tekstowy może ulec zmianie w dowolnym momencie, więc funkcja będzie nieprzezroczysta.

 119
Author: Brian R. Bondy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-27 04:23:02

Funkcja referencyjnie przezroczysta to taka, która zależy tylko od jej wejścia.

 82
Author: Draemon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 02:22:07

[jest to postscript do mojej odpowiedzi z 25 marca, w celu przybliżenia dyskusji do zagadnień programowania funkcyjnego / imperatywnego.]

Koncepcja funkcjonalnej przezroczystości programistów wydaje się różnić od standardowego pojęcia na trzy sposoby:

  • Podczas gdy filozofowie / logicy używają terminów takich jak" reference"," denotation"," designatum "i" bedeutung "(Niemiecki termin Frege), Programiści funkcjonalni używają terminu"value". (To to nie do końca ich sprawka. Zauważyłem, że Landin, Strachey i ich potomkowie również używali terminu "wartość", aby mówić o referencji/denotacji. Może to tylko terminologiczne uproszczenie, które wprowadzili Landin i Strachey, ale wydaje się, że robi dużą różnicę, gdy jest używany w naiwny sposób.)

  • Programiści funkcjonalni zdają się wierzyć, że te "wartości" istnieją wewnątrz języka programowania, a nie na zewnątrz. Tym się różnią zarówno od filozofów, jak i od semantycy języka programowania.

  • Zdają się wierzyć, że te "wartości" powinny być uzyskane przez ocenę.

Na przykład artykuł Wikipedii na temat referential transparency mówi dziś rano:

Mówi się, że wyrażenie jest referencyjnie przejrzyste, jeśli można je zastąpić jego wartością bez zmiany zachowania programu (innymi słowy, dając program, który ma takie same efekty i wyjście na tym samym input).

Jest to całkowicie sprzeczne z tym, co mówią filozofowie/logicy. Mówi się, że kontekst jest referencjalny lub referencjalnie przejrzysty, jeśli wyrażenie w tym kontekście może zostać zastąpione innym wyrażeniem , które odnosi się do tej samej rzeczy (wyrażenie coreferential). Kim są ci filozofowie / logicy? Należą do nich Frege, Russell, Whitehead, Carnap, Quine, Kościół i niezliczonych innych. Każdy z nich jest potężną postacią. Połączona Siła intelektualna tych logików jest co najmniej wstrząsająca. Wszystkie z nich są jednomyślne w stanowisku, że odniesienia/denotacje istnieją poza językiem formalnym, a wyrażenia w języku mogą mówić tylko o o. Tak więc, wszystko, co można zrobić w języku, to zastąpić jedno wyrażenie innym wyrażeniem, które odnosi się do tej samej jednostki. Same referenty /denotacje do nie istnieją w obrębie języka. Dlaczego programiści funkcjonalni odbiegają od tej ugruntowanej tradycji?

Można by przypuszczać, że semantycy języka programowania mogli ich wprowadzić w błąd. Ale nie zrobili tego.

Landin :

(a) każde wyrażenie ma zagnieżdżanie struktury podekspresji, (B) każda podekspresja oznacza coś (zwykle liczbę, wartość prawdy lub funkcja numeryczna) , (c) rzecz, którą wyrażenie oznacza, tj., jego "wartość", zależy tylko od wartości jego sub- wyrażeń, a nie na innych ich właściwościach. [Dodano]

Stoy :

Jedyną rzeczą, która ma znaczenie w wyrażeniu, jest jego wartość, a każde podwyrażenie może być zastąpiony przez dowolny inny równy w wartości [dodano podkreślenie]. Co więcej, wartość wyrażenia jest, w pewnych granicach, zawsze taka sama".

Bird and Wadler :

The wartość wyrażenia zależy tylko od wartości jego składowej wyrażenia (jeśli istnieją) i te podwyrażenia mogą być dowolnie zastępowane przez inne posiadanie tej samej wartości [dodano podkreślenie].

Zatem, patrząc wstecz, wysiłki Landina i Strachey ' a zmierzające do uproszczenia terminologii poprzez zastąpienie "odniesienia"/"denotacji" "wartością" mogły być niegodziwe. Jak tylko ktoś słyszy o "wartości", istnieje pokusa, aby myśleć o procesie oceny, który prowadzi do to. Równie kuszące jest myślenie o tym, co daje ocena, jako o "wartości", chociaż może być całkiem jasne, że nie jest to denotacja. To właśnie, jak się domyślam, stało się z pojęciem "referencjalnej przejrzystości" w oczach programistów funkcjonalnych. Ale "wartość", o której mówili wczesni semantycy, jest , a nie wynikiem oceny lub wyniku funkcji lub czegoś takiego. Jest to denotacja tego terminu.

Once we rozumiejąc tak zwaną "wartość" wyrażenia ("odniesienie "lub" denotacja " w dyskursie klasycznych filozofów) jako złożony obiekt matematyczno-pojęciowy, otwierają się wszelkiego rodzaju możliwości.

  • Strachey interpretował zmienne w imperatywnych językach programowania jako l-wartości , Jak wspomniano w mojej odpowiedzi z 25 Marca, która jest wyrafinowanym obiektem pojęciowym, który nie ma bezpośredniej reprezentacji w składni języka programowania.
  • On interpretowane polecenia w takich językach jak state-to-state functions, kolejna instancja złożonego obiektu matematycznego, który nie jest "wartością" w składni.
  • nawet wywołanie funkcji pobocznej w C ma dobrze zdefiniowaną" wartość "jako transformator stanu, który odwzorowuje Stany NA pary stanów i wartości (tzw." monada " w terminologii programistów funkcyjnych).

Niechęć programistów funkcyjnych do nazywania takich języków "referencjalnie przejrzystymi" jedynie oznacza to, że niechętnie przyznają się do tak złożonych obiektów matematyczno-pojęciowych, jak "wartości". Z drugiej strony wydają się doskonale skłonni nazwać transformator Stanowy "wartością", gdy jest on umieszczony w ich ulubionej składni i ubrany w buzz słowo jak"monada". Muszę powiedzieć, że są one całkowicie niespójne, nawet jeśli przyznamy im, że ich idea "przejrzystości odniesienia" ma pewną spójność.

Trochę historii może rzucić trochę światła na to, jak te pojawiły się nieporozumienia. Okres między 1962 a 1967 rokiem był bardzo intensywny dla Christophera Stracheya. W latach 1962-65 pracował w niepełnym wymiarze godzin jako asystent badawczy u Maurice ' a Wilkesa, aby zaprojektować i wdrożyć język programowania, który stał się znany jako CPL. był to imperatywny język programowania, ale miał mieć również potężne funkcje funkcyjne języka programowania. Landin, który był pracownikiem Strachey w swojej firmie doradczej, miał ogromny wpływ o poglądach na języki programowania. W przełomowym artykule z 1965 roku "Next 700 programming languages", Landin bezlitośnie Promuje funkcjonalne języki programowania (nazywając je denotative languages) I opisuje imperatywne języki programowania jako ich "antytezę". W dalszej dyskusji Strachey budzi wątpliwości co do silnej pozycji Landina.

... Formularz DLs podzbiór wszystkich języków. Są interesującym podzbiorem, ale jednym które jest niewygodny w użyciu, chyba że jesteś do tego przyzwyczajony. Potrzebujemy ich ponieważ w tej chwili {[8] } nie wiemy jak skonstruować / align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center / [Dodano]

W 1965 roku Strachey objął stanowisko Czytelnika w Oksfordzie i wydaje się, że pracował zasadniczo w pełnym wymiarze czasu nad opracowaniem teorii imperatywów i skoków. W 1967 roku był gotowy do teorii, której nauczał w swoim kursie na temat "[113]}Fundamental concepts in programming języki " w kopenhaskiej Szkole Letniej. Notatki z wykładu miały być opublikowane, ale " niestety, z powodu dylatacji edycji, postępowanie nigdy się nie zmaterializowało; jak większość prac Strachey ' a w Oksfordzie, jednak Gazeta miała wpływowy prywatny obieg."(Martin Campbell-Kelly )

Trudności w uzyskaniu pism Strachey ' a mogły doprowadzić do propagowania zamieszania, z ludźmi opierającymi się na wtórnych źródłach i pogłoskach. Ale teraz że "{113]}podstawowe pojęcia " są łatwo dostępne w Internecie, nie ma potrzeby uciekania się do zgadywania pracy. Powinniśmy to przeczytać i zdecydować, co Strachey miał na myśli. W szczególności:

  • w sekcji 3.2 zajmuje się "wyrażeniami", gdzie mówi o "przezroczystości referencyjnej wartości R".
  • jego sekcja 3.3 dotyczy "poleceń", gdzie mówi o "przezroczystości referencyjnej wartości L".
  • w sekcji 3.4.5 mówi o " funkcjach i procedury "i oświadcza ,że" każde odejście od wartości referencyjnej R w kontekście wartości R powinno albo być wyeliminowane przez rozkładanie wyrażenia na kilka poleceń i prostsze wyrażenia, lub, jeśli okaże się to trudne, przedmiotem komentarza."

Jakakolwiek mowa o" referencjalnej przezroczystości " bez zrozumienia różnicy między wartościami L, wartościami R i innymi złożonymi obiektami, które wypełniają koncepcyjny wszechświat imperatywnego programisty, jest zasadniczo błąd.

 69
Author: Uday Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-01 12:37:46

Wyrażenie jest referencjalnie przezroczyste, jeśli można je zastąpić jego wartością, bez zmiany algorytmu, dając algorytm, który ma te same efekty i wyjście na tym samym wejściu.

 21
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 01:39:24

Referencjalnie przejrzysta funkcja to taka, która działa jak funkcja matematyczna; biorąc pod uwagę te same wejścia, zawsze będzie produkować te same wyjścia. Oznacza to, że przekazywany stan nie jest modyfikowany, a funkcja nie ma własnego stanu.

 13
Author: Barry Kelly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 01:36:39

Jeśli interesuje Cię etymologia (tj. dlaczego ta koncepcja ma tę konkretną nazwę), zajrzyj do mojego posta na blogu na ten temat. Terminologia pochodzi od filozofa / Logik Quine.

 8
Author: Andrew Birkett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-25 14:03:03

Dla tych, którzy potrzebują zwięzłego wyjaśnienia, zaryzykuję jedno (ale przeczytaj poniższy tekst).

Referencjalna przejrzystość w języku programowania Promuje rozumowanie równościowe - im bardziej referencjalna przejrzystość masz, tym łatwiej jest robić rozumowanie równościowe. Np. z definicją (pseudo) funkcji,

F x = x + x,

Łatwość, z jaką można (bezpiecznie) zastąpić f(foo) Foo + foo w zakresie tej definicji, bez zbyt wielu ograniczeń na temat tego, gdzie można wykonać tę redukcję, jest dobrym wskaźnikiem, jak dużą przejrzystość referencyjną ma twój język programowania.

Na przykład, gdyby foo było x++ w sensie programowania w języku C, to nie mógłbyś bezpiecznie wykonać tej redukcji (co oznacza, że gdybyś miał wykonać tę redukcję, nie skończyłbyś z tym samym programem, z którym zacząłeś).

W praktycznych językach programowania nie widać doskonałej przejrzystości odniesienia, ale programiści funkcyjni dbają o to bardziej niż większość (por. Haskell, gdzie jest głównym celem).

(pełne ujawnienie: jestem programistą funkcjonalnym, więc przy pierwszej odpowiedzi powinieneś przyjąć to Wyjaśnienie z przymrużeniem oka.)

 6
Author: chrisdornan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-16 23:42:23
  1. semantyka Denotacyjna opiera się na modelowaniu języków poprzez budowanie domen, które stanowią denotowalne wartości.
  2. Programiści funkcyjni używają terminu value do opisania zbieżności obliczeń opartych na regułach przepisywania języka ie. jego semantyka operacyjna.

W 1 istnieje klarowność dwóch języków:

  • ten, który jest modelowany, język obiektowy
  • język modelowania, meta język

W 2, dzięki bliskości obiektu i metalurgii, mogą być mylone.

Jako implementator języka uważam, że muszę stale pamiętać o tym rozróżnieniu.

Więc Prof. Reddy mogę cię tak parafrazować: -)

W kontekście programowania funkcyjnego i semantyki termin Referencjalny Przeźroczystość {[3] } nie jest przeźroczysta.

 4
Author: Anuradha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-02 11:24:35

Zauważ, że to pojęcie "znaczenia" jest czymś, co dzieje się w umyśle obserwatora. Tak więc to samo "odniesienie" może oznaczać różne rzeczy dla różnych ludzi. Tak więc, na przykład, mamy Stronę disambiguation Edinburgh w Wikipedii.

Pokrewną kwestią, która może pojawić się w kontekście programowania, może być polimorfizm.

I być może powinniśmy mieć nazwę dla szczególnego przypadku polimorfizmu (a może nawet odlewania), gdzie dla naszych celów różne przypadki polimorficzne są semantycznie równoważne (w przeciwieństwie do po prostu podobnych. Na przykład liczba 1, która może być reprezentowana za pomocą typu integer, typu złożonego lub dowolnego z wielu innych typów, może być traktowana polimorficznie).

 2
Author: rdm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-26 22:33:36

Następująca odpowiedź mam nadzieję dodaje i kwalifikuje kontrowersyjne 1 i 3 odpowiedzi.

Przyznajmy, że wyrażenie oznacza lub odnosi się do jakiś referent. Powstaje jednak pytanie, czy te odniesienia można zakodować izomorficznie jako część samych wyrażeń, nazywając takie wyrażenia "wartościami". Na przykład wartości liczby literalnej są podzbiorem zbioru wyrażeń arytmetycznych, wartości prawdy są podzbiorem zbioru wyrażeń logicznych, itd. Chodzi o to, aby Oblicz wartość wyrażenia (jeśli takie posiada). Tak więc słowo "wartość" może odnosić się do denotacji lub wyróżniającego się elementu zbioru wyrażeń. Jeśli jednak istnieje izomorfizm (bijekcja) między referentem a wartością, to można powiedzieć, że to to samo. (To powiedziawszy, trzeba uważać, aby zdefiniować referentów i izomorfizm, o czym świadczy pole denotacyjne semantyka. Na przykładzie odpowiedzi na 3. odpowiedź, algebraiczna definicja typu danych data Nat = Zero | Suc Nat nie odpowiada zgodnie z oczekiwaniami zbiorowi liczb naturalnych.)

Napiszmy E[·] dla wyrażenia z dziurą, znanego również w niektórych ćwiartkach jako "kontekst". Dwa przykłady kontekstowe wyrażeń podobnych do C to [·]+1 i [·]++.

Napiszmy [[·]] dla funkcji, która przyjmuje wyrażenie (bez otworu) i dostarcza jej znaczenia (referent, denotacja itp.) w niektórych wszechświat zapewniający znaczenie. (Pożyczam notację z pola semantyki denotacyjnej.)

Niech u nas definicja Quine ' a jest nieco formalnie następująca: a context E[·] jest referencyjnie przejrzyste iff biorąc pod uwagę dowolne dwa wyrażenia E1 i E2 (brak dziur tam) takie, że [[E1]] = [[E2]] (tzn. wyrażenia oznaczają / odnoszą się-do ten sam referent) wtedy jest tak, że [[E[E1]]] = [[E[E2]]] (tzn. wypełnienie dziura z E1 lub E2 powoduje wyrażenie, które również oznacza to samo referent).

Reguła Leibniza zastępowania równości dla równości jest zwykle wyrażona jako " jeśli E1 = E2 then E[E1] = E[E2]", który mówi, że {[1] } jest funkcją. Funkcja (lub program obliczający funkcję) jest odwzorowaniem z źródło do celu, tak aby dla każdego źródła był co najwyżej jeden element docelowy element. Funkcje niedeterministyczne są misnomerami, są albo relacjami, funkcje dostarczające zestawy itp. Jeśli w regule Leibniza równość = jest denotacyjne, wówczas nawiasy podwójne są po prostu brane za pewnik i / align = "left" / Zatem kontekstem odniesienia jest funkcja. Oraz Reguła Leibniza jest głównym składnikiem rozumowania równościowego, więc rozumowanie równościowe jest zdecydowanie związane z transparentnością referencyjną.

Chociaż {[4] } jest funkcją Od wyrażeń do denotacji, może być funkcji Od wyrażeń do "wartości" rozumianych jako ograniczony podzbiór wyrażenia i [[·]] można rozumieć jako ewaluację.

Teraz, Jeśli E1 jest wyrażeniem i {[7] } jest wartością, mamy to, co myślę, że rozumie większość ludzi przy definiowaniu referencjalnych przejrzystość w zakresie wyrażeń, wartości i oceny. Ale jak pokazują pierwsze i trzecie odpowiedzi na tej stronie, jest to definicja inacurate.

Problem z kontekstami takimi jak [·]++ nie jest efektem ubocznym, ale że jego wartość nie jest zdefiniowana w C izomorficznie do jego znaczenia. Funkcje to nie wartości (cóż, wskaźniki do funkcji są), podczas gdy w funkcyjnych językach programowania są. Landin, Strachey, a pionierzy semantyki denotacyjnej byli dość sprytni w używanie funkcjonalnych światów, by nadać sens.

Dla imperatywnych języków C-podobnych możemy (z grubsza) dostarczyć semantyki do wyrażenia za pomocą funkcji [[·]] : Expression -> (State -> State x Value).

Value jest podzbiorem Expression. State Zawiera pary (IDENTYFIKATOR, wartość). Funkcja semantyczna przyjmuje wyrażenie i dostarcza jako jego znaczenie Funkcja od aktualnego stanu do pary ze zaktualizowanym stan i wartość. Na przykład {[25] } jest funkcją ze stanu bieżącego do pary, której pierwszy składnik jest aktualnym stanem i którego drugi składowa jest wartością x. natomiast {[26] } jest funkcją z stanu bieżącego do pary, której pierwszy składnik jest stanem, w którym wartość X jest inkrementowany, a którego drugi składnik jest tą samą wartością. W tym sens, kontekst {[3] } jest referencjalnie przejrzysty iff spełnia definicja podana powyżej.

Myślę, że programiści funkcyjni mają prawo korzystać z przezroczystości referencji w poczucie, że w naturalny sposób odzyskują [[·]] jako funkcja Od wyrażeń do wartości. Funkcje są wartościami pierwszej klasy i stan może być również wartością, a nie denotacja. Monada stanu jest (częściowo) czystym mechanizmem przechodzenia (lub threading) Państwa.

 2
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-29 17:45:32

W programowaniu funkcyjnym przezroczystość referencyjna jest ogólnie definiowana jako fakt, że wyrażenie w programie może być zastąpione przez jego wartość (lub cokolwiek o tej samej wartości) bez zmiany wyniku programu. Oznacza to, że metody powinny zawsze zwracać tę samą wartość dla danego argumentu, bez żadnego innego efektu. Ta koncepcja programowania funkcyjnego odnosi się również do programowania imperatywnego i może pomóc w tworzeniu kodu jaśniej.

Przejrzystość Referencyjna

Wyrażenie referential transparency jest używane w różnych dziedzinach, takich jak matematyka, logika, lingwistyka, filozofia i programowanie. Ma zupełnie inne znaczenie w każdej z tych dziedzin. Tutaj zajmiemy się tylko programami komputerowymi, chociaż pokażemy analogię z matematyką(prosta matematyka, nie martw się). Należy jednak pamiętać, że informatycy nie zgadzają się co do znaczenia przejrzystości odniesienia w programowaniu. Co? przyjrzymy się referencjalnej przezroczystości, ponieważ jest ona używana przez programistów funkcyjnych.

Przejrzystość referencyjna w matematyce W matematyce przezroczystość referencyjna jest właściwością wyrażeń, które można zastąpić innymi wyrażeniami o tej samej wartości bez zmiany wyniku w jakikolwiek sposób. Rozważ następujący przykład:

x = 2 + (3 * 4)

Możemy zastąpić podwyrażenie (3 * 4) dowolnym innym wyrażeniem o tej samej wartości bez zmiany wyniku (wartość X). Najbardziej oczywiste wyrażenie do użycia, jest oczywiście 12:

x = 2 + 12

Każde inne wyrażenie o wartości 12 (maybe (5 + 7)) może być użyte bez zmiany wyniku. W konsekwencji podekspresja (3 * 4) jest referencyjnie przejrzysta.

Możemy również zastąpić wyrażenie 2 + 12 innym wyrażeniem o tej samej wartości bez zmiany wartości x, więc jest ono również referencjalnie przezroczyste:

x = 14

Można łatwo dostrzec korzyści płynące z przejrzystości odniesienia: pozwala rozumowanie. Bez niego nie moglibyśmy rozwiązać żadnego wyrażenia bez uwzględnienia innych elementów.

Przejrzystość odniesienia w programowaniu W programowaniu transparentność odnosi się do programów. Ponieważ programy składają się z podprogramów, które same są programami, dotyczy to również tych podprogramów. Podprogramy mogą być reprezentowane między innymi metodami. Oznacza to, że metoda może być referencyjnie przejrzysta, co ma miejsce w przypadku, gdy wywołanie tej metody może zostać zastąpione według wartości zwracanej:

int add(int a, int b) {
        return a + b
    }

int mult(int a, int b) {
        return a * b;
    }

int x = add(2, mult(3, 4));

W tym przykładzie metoda mult jest referencyjnie przejrzysta, ponieważ każde wywołanie do niej może zostać zastąpione odpowiednią wartością zwracaną. Można to zaobserwować poprzez zastąpienie mult (3, 4) przez 12:

int x = add(2, 12)

W ten sam sposób, add (2, 12) może być zastąpiony odpowiednią wartością zwracaną, 14:

int x = 14;

Żaden z tych zamienników nie zmieni wyniku programu, cokolwiek on zrobi. Zauważ, że możemy użyć dowolnego innego wyrażenia o tym samym wartość, która jest przydatna przy refaktoryzacji.

Z drugiej strony, rozważ następujący program:

int add(int a, int b) {
    int result = a + b;
    System.out.println("Returning " + result);
    return result;
}

Zastąpienie wywołania metody add odpowiednią wartością zwracaną zmieni wynik programu, ponieważ wiadomość nie będzie już drukowana. W takim przypadku usunie tylko efekt uboczny, ale w innych przypadkach może zmienić wartość zwracaną przez metodę:

public static void main(String... args) {
    printFibs(10);
}

public static void printFibs(int limit) {
    Fibs fibs = new Fibs();
    for (int i = 0; i < limit; i++) {
        System.out.println(fibs.next());
    }
}

static class Fibs {
    private int previous = -1;
    private int last = 1;

    public Integer next() {
        last = previous + (previous = last);
        return previous + last;
    }
}

Tutaj następnej metody nie można zastąpić niczym o tej samej wartości, ponieważ metoda jest zaprojektowana tak, aby zwracać inną wartość przy każdym wywołaniu.

Używanie takich nieprzezroczystych metod wymaga silnej dyscypliny, aby nie dzielić zmiennego stanu zaangażowanego w obliczenia. Styl funkcjonalny unika takich metod na rzecz referencjalnie przejrzystych wersji.

Przejrzystość odniesienia w programowaniu imperatywnym Zarówno programowanie imperatywne, jak i funkcyjne wykorzystują funkcje. Chociaż Programowanie funkcyjne wykorzystuje tylko funkcje, imperatyw zastosowania programowania:

  • pure functions: methods returning values and having no other effects
  • pure effects: metody zwracające nic poza zmianą czegoś poza nimi)
  • Funkcje z efektami ubocznymi: metody zwracające wartość i zmiana czegoś

Jak wszyscy wiemy, dobrą praktyką jest unikanie funkcji z efektami ubocznymi. Pozostawia to imperatywnych programistów z czystymi funkcjami i czystymi efektami. Przezroczystość referencyjna jest wtedy potężne narzędzie dla programistów, dzięki któremu ich programy są łatwiejsze do zrozumienia i łatwiejsze do przetestowania.

 0
Author: bumblebee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 17:31:35