Myślę, że pytasz o dwie różne rzeczy.
- Zdolność języka programowania do reprezentowania wszystkich swoich programów jako danych.
- Rozumowanie programów jako danych.
Do celów analitycznych warto je rozdzielić. Skoncentruję się na tym pierwszym.
Zdolność do reprezentowania języków programowania, manipulować (i bieg) swoje programy jako dane idzie pod określeniami takimi jak meta-programowania lub
homoikoniczność .
W (niezręczny) sposób wszystkie dobrze znane języki programowania mogą wykonywać meta-programowanie, a mianowicie przy użyciu typu danych ciągu wraz z możliwością wywoływania programów zewnętrznych (kompilatora, konsolidatora itp.) Na ciągach znaków (np. Zapisując je do pliku najpierw system). Jednak prawdopodobnie nie to masz na myśli. Prawdopodobnie masz na myśli niezłą składnię. Ciągi nie są ładną składnią do reprezentacji programu, ponieważ prawie wszystkie ciągi nie reprezentują programów, tzn. Typ danych ciągów zawiera wiele „śmieci”, gdy są postrzegane jako mechanizm reprezentacji programu. Co gorsza, algebra operacji ciągów nie ma zasadniczo żadnego związku z algebrą budowy programu.
To, co prawdopodobnie masz na myśli, jest o wiele ładniejsze. Np. Jeśli jest programem, to to , ale jako dane, pod ręką do manipulacji i analizy. Jest to często nazywane cytatem . W praktyce oferta cenowa jest nieelastyczna, dlatego zamiast niej używamy quasi-oferty , która jest uogólnieniem oferty, w której oferta może zawierać „dziury”, w których można uruchamiać programy dostarczające dane do „wypełnienia” dziur. Na przykład to quasi-cytat reprezentujący warunek, w którym zamiast warunku mamy dziuręPP ⟨ i F⟨P⟩P[ ⋅ ] M ⟨ x > 0 ⟩ ⟨ i F
F i f[ ⋅ ]t h e n7e l s e8 + 9 ⟩
[ ⋅ ] . Jeśli program ocenia dane , to quasi-cytat ocenia dane
M.⟨ X > 0 ⟩⟨ i FF i f[ M]t h e n7e l s e8 + 9 ⟩
F i fx > 0t h e n7e l s e8 + 9 ⟩ .
(Zauważ, że jest normalnym programem (nie programem jako danymi), który zwraca cytowany program, tj. Program jako dane.) Aby to zadziałało, potrzebujesz typu danych do reprezentowania programów. Zazwyczaj ten typ danych nazywa się AST (abstrakcyjne drzewo składniowe) i można zobaczyć (quasi -) cytaty jako mechanizmy skrótów dla AST.M.
Kilka języków programowania oferuje quasi-cytaty i inne funkcje meta-programowania. To Lisp z funkcją makrowania pionierem tej zdolności do traktowania programów jako danych. Być może niestety moc makr opartych na Lisp od dawna spoczywała w dużej mierze na minimalistycznej składni Lisp; dopiero w MetaML (1) okazało się, że nowoczesny język o bogatej składni jest zdolny do metaprogramowania. Od tego czasu MetaOCaml (2) (potomek MetaML, ważny dla jego przełomu w wciąż trwających poszukiwaniach rozwiązania problemu pisania programów jako dane), Template Haskell (3) i Converge (4) (pierwszy język do uzyskać wszystkie kluczowe funkcje metaprogramowania w mojej opinii) pokazały, że w wielu nowoczesnych językach programowania można umieścić metaprogramowanie. Ważne jest, aby zdać sobie sprawę, że możemy to zrobićdowolny język programowania i zamień go w język meta-programowania
który jest wraz z możliwością reprezentowania (i oceny) własnych programów jako danych.L m p LL.L.m pL.
Reprezentację wyniku działania programu, podanego jako dane, osiąga się przez dodanie funkcji która pobiera program (podany jako dane) jako dane wejściowe i uruchamia go , zwracając swój wynik. Np. Jeśli jest programem oceniającym na 17 i , wersja (quasi-) cytowana , tj. jako dane, to również również zwraca 17. Istnieją różne sposoby subtelności tutaj, które tutaj ignoruję, takie jak pytanie kiedye v a l (⋅)P.⟨ P⟩P.P.e v l (⟨P⟩ )programy meta-programowane są oceniane (co powoduje rozróżnienie między meta-programowaniem w czasie kompilacji a czasem wykonywania), co zrobić z typami lub błędnymi ocenami, co dzieje się ze zmiennymi powiązanymi i swobodnymi w procesie przechodzenia od do lub odwrotnie.P.⟨ P⟩
Jeśli chodzi o drugi wymiar, rozumowanie programów podanych jako dane. Gdy tylko przekształcisz programy w dane, są one „normalnymi” danymi i można je traktować jako dane. Możesz używać wszelkiego rodzaju technologii sprawdzających, np. Typy zależne lub umowy, interaktywne dowody twierdzeń lub zautomatyzowane narzędzia, jak zauważył Joshua. Będziesz jednak musiał przedstawić semantykę swojego języka w procesie rozumowania. Jeśli ten język, tak jak tego potrzebujesz, ma zdolności metaprogramowania, sprawy mogą stać się nieco trudne i nie wykonano wiele pracy w tym kierunku, przy czym (5) jest jedyną logiką programu w tym celu. Istnieją również prace Curry'ego-Howarda nad wnioskami dotyczącymi metaprogramowania (6, 7, 8). Zauważ, że te podejścia oparte na logice, a podejście oparte na typach (2) może rzeczywiście wyrażać właściwości, które zachowują się na wszystkich przyszłych etapach metaprogramowania. Poza (2) żaden z tych dokumentów nie został wdrożony.
Podsumowując: to, o co prosiłeś, zostało zaimplementowane, ale jest dość subtelne i wciąż istnieją otwarte pytania, w szczególności dotyczące typów i usprawnionego rozumowania.
W. Taha. Programowanie wieloetapowe: jego teoria i zastosowania .
W. Taha i MF Nielsen. Klasyfikatory środowiskowe .
T. Sheard i S. Peyton Jones. Szablon meta-programowania dla Haskell .
L. Tratt. Metaprogramowanie w czasie kompilacji w dynamicznie pisanym języku OO .
M. Berger, L. Tratt, Program Logics for Homogeneous Meta-Programming .
R. Davies, F. Pfenning, Analiza modalna obliczeń etapowych .
R. Davies, Podejście czasowo-logiczne do analizy czasu wiązania .
T. Tsukada, A. Igarashi. Logiczna podstawa dla klasyfikatorów środowiska .