Jak leczy się skutki uboczne w semantyce?


19

W sekcji „Wprowadzenie do języków programowania” Anthony'ego Aaby'ego na temat semantyki dokonuje następujących obserwacji:

Znaczna część pracy w semantyce języków programowania jest motywowana problemami napotkanymi przy próbie konstruowania i zrozumienia programów imperatywnych - programów z poleceniami przypisania. Ponieważ polecenie przypisania ponownie przypisuje wartości do zmiennych, przypisanie może mieć nieoczekiwane skutki w odległych częściach programu.

Uderza mnie to jako niezwykłe przyznanie, że dopuszczenie efektów ubocznych zmotywowałoby większą część pracy w semantyce.

W jaki sposób występowanie efektów ubocznych w języku programowania wpływa na możliwość mapowania programu na model obliczeniowy? Czy istnieją podejścia do zarządzania stanem, które mogą poprawić ten proces, jednocześnie pozwalając na skutki uboczne?


Czy należy to oznaczyć jako pytanie miękkie? Ponieważ „znaczna część pracy w semantyce [...] jest motywowana [skutkami ubocznymi]”, z pewnością nie można oczekiwać krótkiej i rygorystycznej odpowiedzi.
Radu GRIGore

1
@Radu: W MO prawdopodobnie oznaczono by to jako [duży obraz], które w większości nie są tam [miękkie pytanie] lub CW.
Charles Stewart

Tag duży obraz jest jeszcze lepszy. Zapomniałem o tym.
Radu GRIGore

Dobry pomysł; Dodałem tag.
Shane

Odpowiedzi:


18

Opierając się na odpowiedzi Charlesa, główną trudnością w teorii języków programowania jest to, że naturalnym pojęciem równoważności programów zazwyczaj nie jest ścisła równość ani w najprostszej semantyce matematycznej, jaką można podać, ani w leżącym u podstaw modelu maszyny. Rozważmy na przykład następujący fragment kodu podobnego do języka Java:

Object x = new Object();
Object y = new Object();
... some more code ...

Tak więc ten program tworzy obiekt i nazywa go x, a następnie tworzy drugi obiekt o nazwie y, a następnie kontynuuje wykonywanie dodatkowego kodu. Załóżmy teraz, że programista decyduje o zmianie kolejności przydziału tych dwóch obiektów:

Object y = new Object();
Object x = new Object();
... some more code ...

Teraz zadaj pytanie: czy to refaktoryzacja zmienia zachowanie programu? Z jednej strony, na bazowej maszynie, xiy zostaną przydzielone w różnych lokalizacjach w dwóch uruchomieniach programu. W tym sensie program zachowuje się inaczej.

Ale w języku podobnym do języka Java można testować odniesienia tylko pod kątem równości, a nie porządku, więc jest to różnica, której „więcej kodu” nie może zaobserwować . W rezultacie większość programistów spodziewa się, że odwrócenie kolejności nie będzie miało wpływu na ostateczną odpowiedź, a większość autorów kompilatorów spodziewa się, że będzie mogła na tej podstawie przeprowadzać zmiany kolejności i optymalizacje. (Z drugiej strony, w C-jak język, to można porównać wskaźniki dla zamawiającego, oddając je do liczb całkowitych pierwszy, a więc takim zamianom czy nie koniecznie zachować zaobserwowania zachowania).

Jednym z głównych pytań semantyki jest odpowiedź na pytanie, kiedy dwa programy są wyraźnie równoważne. Ponieważ nasze pojęcie obserwacji zależy od cech języka programowania, otrzymujemy definicję w rodzaju „dwa programy są równoważne, gdy żaden program kliencki nie jest w stanie obliczyć różnych odpowiedzi na podstawie otrzymania tych programów jako danych wejściowych”. Kwantyfikacja wszystkich programów klienckich sprawia, że ​​to pytanie jest trudne - wydaje się, że ostatecznie musisz powiedzieć coś o wszystkich możliwych programach klienckich, aby powiedzieć coś o dwóch konkretnych fragmentach kodu.

Sztuczka z semantyką denotacyjną polega na podaniu matematycznej interpretacji, która pozwala uniknąć tej uniwersalnej kwantyfikacji - mówisz, że znaczenie fragmentu kodu jest pewną wartością matematyczną, i porównujesz je, sprawdzając, czy są one matematycznie równe lub nie. Jest to lokalne (tj. Kompozycyjne) i nie obejmuje kwantyfikacji wszystkich możliwych klientów. (Musisz wykazać, że semantyka denotacyjna oznacza oczywiście równoważność kontekstową, aby mogła ona brzmieć. Gdy jest kompletna - gdy równość denotacyjna jest dokładnie taka sama jak równoważność kontekstowa, mówimy, że semantyka jest „w pełni abstrakcyjna”.)

