Streszczenie Kontynuacje
Kontynuacje są abstrakcyjne pojęcie, które są używane do opisu semantyki przepływu sterowania. W tym sensie oba istnieją i nie istnieją (pamiętaj, że są abstrakcyjne) w dowolnym języku, który oferuje operatory kontroli (jak każdy inny język Turinga), w taki sam sposób, w jaki istnieją obie liczby (jako obiekty abstrakcyjne) i nie istnieją (jako namacalne byty).
Kontynuacje opisują efekty kontrolne, takie jak wywoływanie/zwracanie funkcji, obsługa wyjątków, a nawet próby. Dobrze napisany język będzie, między innymi, zaprojektowany z abstrakcjami opartymi na kontynuacjach (np. Wyjątkach). (Oznacza to, że dobrze napisany język będzie składał się z operatorów kontrolnych, którzy zostali zaprojektowani z myślą o kontynuacji.) Jest oczywiście całkowicie uzasadnione, aby język mógł ujawniać kontynuacje jako abstrakcja kontroli, umożliwiając użytkownikom tworzenie własne abstrakcje na wierzchu.)
First Class Kontynuacje
Jeśli pojęcie kontynuacji jest reified jako obiekt pierwszej klasy w języku, to mamy narzędzie, na którym wszystkie rodzaje efektów sterowania można wybudowany. Na przykład, jeśli język ma kontynuacje pierwszej klasy, ale nie wyjątki, możemy tworzyć wyjątki oprócz kontynuacji.
Problemy z pierwszej klasy Kontynuacje
Podczas kontynuacją pierwszej klasy są potężne i użyteczne narzędzie w wielu przypadkach istnieją również pewne wady wystawiając je w języku:
- Różne abstrakcji budowane kontynuacja może spowodować nieoczekiwane/nieintuicyjne zachowanie po złożeniu. Na przykład blok
finally
może zostać pominięty, jeśli użyję kontynuacji do przerwania obliczeń.
- Jeśli bieżąca kontynuacja może być wymagana w dowolnym czasie, wówczas czas uruchamiania języka musi być skonstruowany w taki sposób, aby w danym momencie możliwe było wygenerowanie reprezentacji struktury danych bieżącej kontynuacji. To powoduje pewien stopień obciążenia dla funkcji, która na dobre lub na gorsze jest często uważana za "egzotyczną". Jeśli język jest hostowany (taki jak Clojure jest hostowany w JVM), to reprezentacja musi być w stanie zmieścić się w ramach przewidzianych przez platformę hostingową. Mogą istnieć również inne funkcje, które język chciałby utrzymać (np. C interop), które ograniczają przestrzeń rozwiązania. Takie problemy zwiększają potencjał "niedopasowania impedancji" i mogą poważnie skomplikować rozwój rozwiązania opartego na wydajności.
Dodanie pierwszej klasy kontynuacje do języka
Through metaprogramowanie, możliwe jest dodanie wsparcia dla kontynuacji pierwszej klasy na języku. Zasadniczo podejście to polega na transformacji kodu do stylu przekazywania kontynuacji (CPS), w którym bieżąca kontynuacja jest przekazywana jako jawny argument do każdej funkcji.
Na przykład biblioteka Davida Nolena delimc implementuje rozdzielone kontynuacje części programu Clojure za pomocą serii przekształceń makr. W podobnym duchu napisałem: pulley.cps, który jest makro kompilatorem, który przekształca kod w CPS, wraz z biblioteką wykonawczą do obsługi większej liczby podstawowych funkcji Clojure (takich jak obsługa wyjątków) oraz współdziałania z natywnym kodem Clojure.
Jednym z problemów związanych z tym podejściem jest sposób radzenia sobie z granicami między natywnym (Clojure) i przekształconym (CPS) kodem. W szczególności, ponieważ nie możesz uchwycić kontynuacji kodu natywnego, musisz albo zabronić (lub w jakiś sposób ograniczyć) współdziałanie z językiem podstawowym, albo obciążyć użytkownika, upewniając się, że kontekst pozwoli dowolnej kontynuacji, którą chcą uchwycić, aby faktycznie zostać złapanym.
pulley.cps zmierza w kierunku tego drugiego, chociaż niektóre próby zostały podjęte, aby umożliwić użytkownikowi zarządzanie tym. Na przykład, możliwe jest zablokowanie kodu CPS w celu wywołania natywnego kodu. Ponadto zapewniono mechanizm dostarczania wersji CPS istniejących funkcji natywnych.
W języku o wystarczająco silnym systemie typów (takim jak Haskell), możliwe jest zastosowanie systemu typu do enkapsulacji obliczeń, które mogą wykorzystywać operacje kontrolne (tj. Kontynuacje) z funkcjonalnie czystego kodu.
Podsumowanie
Mamy teraz informacje niezbędne, aby bezpośrednio odbierać swoje trzy pytania:
- Clojure nie obsługuje pierwszej klasy kontynuacje spowodowane względami praktycznymi.
- Wszystkie języki są zbudowane na kontynuacjach w sensie teoretycznym, ale niewiele języków eksponuje kontynuacje jako pierwszorzędne obiekty. Jednak możliwe jest dodanie kontynuacji do dowolnego języka poprzez, na przykład, przekształcenie w CPS.
- Sprawdź dokumentację dla delimc i/lub pulley.cps.
Twój tytuł pytania nie ma wiele wspólnego z tekstem pytania. –
Czy to lepiej? – unj2