Edycja: mój język pozwala na wielokrotne dziedziczenie, w przeciwieństwie do Java.
Zacząłem projektować i rozwijać własny język programowania do celów edukacyjnych, rekreacyjnych i potencjalnie użytecznych.
Na początku postanowiłem oprzeć ją na Javie.
Sugerowało to, że cały kod zostałby napisany w postaci klas, a kod kompiluje się w klasy, które są ładowane przez maszynę wirtualną.
Wykluczyłem jednak takie funkcje, jak interfejsy i klasy abstrakcyjne, ponieważ nie znalazłem takiej potrzeby. Wydawało się, że wprowadzają w życie paradygmat, i chciałbym, żeby mój język tego nie robił. Chciałem jednak zachować klasy jako jednostkę kompilacji, ponieważ wydawało mi się to wygodne w implementacji, znane i po prostu spodobał mi się ten pomysł.
Potem zauważyłem, że w zasadzie mam system modułowy, w którym klasy mogą być używane albo jako „przestrzenie nazw”, zapewniając stałe i funkcje za pomocą static
dyrektywy, albo jako szablony dla obiektów, które muszą zostać utworzone („rzeczywisty” cel klas w innych językach).
Teraz zastanawiam się: jakie są wady i zalety posiadania klas jako jednostek kompilacyjnych?
Również wszelkie ogólne komentarze na temat mojego projektu byłyby bardzo mile widziane. Post informacyjny w moim języku można znaleźć tutaj: http://www.yannbane.com/2012/12/kava.html .
Odpowiedzi:
Może zmniejszyć złożoność języka. Nie ma potrzeby stosowania różnych konstrukcji, wszystko jest traktowane tak samo. W niektórych projektach (choć nie twoje) wydaje się, że korzystasz z braku statyki i problemów projektowych, na które zwykle wpadają (problemy z kolejnością inicjalizacji, ograniczenia współbieżności, niezręczność z klasami rodzajowymi / rodzajowymi). Pozwala to również na pewne zalety koncepcji modułu, takie jak izolowane instancje modułów dla piaskownicy lub równoległości; oraz wpisywanie modułów, w których zależności pasują do jakiegoś interfejsu, a wartość implementacji całego modułu można utworzyć i wprowadzić.
To powiedziawszy, koncepcja ma zwykle więcej problemów niż nie. Realistycznie nie można traktować wszystkiego tak samo, ponieważ klasy „najwyższego poziomu” wymagają specjalnych zasad, takich jak domyślny konstruktor (w przeciwnym razie możesz napotkać dziwne problemy przy ich rozkładaniu). Modułowość jednostek kompilacyjnych również staje się naprawdę niezręczna. W jaki sposób klasa odwołuje się do innych, gdy są tylko klasami? Jak radzi sobie z tymi zależnościami i jak określasz prawidłową kolejność rozkładania klas? Jak upewnić się, że duplikaty odwołań do klas są ponownie wykorzystywane przez różne części aplikacji (lub jak radzić sobie ze zduplikowanymi instancjami, jeśli taka jest semantyka)?
Po przyjrzeniu się temu napotkałem wiele problemów z zależnościami, prawidłowym określaniem zakresu i problemami z inicjalizacją. W końcu napotykasz problemy, które czynią „klasy najwyższego poziomu” specjalnymi, i wiele ograniczeń, które sprawiają, że działają, co ostatecznie kształtuje je w proste przestrzenie nazw.
źródło
Object
. Zdaję sobie sprawę, że prawdopodobnie potrzebuję do tego specjalnego zachowania, ale tak długo, jak to jest izolowany przypadek, nie mam nic przeciwko. Nie sądzę jednak, że będę miał problemy z zależnościami. Istnieje zestaw klas, które są ładowane podczas uruchamiania maszyny Wirtualnej, niektóre z nich są implementowane natywnie (klasa System), ale wszystkie dziedziczą z Object. Gdy wszystko zostanie załadowane, KVM ładuje klasę, którą załadowano, i oblicza zależności. Jestem jednak zainteresowany, jakie problemy wprowadzają statykę?object
, mam na myśli klasy, które zachowują się jak moduły, a nie klasy wewnętrzne, które niekoniecznie są publiczne poza jednostką kompilacji. „Rozpracowuje zależności” zamienia się w gniazdo gigantycznego szerszenia w szczegółach, jeśli chcesz mieć jakiekolwiek zachowanie w stylu DLL; ymmv. Co do statycznego .Math
klasy, która w rzeczywistości jest modułem z metodami statycznymi i wywoływanym stałym podwójnym elementem statycznymPi
.Zamiast odpowiedzieć na to pytanie, przejdę o jeden poziom wyżej i zasugeruję studiowanie MIT OpenCourseWare , zwłaszcza 6.035 (inżynieria języka komputerowego). Wyjaśni to całą problematykę, abyś nie miał ochoty ponownie zadawać takich pytań.
Inżynieria języka komputerowego
Jedynym warunkiem wstępnym jest Java.
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-035-computer-language-engineering-spring-2010/lecture-notes/
Opis kursu
Kurs analizuje problemy związane z implementacją języków programowania wyższego poziomu. Omawiane tematy obejmują: podstawowe pojęcia, funkcje i struktury kompilatorów, interakcję teorii i praktyki oraz wykorzystanie narzędzi do budowania oprogramowania. Kurs obejmuje wieloosobowy projekt dotyczący projektowania i wdrażania kompilatora.
źródło