Oznacza to jednak, że musisz upewnić się, że semantyka denotacyjna potwierdza te równoważności. W tym przykładzie, jeśli chcesz nadać denotacyjną semantykę dla tego języka podobnego do Javy, musisz upewnić się, że nie tylko wywołanie nowego zabiera stertę i zwraca nową stertę z nowo utworzonym obiektem, ale że znaczenie programu jest niezmienny tak samo we wszystkich permutacjach stosu wejściowego. Może to obejmować dość złożone struktury matematyczne (np. W tym przypadku praca w kategorii, która zapewnia, że ​​wszystko działa modulo w odpowiedniej grupie permutacyjnej).


„dwa programy są równoważne, gdy żaden program kliencki nie jest w stanie obliczyć różnych odpowiedzi na podstawie otrzymania tych programów jako danych wejściowych”. Jestem tym zmieszany. Jeśli masz program X i program kliencki Y, to mam na myśli, że Y „wywołuje” w X. Ale wydaje się, że mówisz, że Y odczytuje tekst X jako dane wejściowe , w którym to przypadku prawie nie wywołałbym Jesteś „klientem” X. Czy możesz to wyjaśnić?
Radu GRIGore

1
Przez „klienta X” mam na myśli to samo, co „kontekst programu”, który jest po prostu „większym programem, który zawiera X jako podtermin”.
Neel Krishnaswami

Więc używasz „X jest klientem Y” zamiennie z „X czyta Y jako dane wejściowe”, ponieważ myślisz o X jako lambda zastosowanym do Y? To ma sens, ale jest trochę pokręcone, kiedy mówisz o Javie. :)
Radu GRIGore

1
@RaduGRIGore: kontekst programu oznacza coś innego. Czytasz poprawnie post, ale jeśli X odczytuje kod źródłowy Y jako dane wejściowe (tak interpretuję post), możesz rozróżnić co dwa różne składniowo programy; zamiast tego, jeśli Y jest funkcją lambda na X, możesz rozróżnić zbyt mało programów. Komentarz Neela na temat „kontekstu programu” jest poprawną definicją: kontekst programu Y jest programem z dziurą w AST, w którym można (znacząco) umieścić dwa różne fragmenty programu X1 i X2.
Blaisorblade

@NeelKrishnaswami: czy możesz wyjaśnić, co masz na myśli w poście? Możesz po prostu kontynuować przykład i mówić o programie, w którym możesz wstawić jeden lub drugi fragment.
Blaisorblade

12

Istnieją oczywiście sposoby radzenia sobie z efektami w (denotacyjnej) semantyce. Na przykład możemy użyć idei Eugenio Moggiego, że efektami obliczeniowymi są monady (ta idea została również wykorzystana w projekcie Haskell). Jednym z problemów jest to, że monady są trudne do połączenia. Gordon Plotkin i John Power zasugerowali udoskonalenie monad Moggiego do teorii Lawvere'a lub teorii algebraicznych, jak się je nazywa, co obejmuje efekty algebraiczne (najczęstsze efekty to algebraiczne, takie jak stan, operacje we / wy, niedeterminizm, ale kontynuacje są nie). Aby uzyskać kompleksowe leczenie, zobacz tezę Matiji Pretnar .

Powinienem też wspomnieć o możliwej semantyce światów dla stanu lokalnego, opracowanej przez Franka Olesa i Johna Reynoldsa (przepraszam, nie mogę znaleźć lepszego linku, te rzeczy pochodzą z 1982 roku), która poprzedza monady Moggi. Użyli kategorii preheaves, aby uzyskać semantykę języka przypominającego algol, który poprawnie modelował wiele aspektów stanu lokalnego (ale nie wszystkie z nich, myślę, że model pozwalał na snapback, ale może moja pamięć źle mi służy).


1
Tak, semantyka kategorii funktorów nie zweryfikowała wszystkich równoważności Meyera-Siebera. Peter O'Hearn i Robert Tennant opracowali parametryczną wersję semantyki kategorii funktorów w połowie lat 90., która (IIRC) otrzymała wszystkie przykłady Meyera-Siebera, ale nie wiem, czy była w pełni abstrakcyjna, czy nie.
Neel Krishnaswami

Model O'Hearn i Tennent nie jest w pełni abstrakcyjny. Zostało to omówione w samym artykule. Ale udoskonalenie przez O'Hearn i Reynoldsa przy użyciu liniowego rachunku lambda jest w pełni abstrakcyjne aż do drugiego rzędu. Przełamuje się dla trzeciego rzędu, przy czym przykładami są równoważności badane przez Ahmeda, Dreyera, Birkedala i in.
Uday Reddy

12

Matthias Felleisen przedstawił przekonujące rozwiązanie problemu skutków ubocznych w semantyce w swojej serii „Syntaktyczne teorie kontroli i stanu”.

Ta linia pracy zaowocowała maszyną CESK, prostą abstrakcyjną strukturą maszyny zdolną do zwięzłego modelowania funkcjonalnych, obiektowych, imperatywnych, a nawet logicznych języków. CESK obsługuje nie tylko skutki uboczne, ale także „złożone” konstrukcje kontrolne, takie jak wyjątki, kontynuacje, lenistwo, a nawet wątki.

