Czy jest jakiś mechanizm, który uczyniłby język programowania bardziej stabilnym (kompatybilnym) dla zmian?

14

Istnieje duża liczba języków programowania. Niektóre z nich dorastają i stają się bardzo popularne. Ludzie coraz częściej używają takich języków. Założyciel takiego języka (lub organizacja / społeczność założycielska) może próbować wprowadzić zmiany w celu ulepszenia języka. Ale czasami trudno jest wprowadzić pewne zmiany z powodu wstecznej kompatybilności, a takie brzydkie rzeczy istniały już w języku od lat i są używane przez wielu użytkowników.

Czy istnieją jakieś zasady lub kroki architektoniczne na etapie projektowania języka, które mogą pomóc w uczynieniu go bardziej stabilnym, aby projektanci języków nie bali się złamać wstecznej kompatybilności?

Wiaczesław Kondratiuk
źródło
2
stabilność języka wyklucza dokonywanie jakichkolwiek przełomowych zmian. Czy możesz wyjaśnić swoje pytanie?
Simon Bergot,
Bardziej stabilny oznacza dla mnie mniej zmian (mam nadzieję, że nie są one konieczne), co jest dokładnym przeciwieństwem zmian niezgodnych wstecz. Czym jesteś zainteresowany lub pytasz o oba na wpół niezależnie?
@ Simon, jak zaprojektować język, w którym podczas próby dodania nowej funkcji nie boisz się ograniczyć porównywalności
Viacheslav Kondratiuk
@ delnan pozwala powiedzieć, oba.
Viacheslav Kondratiuk
@viakondratiuk Nie bój się nie jest czymś, co może zmienić wygląd języka. Lepszym pytaniem może być „Jak zaprojektować język, aby dodanie nowych funkcji nie powodowało przełomowych zmian ?”.
svick,

Odpowiedzi:

6

Stabilność języka nie jest decyzją techniczną. Jest to umowa między autorem języka a użytkownikami.

Autor reklamuje daną wersję jako mniej lub bardziej stabilną. Im mniej stabilny jest język, tym więcej zmian może wprowadzić autor. Każdy użytkownik zainteresowany tym językiem może zdecydować, czy chce poświęcić na to czas, aby nauczyć się nowych funkcji lub opracować aplikacje, które mogą ulec uszkodzeniu w wyniku aktualizacji w przyszłym miesiącu.

Używanie niestabilnego języka może być interesujące, ponieważ interesuje Cię nowa koncepcja lub chcesz pomóc, przekazując swoją opinię. Jeśli jesteś firmą, możesz poczekać, aż technologia będzie bardziej stabilna, zanim zainwestujesz w nią swój czas. Dbasz o rzeczy takie jak czas na marketing i wrażenia użytkowników.

To jest kwestia komunikacji i zaufania. Spójrz na rozwój języka rdzawego. Są krystalicznie jasne o tym, co zmieniają i co trzymają. Kiedy chcą opóźnić decyzję dotyczącą danej funkcji, używają tego, co nazywają bramą funkcji. Z drugiej strony zespół Angular spotkał się z dużym gniewem w związku z ogłoszeniem 2.0, ponieważ zmiany były większe niż oczekiwano.

Nawet autor bibliotek musi komunikować się o stabilności api. Prawie każda technologia używana przez innych ludzi musi znaleźć równowagę między stabilnością a doskonałością. Producent samochodów nie może zmienić położenia pedałów, a projektant laptopa nie wymyśli nowego układu klawiatury z tego samego powodu: nie pomagasz użytkownikom, jeśli nie możesz podjąć decyzji o sposobie korzystania z Twojego produktu.

