Gdybyś zaprojektował język programowania, jak byś to zrobił? Jakie funkcje byś wprowadził? Co byś pominął? Pisanie statyczne czy dynamiczne? Mocno czy słabo napisane? Skompilowane lub zinterpretowane? Uzasadnij swoje odpowiedzi.
Gdybyś zaprojektował język programowania, jak byś to zrobił? Jakie funkcje byś wprowadził? Co byś pominął? Pisanie statyczne czy dynamiczne? Mocno czy słabo napisane? Skompilowane lub zinterpretowane? Uzasadnij swoje odpowiedzi.
Odpowiedzi:
Zdecydowanie uważam, że funkcjonalne języki programowania się zaakceptują, więc mój język będzie funkcjonalny. Zobacz efekty oswajania za pomocą programowania funkcjonalnego
Myślę, że procesory wkrótce będą miały setki rdzeni, a wątkom będzie do cholery zarządzać. Zatem model aktora jest koniecznością zamiast wątków. Zobacz Erlang - oprogramowanie dla współczesnego świata
Myślę też, że OOP nie powiodło się, założono, że komunikacja między obiektami jest asynchroniczna . Myślę więc, że potrzebujemy przekazywania wiadomości z niezmiennymi wiadomościami. Wyślij i zapomnij. Jak w modelu Actor. Zobacz Programowanie obiektowe: zła ścieżka?
Myślę, że dobrze byłoby mieć pisanie statyczne , więc błędy są wychwytywane wcześniej w cyklu programowania. Ale użyłbym wnioskowania typu jak w Haskell, aby deweloper nie musiał pisać tego typu wszędzie w kodzie, jak w C, C # i Javie. Zobacz: Learn You A Haskell for Great Good
Zaprojektowałbym też świetną bibliotekę interfejsu użytkownika , z deklaratywnym układem , tak jak w WPF i Androidzie. Ale chciałbym mieć to tak, jak w Funkcjonalnym Programowaniu Reaktywnym .
Mój język byłby więc jak współbieżność w Erlangu, ale z pisaniem jak w Haskell i strukturą GUI jak w WPF.NET.
Uwaga: Użyłem składni podobnej do C do opisania funkcji w tym poście, ale nie jestem wybredny w samej składni, o ile nie jest to coś śmiesznego, jak wszystkie słowa kluczowe będące CAPS.
1. System pisania
Najważniejszą funkcją, której chciałbym w danym języku, jest pisanie statyczne z opcjonalnym pisaniem dynamicznym. Powodem jest to, że pisanie statyczne pozwala a) wcześnie wychwytywać błędy, a nie późno, oraz b) większość kodu jest domyślnie wpisywana statycznie, niezależnie od tego, czy język je rozróżnia. Istnieje jednak kilka przypadków użycia, w których dynamiczne pisanie jest niezwykle przydatne. Na przykład podczas odczytu danych z pliku często masz pola różnych typów, a dynamiczne pisanie ułatwia heterogeniczne kontenery. Tak więc mój idealny język miałby coś takiego:
//variable declarations
int anInt = 42 //anInt is now irrevocably an integer and assigning another type to it is an error
vartype aVariable = 42 //aVariable is currently an integer, but any type can be assigned to it in the future
//function definitions
int countElements(Collection c)
{
return c.count();
}
//c HAS to be a collection, since countElements doesn't make sense otherwise
void addToCollection(Collection& c, vartype v)
{
c.append(v)
}
//c is passed by reference here
2. Opracowane a zinterpretowane
Chciałbym, aby język był albo skompilowany z wyprzedzeniem, albo JIT skompilowany, ale nie wyłącznie interpretowany, ponieważ powodem jest szybkość. Jest to związane z punktem 1 , ponieważ optymalizujący kompilator / jitter będzie miał znacznie łatwiejszy czas na optymalizację kodu o typie statycznym, a kod o typie dynamicznym można po prostu pozostawić bez zmian.
3. Zamknięcia
Język musi obsługiwać konstrukcje programowania funkcjonalnego, a funkcje powinny być obiektami najwyższej klasy.
4. Zorientowany obiektowo
Język powinien umożliwiać pisanie kodu obiektowego, ale powinien być również dozwolony prosty kod imperatywny. tzn. powinno być możliwe napisanie programu hello world takiego:
int main(string<> args=null)
{
printf("hello, world");
return 0;
}
// this code also demonstrates two other features,
// default arguments for functions (not explained further)
// and immutable lists like string<> (see 6. Built-in datatypes)
5. Przestrzenie nazw
Przestrzenie nazw są dobrą rzeczą. Bardzo niewiele rzeczy powinno trafić do globalnej przestrzeni nazw. Ale jeśli musisz umieścić rzeczy w globalnej przestrzeni nazw, możesz (ala C ++).
6. Wbudowane typy danych
Język musi mieć, jako wbudowane typy danych, następujące konstrukcje:
int
lub typy danych. Jeśli jest tylko jeden int
typ, powinien mieć nieograniczony zasięg. Jeśli jest ich więcej, powinno być niejawne upcasting do najmniejszego typu, który jest w stanie utrzymać wynik obliczeń, przy czym typ nieograniczonego zakresu jest największy.float
typ binarny , który jest równoważny z IEEE 754double
list
typ, który jest implementowany jako podwójnie połączona lista lub blok ciągłej pamięci przechowującej wskaźniki do każdego elementulist
typ, który działa jak tablica, ale którego rozmiaru nie można zmienić po utworzeniustring
Typy zmienne i niezmienne , przy czym domyślnie są niezmienne.map
lub dict
typ, który jest zmienny i zawiera niezmienne klucze oraz zmienne i / lub niezmienne wartości.vartype
razie potrzeby mogą być dboolean
typnull
lub none
typ, który można przypisać do zmiennej dowolnego typu.set
typydecimal
Typ, który implementuje zmienne dziesiętnych liczb zmiennoprzecinkowychfixed
Rodzaju, które realizuje szereg stałoprzecinkowychTe decimal
, float
oraz fixed
rodzaje powinny dzielić dokładny sam interfejs publiczny (albo poprzez dziedziczenie lub kaczka wpisywanie), pozwalając im być transparentnie przekazywane i wrócił z funkcji. Można wywołać typ nadrzędny real
.
7. Zadzwoń według wartości i referencji
Powinieneś być w stanie wywoływać funkcje zarówno według wartości, jak i odwołania, przy czym domyślna wartość to (tzn. Kopia argumentu jest tworzona i obsługiwana w funkcji).
8. Wskaźniki
Język powinien mieć wskaźniki i umożliwiać arytmetykę wskaźników. Wskaźniki można wpisywać tylko statycznie (aby uniknąć koszmaru, którym jest a void*
). vartype
wskaźniki są wyraźnie zabronione. Posiadanie wskaźników i arytmetyki wskaźników pozwala na poważne wykorzystanie języka jako języka programowania systemów.
9. Montaż w linii
W związku z 8. Język powinien umożliwiać wstawianie kodu języka asemblera w sytuacjach, gdy jest to konieczne.
10. Bezpieczeństwo
Język powinien być w większości bezpieczny w obsłudze, obsługujący obsługę wyjątków itp. Arytmetyka wskaźnika i wbudowany zestaw mogą być przeniesione do części kodu wyraźnie oznaczonych jako niebezpieczne. Niebezpieczny kod jest dozwolony, ale zdecydowanie odradzany.
11. Nieokreślone zachowanie
Standard językowy powinien określać, jak program ma się zachowywać we wszystkich okolicznościach, z wyjątkiem kodu wyraźnie oznaczonego jako niebezpieczny, tzn. Nie powinno być niezdefiniowanego zachowania poza niebezpiecznymi blokami. Pozwala to na używanie tego języka jako realnego języka programowania aplikacji, a jednocześnie pozwala powiedzieć, napisać w nim system operacyjny.
To wszystko, co mogę teraz wymyślić, ale będę edytować / aktualizować post, gdy będę myśleć o kolejnych rzeczach.
decimal
tutaj typ.
Tak wyglądałby mój wymarzony język programowania:
yield
w Smalltalk? Powinien być tak czysty w użyciu.
Zaprojektowałbym go prawie jak C #, ale Microsoft mnie pobił. :)
(Poza tym, że mój byłby mniej przemyślany i bardziej amatorski.)
Nie mam nic przeciwko temu, czy jest to kompilowane, czy interpretowane, więc nie muszę tego uzasadniać.
W odniesieniu do silnego pisania statycznego trudno mi docenić, dlaczego wymaga to nawet uzasadnienia. Pisanie statyczne to funkcja wychwytująca błędy podczas kompilacji. Pisanie dynamiczne to brak tej funkcji i odracza błędy do czasu uruchomienia. Z mojego osobistego doświadczenia miałem kilka przypadków użycia, w których dynamiczne wysyłanie miało sens i było przydatne, więc zwoje, które musiałem przejść w C # przed 4.0, aby je uzyskać, były łatwo uzasadnione. W wersji C # 4.0 nie muszę nawet tego uzasadniać, ponieważ mamy teraz dynamiczną wysyłkę.
Jednak prawdopodobnie stworzyłbym nową składnię zamiast trzymania się tak religijnie starej składni C, jak C #. Instrukcja switch jest szczególnie okropna, a ja też nie lubię składni obsady (jest to niewłaściwa metoda). Nie kłopoczę się jednak szczegółami składni, więc nie muszę tego szczegółowo wyjaśniać, z wyjątkiem tego, że nie chciałbym, żeby był tak gadatliwy jak Visual Basic.
Co jeszcze chciałbyś, żebym uzasadnił?
Oto lista funkcji, które chciałbym wprowadzić:
Styl Lisp
Plusy :
(eval "your data files")
Wady :
Styl Haskell
Plusy :
Wady :
Styl Python
Plusy :
Realizacja :
Zezwól na przeciążenie funkcji na podstawie typów, podobnych do CL defgeneric
:
(define (+ (a <int>) (b <int>))
(ints-add a b))
(define (+ (a <string>) (b <string>))
(string-concat a b))
(define (+ a b)
(add-generic a b))
Plusy :
Wady :
Styl C.
Plusy :
Wady :
Plusy :
Wady :
Pomyśl o tym, ten mniej więcej określa schemat, z wyjątkiem bitu kompilacji i programowania systemu. Można to obejść, używając libguile i pisząc te bity w C.
car
funkcją i cdr
argumentami, jest obiekt, którego name
pole jest metodą, a którego arguments
pole jest argumentem. Zamiast zagnieżdżania masz pola prev
i next
wskaźnik.)
Istnieje kilka języków, które uważam za cholernie dobre (C # jest moim ulubionym). Ponieważ jest to mój język fantasy, tak naprawdę chcę, aby miał:
Mówię o mnie, bum, ponieważ nie wiem zbyt wiele o projektowaniu języków, ale myślę, że funkcja, o której mówię, nazywa się podpowiedziami w innych językach. Może wskazówki kompilatora ?
Nie wiem, czy przeczytałem to w wersji roboczej Perl6, czy też było wtedy na haju, ale wyobrażam sobie język, w którym wszystko domyślnie jest luźne i logiczne. Ale jeśli chcesz naprawdę zwiększyć wydajność i powiedzieć, hej, ta wartość jest zawsze liczbą całkowitą lub nigdy nie jest zerowa, lub może być równoległa lub jest to bezstanowa, takie rzeczy ... Że kompilator może automatycznie przejść do miasta na tych specjalnie oznaczonych obszarach.
E: Będę wdzięczny za komentarze wyjaśniające, o co proszę, lub przytaczające przykłady, w których już to istnieje.
safety
i speed
, często możesz albo sprawdzić i wymusić kompilator (aby znaleźć problemy), albo założyć, że to, co mówisz, jest prawdą (i skompilować szybszy kod).
Aby wypróbować nowe pomysły:
Zrobiłbym dynamiczny funkcjonalny język programowania, który pozwala wykonywać wszystkie sztuczki wyrażania instrukcji i najprostszą składnię lambda z dopasowaniem wzorca. Włączono regułę zewnętrzną.
// a view pattern (or Active Pattern in F#)
default = \def val: !!val.Type val def
// usage of the pattern
greet = \name<(default "world") `and` hasType Str>:
p "Hello, \{name}!"
(p "Enter your name", .input).greet // (, ) is a sequence expression, returning the last value
Oto wyjaśnienie:
default =
ustawia pamięć, \def val
rozpoczyna funkcję curry z dwoma argumentami, val.Type
jest taki sam jak Type[val]
, !!
konwertuje na wartość logiczną i można zastosować wartość logiczną, więc val
idef are after it.
f x
= f[x]
= x.f
.f
=f[]
i w greet
, użył name<(default "world")
i hasType Str>
, oznacza to, że wzór default "world"
zostanie użyty i związany z name
. Domyślny wzorzec określa wartość domyślną.
and
to kolejny wzór, który łączy ze sobą dwa wzory. default
wzór nie może zabraknąć podczas hasType
może zawieść. W takim przypadku zgłasza wyjątek.
Zmienne są w rzeczywistości magazynami, które można funkcjonalnie przekazywać, a tabele pamięci mogą być referencjami, tworzone i niszczone wraz ze zmianą zakresów.
Hashe i takie będą jak w Lua i JavaScript.
Jeśli mam stworzyć skompilowany język, zrobię F # dla Javy z funkcjami podobnymi do Haskella. Jest to czysto funkcjonalny język, z tą różnicą, że istnieje funkcja, która łączy Cytaty i Wyrazy Comp w celu osiągnięcia programowania imperatywnego poprzez pisanie bloków podobnych do pseudokodu.
Pamiętając, że jedynymi znanymi mi językami są PHP i javascript oraz że naprawdę powinienem nauczyć się jeszcze kilku przed zaprojektowaniem języka:
Składnia: Zastanów się dokładnie nad nazwami funkcji i kolejnością argumentów (tzn. Bądź mniej niechlujny niż PHP).
Cechy:
Posiadają zestaw string
funkcji, które działają na zmiennych jako ciąg bajtów, ale nie rozumieją tekstu, oraz zestaw text
funkcji, które rozumieją wiele kodowań i mogą działać na UTF-8 i innych ciągach wielobajtowych. (I mają wbudowane w język sprawdzanie poprawności kodowania, z funkcją, text.isValidEncoding(text, encoding)
która powie ci, czy sekwencja bajtów jest zniekształcona i niebezpiecznie traktowana jako tekst.
Myślę, że podoba mi się pomysł silnego pisania statycznego, ale nigdy go nie użyłem, więc naprawdę nie mogę powiedzieć.
Przed zaprojektowaniem języka programowania znajdę dobrą odpowiedź na pytanie: dlaczego potrzebujemy jeszcze jednego języka programowania? Kod Rosetta w chwili pisania tego tekstu wymienia 344 języki. Jeśli żadna z nich nie spełniła moich potrzeb, określenie, dlaczego tego nie zrobiły, określałoby punkt początkowy (najbliższe języki) i to, co do niego dodać.
Gdybym wygrał na loterii i z jakiegoś powodu nie miał nic lepszego do roboty, zacznę od Liskell i uczynię go pełnoprawnym językiem w przeciwieństwie do interfejsu GHC, a następnie ułatwię (i zautomatyzuje) FFI, aby móc użyć dowolnego Biblioteka C / C ++.
Dobry język to język, który jest:
Trudno jest zmienić to w listę funkcji, ale myślę, że Programowanie Funkcjonalne, mimo że nie wydaje się naturalne , jest bliższe temu niż programowanie imperatywne (szczególnie w ukrywaniu drobiazgowych szczegółów)
W tej chwili językiem bliższym tej liście jest prawdopodobnie Haskell:
Na twoje pierwsze pytanie: „jak byś to zrobił” - krótka odpowiedź, nie zrobiłbym tego. Nie mam wystarczającej teorii parsera / kompilatora, aby to wyciągnąć. Ale programuję od 25 lat, więc mam kilka pomysłów i opinii, którymi mogę się podzielić.
Po pierwsze, spróbuję wymyślić podejście OOP, które pozwala tworzyć naprawdę połączone modele. Rozumiem przez to, że modele są jedną z najważniejszych rzeczy w prawie każdym projekcie programistycznym - zawsze jest dużo cholernej pracy i ciągłego refaktoryzacji, aby wszystko było w porządku, i winię to za brak prawdziwej łączności w Języki OO.
Pozwól mi pokazać. Powiedzmy, że dom klasy ma właściwość Door.
var door = house.Door;
Masz teraz zmienną lokalną z odniesieniem do instancji Door.
Ale zastanów się, co się właśnie wydarzyło: właśnie zerwałeś Drzwi z Domu, a teraz z przyjemnością przechodzisz dookoła Drzwi, a reszta twojego kodu nie zna faktu, że Drzwi te są w rzeczywistości przymocowane do Domu.
Dla mnie jest to zasadniczo błędne.
I tak, wiem, można to „łatwo” naprawić indywidualnie dla każdego przypadku - w tym przypadku poprzez zachowanie odwrotnego odniesienia od wszystkich drzwi do domu, do którego jest on obecnie przyłączony. To oczywiście otwiera twój model na błędy, ponieważ Twoim obowiązkiem jest dokładnie utrzymywać dwa odwrotne odniesienia, więc ustawiasz właściwości House.Doors i Door.House na prywatne i dodajesz metody takie jak House.AddDoor (), House.RemoveDoor ( ), Door.SetHouse () itp. I połącz to wszystko, a następnie przetestuj urządzenie, aby upewnić się, że rzeczywiście działa.
Czy to nie brzmi jak dużo pracy, aby modelować tak prostą relację? Dużo kodu do utrzymania? Dużo kodu do refaktoryzacji w miarę ewolucji modelu?
Problemem są wskaźniki. Każdy język OO, który widziałem, z natury cierpi na to, że odwołanie do obiektu jest tak naprawdę wskaźnikiem, ponieważ tego właśnie używają komputery.
Wskaźniki nie są dobrym sposobem na modelowanie prawdziwego świata. Niezależnie od tego, jaki świat chcesz modelować, jest prawie pewne, że wszelkie relacje w tym świecie będą relacjami dwukierunkowymi. Wskaźniki wskazują tylko w jednym kierunku.
Chciałbym zobaczyć język, w którym podstawowym modelem danych jest wykres - w którym wszystkie relacje mają domyślnie dwa końce. To prawie na pewno zapewniłoby znacznie bardziej naturalne dopasowanie do modelowania świata rzeczywistego, co jest naprawdę jedyną rzeczą, do której potrzebujemy komputerów. (to i gry wideo.)
Nie mam pojęcia, jak wyglądałaby składnia takiego języka ani czy można go nawet wyrazić za pomocą tekstu. (Zastanawiałem się, czy taki język musiałby być w jakiś sposób graficzny)
Chciałbym również wyeliminować wszystkie formy stanu przypadkowego.
Na przykład przy tworzeniu stron internetowych spędzamy dużo czasu na kształtowaniu danych z baz danych, modeli biznesowych, modeli widoków do prezentacji ... następnie niektóre z tych danych są prezentowane w formularzach, co jest tak naprawdę kolejną transformacją. .. i stan wraca z formularzy, a następnie przekształcamy te dane i rzutujemy je z powrotem na model widoku, np. segregatory modelu widoku i takie ... następnie rzutujemy z modelu widoku z powrotem na model biznesowy model ... następnie używamy mapujących obiektowo-mapujących (lub pomruków) do transformacji danych z modelu widokowego i projekcji na relacyjną bazę danych ...
Czy to zaczyna brzmieć zbędnie? W którym momencie tego całego szaleństwa naprawdę osiągnęliśmy coś pożytecznego? Przez użyteczne mam na myśli coś namacalnego - coś, co użytkownik końcowy może zrozumieć i na czym mu zależy. W końcu godziny spędzone na budowaniu czegoś, co użytkownicy mogą zrozumieć, są naprawdę jedynymi dobrze spędzonymi godzinami. Cała reszta to skutki uboczne.
Chciałbym bardzo dynamicznego języka. Cykl zapisu / kompilacji / uruchamiania jest żmudną stratą czasu. Idealnie, język powinien po prostu dowiedzieć się, co się zmieniło, i w razie potrzeby skompilować / załadować w sposób przezroczysty w tle.
Idealnie byłoby, gdybyś nie musiał nawet naciskać „uruchom” - rzeczy powinny się dziać na ekranie, gdy wprowadzasz zmiany, natychmiast odzwierciedlając wprowadzone zmiany. Problem z cyklem zapisu / kompilacji / uruchamiania, a nawet bardziej bezpośrednim cyklem zapisu / uruchamiania, polega na tym, że jesteś zbyt rozłączony z tym, co robisz - aby czuć się związanym z naszą pracą, potrzebują natychmiastowej informacji zwrotnej, natychmiastowych wyników. Każde czekanie jest za długie!
Znów nie wiem nawet, czy można to osiągnąć za pomocą tradycyjnego IDE, czy też wymagałoby to zupełnie nowego rodzaju interfejsu.
Powinieneś być w stanie używać kombinacji słabego i mocnego pisania, niezależnie od tego, co najbardziej odpowiada problemowi, nad którym pracujesz.
Stan powinien być czymś, co w pełni zarządza językiem. Dlaczego powinieneś polegać na bazie danych w zakresie trwałości? Idealnie, chciałbym móc po prostu określić czas życia dowolnej zmiennej w modelu: jedno żądanie sieciowe, jedna sesja, 24 godziny, na stałe.
Dlaczego musimy wybierać spośród całej gamy rozwiązań pamięci masowej dla różnych mediów i warunków życia? - nie wspominając o transformacji i kształtowaniu danych w celu dopasowania do każdego nośnika; pamięć podręczna przeglądarki, baza danych, pamięć, dysk, kogo to obchodzi! Dane to dane. Miejsce przechowywania danych (i na jak długo) powinno być prostym wyborem, a nie bitwą przeciwko bogom!
Powodzenia z tym.
Prawdopodobnie byłby to język paradygmatu obsługujący następujące elementy:
Dlaczego te Zorientowany obiektowo, ponieważ jest to świetny sposób na organizowanie dużych programów, szczególnie w celu organizowania danych. Ustrukturyzowane, ponieważ nie zawsze tego chcesz / potrzebujesz (OOP), ludzie powinni mieć wybór. Funkcjonalny, ponieważ ułatwia programistom debugowanie i sprawia, że programy są bardziej przejrzyste.
Używałbym modelu Pythona z wciętymi blokami do oznaczania bloków kodu. Jest bardzo clen i miło czytać.
Kradłbym całkiem sporo pomysłów od Pythona, ponieważ Python jest bardzo fajnym językiem. Wziąłbym to za wyciąg i skopiowałem jego mapy, listę i krotki.
Teraz prawdopodobnie nie wziąłbym dynamicznych pojęć z Pythona: po pierwsze, prawdopodobnie byłby typowany w sposób jawny i statyczny. Myślę, że dzięki temu programy stają się bardziej przejrzyste. Zmienne prawdopodobnie wszystkie byłyby obiektami z metodami, wtedy możesz zrobić coś takiego, str.length()
aby uzyskać długość łańcucha. W definicjach funkcji należy określić typ zwracanego argumentu i typy argumentów (obsługując również pewien rodzaj typów ogólnych).
Wróćmy do kopiowania z Pythona ;-). Uwielbiam to sposób na opcjonalne argumenty procedur, więc prawdopodobnie bym to miał. Python nie obsługuje jednak przeciążania procedur, chciałbym tego.
Spójrzmy na zajęcia, porzuciłbym wielokrotne dziedzictwo; łatwe do nadużyć. Zaimplementowałbym zakresy prywatne i podobne i prawdopodobnie zaimplementowałbym to tak, jak to się dzieje w C ++. Miałbym także abstrakcyjne klasy i interfejsy; Nie wierzę, że Python ma to.
Wspierałby klasy wewnętrzne, w rzeczywistości chciałbym bardzo silnego języka obiektowego.
Prawdopodobnie zostanie to zinterpretowane. Możliwe jest uzyskanie go bardzo szybko dzięki dobrej kompilacji JIT (chciałbym szybkiego języka, choć produktywność programisty byłaby na pierwszym miejscu), a kompilacja jest po prostu niekorzystna dla produktywności w wielu przypadkach. Języki interpretowane promują również niezależność platformy, co jest coraz ważniejsze każdego dnia.
Miałby wbudowaną obsługę Unicode; w dzisiejszych czasach internacjonalizacja ma duże znaczenie.
Zdecydowanie byłoby to śmieci. Cholera, nienawidzę samodzielnie zarządzać pamięcią; też nie sprzyja wydajności.
Wreszcie miałby dobrą bibliotekę standardową.
Wow, właśnie zdałem sobie sprawę, jak bardzo kocham Pythona.
Interpreted languages also promote platform independance
? Sądzę, że jest więcej kompilatorów międzyplatformowych, a nie kompilatorów (procent), ale nie mogłem zrozumieć, dlaczego to zdanie powinno być prawdziwe? Myślę, że nie ma między nimi żadnej różnicy, jeśli chodzi o umiejętności na różnych platformach.
Przede wszystkim kupiłbym kilka książek o kompilatorach, kilka standardów i wziął kurs lub dwa w językach i kompilatorach. Chciałbym przyczynić PEP s i odwiedzić C ++ standardów posiedzeniach komisji. Dodałbym łatki do kompilatorów, których używam, mam nadzieję, że zarówno pod kątem funkcji, jak i błędów.
Potem wrócę i z przerażeniem spojrzę na tę listę, którą teraz wymyśliłem, czyli w jakich kierunkach pójdę z językiem, gdybym teraz zaczął:
Widząc, że nawet te dość szerokie kwestie prawdopodobnie szybko by się zmieniły, gdybym zaczął wdrażać język, więc myślę, że wchodzenie w dalsze szczegóły nie jest konieczne.
Gdybym miał czas, zaprojektowałbym lokalizowalny język programowania oparty na Scali, więc miałby większość swoich funkcji, z wyjątkiem prawdopodobnie XML. Moim celem jest stworzenie języka, który będzie czytał prawie naturalnie w językach o innej strukturze niż angielski, takich jak arabski (mój język ojczysty). Mam na myśli następujące funkcje:
#lang
Dyrektywa dotycząca preprocesora , używana do informowania preprocesora o języku ludzkim używanym do programowania. Na przykład: #lang ar
pozwoliłby na użycie tego słowa فئة
zamiast class
, عرف
zamiast def
, i tak dalej. Słowa kluczowe specyficzne dla języka ludzkiego byłyby zdefiniowane w standardowych plikach preprocesora.class MyClass is composed of {
aby się stać class MyClass {
, i „as”, def MyMethod(x: Int) as {
aby się stać def MyMethod(x: Int) {
. W niektórych (ludzkich) językach kod byłby znacznie łatwiejszy do zrozumienia, szczególnie dla studentów.اعرض طول اسم محمد
, co jest równoważne z print(length(name(Mohammad)))
językiem programowania-angielskim. (Nawiasy podano dla przejrzystości).Wierzę, że te minimalne zmiany w preprocesorze i kompilatorze znacznie uprościłyby programowanie osobom nieanglojęzycznym.
print
) Nie zaszkodzi.