Maszyna CESK, a szerzej - semantyka operacyjna w szerszym zakresie, są de facto standardem w teorii języków programowania przez około dwie dekady.

Krótko mówiąc, maszyna CESK jest maszyną małostopniową z czterema komponentami do opisania każdego stanu maszyny: ciąg sterujący (uogólnienie licznika programu), środowisko, magazyn (zwany także stertą) i bieżąca kontynuacja.

Środowisko mapuje zmienne na adresy; sklep mapuje adresy na wartości.

Ułatwia to modelowanie zmiennych zmiennych: wystarczy zmienić wartość pod jego adresem.

Ułatwia także modelowanie wskaźników i alokację dynamiczną: po prostu spraw, aby adresy sklepów były najwyższej jakości.

Podobnie kontynuacje pierwszej klasy wynikają z nadania im wartości adresowalnych.


6

W jaki sposób występowanie efektów ubocznych w języku programowania wpływa na zdolność mapowania programu do modelu obliczeniowego?

Nie musi to utrudniać, ale nakłada ograniczenia na sposób konstruowania semantyki większych wyrażeń z mniejszych. Może bardzo źle oddziaływać z niektórymi innymi konstrukcjami programistycznymi, na przykład, jeśli chce się nadać semantykę denotacyjną w stylu Scotta dla języka umożliwiającego przypisanie funkcji wyższego rzędu do globalnych odniesień.

Problemem są nie tylko skutki uboczne, takie jak stan. Proste języki rozkazujące, takie jak strzeżony język poleceń Dijkstry, mają tego rodzaju skutki uboczne i mają ładną semantykę. Pojawiają się problemy z rozszerzeniami rachunku lambda o rodzaj semantyki operacyjnej oczekiwanej od języków programowania, nawet przy braku efektów ubocznych: najwcześniej, PCF Plotkina, podano modele denotacyjne stosunkowo wcześnie, ale semantyka nie była w pełni abstrakcyjna, co oznacza, że semantyka denotacyjna była zbyt ogólna, nie do końca odpowiadająca semantyce operacyjnej. PCF w końcu uzyskał w pełni abstrakcyjną semantykę denotacyjną pod koniec lat osiemdziesiątych z semantyką gier, która wcale nie przypomina semantyki teoretycznej Scott. Współbieżność nadal nie otrzymała w pełni odpowiedniego traktowania denotacyjnego.

Wielu kwestionuje znaczenie tego rodzaju semantyki. Zawsze możemy zapewnić pewnego rodzaju semantykę operacyjną, nawet jeśli ta „semantyka” jest tylko źródłem programu i nazwami niektórych komputerów, które skompilowały i uruchomiły program: z tego powodu Strachey potępił semantykę operacyjną. Ale semantyka operacji strukturalnych Plotkina pokazała, jak semantykę operacyjną można oddzielić od modeli maszyn, a praca Pitta pokazała, w jaki sposób semantyka może wspierać podobne rozumowanie programów i języków programowania do semantyki denotacyjnej. Tak więc semantyka operacyjna jest realną alternatywą dla semantyki denotacyjnej i została z powodzeniem zastosowana w znacznej liczbie języków programowania, takich jak Standard ML.

Czy istnieją podejścia do zarządzania stanem, które mogą poprawić ten proces, jednocześnie pozwalając na skutki uboczne?

W pewnym stopniu trudności w zapewnieniu semantyki odpowiadają trudnościom w zapewnieniu potężnych języków programowania, które zachowują się tak, jak można by się spodziewać. Pragmatycznie umotywowane decyzje projektowe - takie jak unikanie użycia stanu globalnego razem z współbieżnością, zwykle poprzez współbieżność przekazywania wiadomości - ułatwiają zapewnienie semantyki.


PCF Scotta nie ma stanu i nie jest też Scotta, jest to zobaczyć? En.wikipedia.org/wiki/...
Andrej Bauer

@Andrej: Err, całkiem, biorąc pod uwagę, że Luke Ong nadzorował mojego D. Phila, nie powinienem popełniać tego błędu. Zamieściłem podsumowanie zwiastuna PCF Milnera i LCF Scotta, które jest bardziej ... soczyste niż WP jako historia LtU : lambda-the-ultimate.org/node/2196 Przyszło mi do głowy, że możesz mieć dostęp do zaginionego Scotta (1969) rękopis ...
Charles Stewart

Myślę, że to byłby PCF Plotkina :-) Mogę spróbować zdobyć manuskrypt, ale tak naprawdę go nie mam.
Andrej Bauer,

Ale pozostaje faktem, że PCF nie ma stanu. Jaki „powód” mówisz Stracheyowi, aby potępił semantykę operacyjną? To nie było dla mnie oczywiste. Ostatni akapit zaprzecza temu, co powiedziałeś wcześniej, a mianowicie strzeżone polecenia mają ładną semantykę, ale PCF nie!
Uday Reddy

@Andrej, Uday: Naprawiłem swój post mniej niż trzy lata później.
Charles Stewart
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.