Simon Bergot
źródło
5
  • Pamiętaj, że języki zmieniają się przez całe życie, niezależnie od tego, jak dobrze można je zaprojektować z góry. Zamiast próbować natychmiast wysłać najbardziej niesamowity język na ziemi, najpierw spróbuj być użyteczny i rozszerzalny. Przeciętny miernik, którego faktycznie mogę używać, jest wart więcej niż każdy wspaniały język programowania, który istnieje tylko w teorii.
  • Rozważ ułatwienia, aby składnia była rozszerzalna, np. Makra. Makra nie są automatycznie dobrą rzeczą i mogą być zbyt potężne. Niektóre języki mają bardzo elastyczną składnię od samego początku, co zmniejsza zapotrzebowanie na makra. Kilka scenariuszy do rozważenia:

    • Czy mogę wprowadzić nowego operatora, na przykład |>bez opuszczania języka? Czy mogę wybrać pierwszeństwo i powiązanie dla tego operatora?
    • Jaką ceremonię muszę przejść dla funkcji inline / lambda / zamknięcia?
    • Czy mogę użyć istniejącej składni języka do implementacji składni pętli foreach? Na przykład Ruby i Scala mogą to zrobić za pomocą elastycznej składni wywołania metody za pomocą lambdas.
  • Rozważ ułatwienia, aby semantyka była rozszerzalna. Typowe potrzeby to:

    • Przeciążenie operatora, w którym typy zdefiniowane przez użytkownika mogą przypisywać własne znaczenie istniejącym operatorom. Dzięki temu język jest znacznie przyjemniejszy w aplikacjach wymagających matematyki.
    • Dosłowne przeciążenie. Czy mogę sprawić, by literały ciągów były mojego własnego typu? Czy mogę sprawić, że wszystkie literały liczbowe w bieżącym zakresie będą bignum?
    • Protokoły Metaobject. Jeśli język nie ma cech, czy mogę je zaimplementować w bieżącym systemie obiektowym? Czy mogę zaimplementować inną kolejność rozwiązywania metod? Czy mogę zmienić sposób przechowywania obiektów lub wysyłania metod?
  • Przeprowadzić testy regresji. Dużo testów. Napisane nie tylko przez projektantów języka, ale także przez użytkowników. Podczas dodawania funkcji przerywa te testy, należy dokładnie rozważyć zalety tej funkcji w porównaniu z korzyściami wynikającymi z kompatybilności wstecznej.
  • Wersja swojego języka. Nie tylko w twojej dokumentacji, ale także w samym kodzie źródłowym. Gdy to zrobisz, jedyną częścią twojego języka, która nie może się zmienić, jest ta wersja składni pragma. Przykłady: Rakieta pozwala określić dialekt. Perl pozwala na to use v5.20, co włącza wszystkie niezgodne wstecz funkcje Perla v5.20. Możesz także załadować pojedyncze funkcje, które jawnie lubią use feature 'state'. Podobne: Python's from __future__ import division.
  • Rozważ zaprojektowanie swojego języka w taki sposób, aby uzyskać kilka zastrzeżonych słów. To, że classwprowadza klasę, nie oznacza, że ​​nie byłbym w stanie mieć zmiennej lokalnej o nazwie class. W praktyce skutkuje to słowami kluczowymi, które wprowadzają deklaracje zmiennych lub metod, co jest sprzeczne z tradycją C polegającą na stosowaniu nazw typów do wprowadzania deklaracji. Inną alternatywą jest użycie sigils dla twojego $variables, tak jak w Perlu i PHP.

Częścią tej odpowiedzi jest przemówienie Guya Steele'a „Growing a Language” (1998) ( pdf ) ( youtube ).

amon
źródło
Niektóre z twoich punktów mówią o tym, że programiści używający języka mogą go rozszerzyć, a niektórzy mówią o projektantach języka, którzy mogą go rozszerzyć. Czy te dwa nie są w większości niezwiązane? I myślę, że pytanie dotyczy tego drugiego rodzaju.
svick,
@svick Chodzi o to, że język jest tak rozszerzalny dla użytkowników końcowych, że można przeprowadzić wiele rozszerzeń i eksperymentów bez zmiany samego języka. Protokoły Metaobject, przeciążenie operatora i systemy makro są sposobem na pozostawienie otwartych drzwi na późniejsze zmiany. Wszystko, co jest realizowane przez te drzwi, zasadniczo nie psuje języka. Niestety, same drzwi mogą później zostać przeprojektowane. Właśnie tam pojawia się przesłanka odpowiedzi Simona: zanim obiecujesz stabilność, przeprowadź testy beta, aby dowiedzieć się, czy Twój język rzeczywiście działa.
amon
1

Myślę, że dość ważnym krokiem jest wypromowanie menedżera pakietów, który może również zarządzać wersją samego języka.

Na przykład używam SBT dla Scali lub Leiningen dla Clojure. Oba pozwalają mi zadeklarować, której wersji języka chcę używać, każdego projektu . Łatwo więc rozpocząć ekologiczne projekty w najnowszej wersji języka, jednocześnie aktualizując istniejące projekty w bardziej komfortowym tempie, jeśli w ogóle.

Oczywiście, w zależności od języka, może to nadal powodować konieczność oczekiwania na przeniesienie odpowiednich bibliotek do potrzebnej wersji (dzieje się tak na przykład w Scali), ale mimo to ułatwia.

Andrea
źródło
z konsekwencją, że w pakietach / modułach, które można importować, należy zdefiniować jak najwięcej języka
jk.
Tak, ale niekoniecznie. Na przykład, kompilator Scali jest napisany w Scali, ale kiedy ustawisz wersję Scala w sbt, jest ona po prostu pobierana jako Jar i używana do kompilacji źródeł. Nawet jeśli byłby to nieprzejrzysty plik binarny, to też by się udało. Istnieją powody, by zdefiniować jak najwięcej języka, który powinien być zdefiniowany w pakietach do importowania, ale są one objęte odpowiedzią amona
Andrea