
Filozofia przewodnia
1. Języki programowania dla ludzi
Języki programowania umożliwiają ludziom komunikację z komputerami. Komputer z przyjemnością będzie mówił w każdym języku, który nie jest dwuznaczny. Powodem, dla którego mamy języki wysokiego poziomu, jest to, że ludzie nie potrafią obsługiwać języka maszynowego. Celem języków programowania jest ochrona naszego biednego, kruchego ludzkiego mózgu przed przytłoczeniem mnóstwem szczegółów.
Architekci wiedzą, że niektóre problemy projektowe są bardziej przyziemne niż inne. Jednym z najwyraźniejszych i najbardziej abstrakcyjnych problemów projektowych jest projektowanie mostów. W tym przypadku Twoim zadaniem jest pokonanie wymaganego dystansu, wykorzystując jak najmniej materiału. Na drugim końcu spektrum znajduje się projektowanie krzeseł. Projektanci krzeseł powinni pomyśleć także o ludzkich pośladkach.
Podobna różnica dotyczy tworzenia oprogramowania. Projektowanie algorytmów do kierowania danymi w sieci to ciekawy, abstrakcyjny problem, podobny do projektowania mostów. Natomiast projektowanie języków programowania przypomina projektowanie krzeseł: trzeba radzić sobie ze słabościami człowieka.
Większości z nas trudno to zaakceptować. Projektowanie eleganckich systemów matematycznych wydaje się większości z nas o wiele bardziej atrakcyjne niż uleganie ludzkim słabościom. Rola matematycznej elegancji polega na tym, że pewien stopień elegancji sprawia, że programy są łatwiejsze do zrozumienia. Ale elegancja na tym się nie kończy.
A kiedy mówię, że języki powinny być projektowane z uwzględnieniem ludzkich słabości, nie mam na myśli, że języki powinny być projektowane dla złych programistów. Prawda jest taka, że oprogramowanie należy tworzyć dla najlepszych programistów, ale nawet najlepsi programiści mają swoje ograniczenia. Nie sądzę, żeby komukolwiek podobało się programowanie w języku, w którym wszystkie zmienne byłyby reprezentowane przez literę „x” z indeksami całkowitymi.
2. Zaprojektuj dla siebie i swoich przyjaciół
Jeśli przyjrzymy się historii języków programowania, zauważymy, że większość najlepszych języków została zaprojektowana do użytku przez ich autorów, a większość najgorszych języków została zaprojektowana dla innych osób.
Kiedy języki są projektowane dla innych ludzi, zawsze chodzi o określoną grupę ludzi: ludzi, którzy nie są tak inteligentni, jak twórcy danego języka. Dzięki temu otrzymujesz język, który do ciebie przemawia. Najbardziej znanym przykładem jest Cobol, ale większość języków jest przesiąknięta tym duchem.
Nie ma to nic wspólnego z poziomem zaawansowania języka. Język C jest językiem dość niskopoziomowym, ale został stworzony do użytku przez jego autorów, dlatego hakerzy go uwielbiają.
Argumentem za projektowaniem języków dla złych programistów jest to, że złych programistów jest więcej niż dobrych. Być może tak jest. Jednak ta niewielka grupa dobrych programistów pisze nieproporcjonalnie więcej oprogramowania.
Interesuje mnie pytanie, w jaki sposób możemy stworzyć język, który spodoba się najlepszym hakerom? Sądzę, że to pytanie jest identyczne z pytaniem o to, jak stworzyć dobry język programowania. Nawet jeśli nie jest, to jest to przynajmniej ciekawe pytanie.
3. Daj programiście jak największą kontrolę
Wiele języków (zwłaszcza tych stworzonych dla innych ludzi) pełni funkcję niańki: próbuje ostrzegać przed rzeczami, które ich zdaniem mogą być dla ciebie złe. Ja mam przeciwne zdanie: daj programiście jak największą kontrolę.
Kiedy uczyłem się Lispa, najbardziej podobało mi się to, że rozmawialiśmy jak równi sobie. W pozostałych językach, których nauczyłem się do tego czasu, istniał język i mój program w tym języku, i istniały one zupełnie niezależnie. Ale w Lispie funkcje i makra, które napisałem, były tymi samymi, w których napisany był sam język. Mógłbym przepisać sam język, gdybym chciał. Miało taki sam urok jak oprogramowanie typu open source.
4. Zwięzłość jest siostrą dowcipu
Zwięzłość jest niedoceniana, a nawet pogardzana. Jeśli jednak zajrzysz w serca hakerów, zobaczysz, że bardzo lubią zwięzłość. Ile razy słyszałeś hakerów z rozrzewnieniem opowiadających, jak na przykład w APL potrafią zdziałać cuda, pisząc zaledwie kilka linijek kodu? Myślę, że naprawdę inteligentni ludzie naprawdę chcą zwracać na to uwagę.
Uważam, że niemal wszystko, co skraca programy, jest dobre. Powinno być wiele funkcji bibliotecznych, wszystko co może być ukryte powinno takie być; składnia powinna być bardziej zwięzła; Nawet nazwy podmiotów powinny być krótkie.
Ale nie tylko programy powinny być krótkie. Instrukcje również powinny być krótkie. Duża część podręczników jest wypełniona wyjaśnieniami, zastrzeżeniami, ostrzeżeniami i przypadkami szczególnymi. Jeśli musisz skrócić instrukcję, najlepszym rozwiązaniem będzie poprawienie języka, który wymaga wielu wyjaśnień.
5. Rozpoznaj, czym jest hakowanie
Wiele osób chciałoby, aby hakowanie było matematyką lub przynajmniej czymś w rodzaju nauki. Myślę, że hakowanie jest bardziej jak architektura. Architektura jest związana z fizyką w tym sensie, że architekt musi zaprojektować budynek, który się nie zawali, ale prawdziwym celem architekta jest stworzenie wspaniałego budynku, a nie dokonywanie odkryć w dziedzinie statyki.
Hakerzy uwielbiają tworzyć świetne programy. I myślę, że przynajmniej w naszych umysłach powinniśmy pamiętać, że pisanie świetnych programów jest świetne, nawet jeśli nasza praca nie przekłada się łatwo na zwykłą intelektualną walutę prac naukowych. Z intelektualnego punktu widzenia, zaprojektowanie języka, który kochają programiści, jest tak samo ważne, jak zaprojektowanie języka okropnego, który ucieleśnia ideę, na temat której można opublikować pracę naukową.
Otwarte problemy
1. Jak zorganizować duże biblioteki?
Biblioteki stają się ważną częścią języków programowania. Stają się tak duże, że może to być niebezpieczne. Jeśli znalezienie funkcji w bibliotece, która wykonuje to, czego potrzebujesz, zajmuje więcej czasu niż napisanie tej funkcji samodzielnie, to jedyny efekt takiego kodu to pogrubienie podręcznika. (Podręczniki Symbolics są tego przykładem.) Musimy więc rozwiązać problem organizacji biblioteki. Najlepiej byłoby je zaprojektować tak, aby programista mógł odgadnąć, która funkcja biblioteczna zadziała.
2. Czy ludzie naprawdę boją się składni prefiksów?
Jest to problem otwarty w tym sensie, że myślę o nim od kilku lat i wciąż nie znam odpowiedzi. Składnia prefiksu wydaje mi się zupełnie naturalna, z wyjątkiem jego zastosowania w matematyce. Ale być może duża część niepopularności Lispa wynika po prostu z nieznanej składni... Czy należy coś z tym zrobić, to już inna kwestia.
3. Czego potrzebujesz do oprogramowania serwerowego?
Sądzę, że większość aplikacji, które zostaną napisane w ciągu najbliższych dwudziestu lat, będą aplikacjami internetowymi, w tym sensie, że programy będą umieszczone na serwerze i będą komunikować się z użytkownikiem za pomocą przeglądarki internetowej. A żeby pisać takie aplikacje potrzebujemy czegoś nowego.
Jedną z takich rzeczy jest obsługa nowego sposobu udostępniania aplikacji serwerowych. Zamiast jednej lub dwóch głównych wersji rocznie, jak w przypadku oprogramowania na komputery stacjonarne, oprogramowanie na serwery będzie wydawane w serii małych zmian. Możesz mieć pięć lub dziesięć wydań dziennie. I każdy zawsze będzie miał najnowszą wersję.
Czy wiesz, jak projektować programy, aby były łatwe w utrzymaniu? Oprogramowanie serwera musi być zaprojektowane w sposób umożliwiający zmianę. Powinieneś móc łatwo zmienić tę zmianę, albo przynajmniej wiedzieć, co oznacza mała zmiana i co jest ważne.
Kolejną rzeczą, która może być użyteczna w oprogramowaniu serwerowym, jest nagła ciągłość dostarczania. W aplikacji internetowej możesz użyć czegoś takiego aby uzyskać efekt procedur w bezstanowym świecie sesji internetowych. Zapewnienie ciągłości dostaw może być warte zachodu, jeśli opcja ta nie jest zbyt kosztowna.
4. Jakie nowe abstrakcje pozostają do odkrycia?
Nie jestem pewien, czy ta nadzieja jest uzasadniona, ale osobiście bardzo chciałbym odkryć nową abstrakcję – coś, co mogłoby zrobić tyle samo, co funkcje pierwszej klasy, rekurencja, a przynajmniej parametry domyślne. Być może jest to marzenie niemożliwe do spełnienia. Tego typu rzeczy często pozostają nieotwarte. Ale nie tracę nadziei.
Mało znane sekrety
1. Możesz używać dowolnego języka.
Wcześniej tworzenie aplikacji oznaczało tworzenie oprogramowania na komputery stacjonarne. W przypadku oprogramowania na komputery stacjonarne istnieje duża tendencja do pisania aplikacji w tym samym języku, w którym działa system operacyjny. Tak więc dziesięć lat temu pisanie oprogramowania oznaczało zazwyczaj pisanie programów w języku C. Z czasem tradycja ta ewoluowała: aplikacje nie muszą być pisane w skomplikowanych językach. Tradycja ta rozwijała się przez tak długi czas, że przyswoili ją sobie również ludzie bez wykształcenia technicznego, np. menedżerowie i inwestorzy venture capital.
Oprogramowanie po stronie serwera całkowicie niszczy ten model. Dzięki niemu możesz używać dowolnego języka. Prawie nikt jeszcze tego nie rozumie (zwłaszcza menedżerowie i inwestorzy venture capital). Ale niektórzy hakerzy to rozumieją, dlatego słyszymy o językach niezależnych, takich jak Perl i Python. Nie słyszymy o Perlu i Pythonie, ponieważ ludzie używają ich do pisania aplikacji. Windows.
Dla nas, osób zainteresowanych projektowaniem języków programowania, oznacza to, że nasza praca ma potencjalnych odbiorców.
2. Prędkość pochodzi od profilerów
Projektanci języków, a przynajmniej osoby wdrażające języki, lubią pisać kompilatory, które generują szybko kod. Ale nie sądzę, żeby to miało wpływ na szybkość nauki języków dla użytkowników. Knuth już dawno zauważył, że prędkość zależy od kilku wąskich gardeł. Każdy, kto próbował przyspieszyć działanie programu, wie, że nie sposób zgadnąć, gdzie znajduje się wąskie gardło. Odpowiedzią jest Profiler.
Projektanci języków rozwiązują niewłaściwy problem. Użytkownicy nie potrzebują testów porównawczych, aby działać szybko. Potrzebują języka, który będzie w stanie wskazać, które części programu należy przepisać. W tym momencie w praktyce najważniejsza jest szybkość. Być może więc lepiej byłoby, gdyby osoby wdrażające języki poświęcały połowę czasu, jaki poświęcają na optymalizację kompilatora, a na napisanie dobrego profilera.
3. Potrzebujesz aplikacji, która pomoże Ci rozwinąć język
Być może nie jest to ostatnie słowo, ale wygląda na to, że najlepsze języki ewoluowały wraz z aplikacjami, które ich używały. Język C został napisany przez osoby, którym zależało na programowaniu systemowym. Lisp został zaprojektowany częściowo z myślą o symbolicznym różniczkowaniu, a McCarthy był tak zdeterminowany, aby zacząć, że zaczął pisać programy różniczkujące już w pierwszym artykule na temat Lispa w 1960 roku.
Jest to szczególnie przydatne, jeśli Twoja aplikacja rozwiązuje jakiś nowy problem. Dzięki temu Twój język zyskuje nowe funkcje, których oczekują programiści. Osobiście jestem zainteresowany napisaniem języka, który sprawdzi się w aplikacjach serwerowych.
[Podczas dyskusji Guy Steele również poruszył ten temat, dodając, że aplikacja nie powinna polegać na pisaniu kompilatora dla danego języka, chyba że dany język jest zaprojektowany do pisania kompilatorów.]
4. Język powinien nadawać się do pisania jednorazowych programów.
Wiesz, co oznacza program jednorazowy: ma miejsce wtedy, gdy musisz szybko rozwiązać jakieś ograniczone zadanie. Myślę, że jeśli się rozejrzysz, znajdziesz mnóstwo poważnych programów, które zaczęły się jako jednorazowe przedsięwzięcia. Nie zdziwiłbym się, gdyby większość programów zaczynała jako jednorazowe przedsięwzięcia. Jeśli więc chcesz stworzyć język nadający się do pisania oprogramowania w ogólności, to powinien on się również nadawać do pisania programów jednostkowych, ponieważ jest to początkowy etap wielu programów.
5. Składnia jest związana z semantyką
Tradycyjnie składnię i semantykę uważa się za zupełnie różne rzeczy. Może to brzmieć szokująco, ale tak nie jest. Myślę, że to, co chcesz osiągnąć w swoim programie, zależy od sposobu, w jaki to wyrazisz.
Niedawno rozmawiałem z Robertem Morrisem, który zauważył, że przeciążanie operatorów jest dużą zaletą języków ze składnią infiksową. W językach ze składnią prefiksową każda zdefiniowana funkcja jest w rzeczywistości operatorem. Jeśli chcesz dodać nowy typ liczby, którą wymyśliłeś, możesz po prostu zdefiniować nową funkcję, aby go dodać. Jeśli zrobisz to w języku ze składnią infiksową, zobaczysz, że jest duża różnica między użyciem przeciążonego operatora a wywołaniem funkcji.
Pomysły, które powracają z czasem
1. Nowe języki programowania
Patrząc wstecz na lata 1970. XX wieku, modne było tworzenie nowych języków programowania. Teraz już tak nie jest. Ale wierzę, że oprogramowanie serwerowe sprawi, że moda na tworzenie nowych języków powróci. W przypadku oprogramowania serwerowego można używać dowolnego języka, więc jeśli ktoś stworzy język, który wyda się lepszy od innych, znajdą się osoby, które zdecydują się go używać.
2. Podział czasu
Richard Kelsey wpadł na ten pomysł, którego czas znów nadszedł i w pełni go popieram. Moim zdaniem (i obstawiam również Microsoft), że znaczna część obliczeń zostanie przeniesiona z komputerów stacjonarnych na serwery zdalne. Innymi słowy, podział czasu powraca. Myślę, że trzeba będzie to wspierać na poziomie językowym. Na przykład Richard i Jonathan Reeves włożyli wiele pracy w wprowadzenie harmonogramowania procesów do Schematu 48.
3. Wydajność
Ostatnio wydawało się, że komputery są wystarczająco szybkie. Coraz częściej słyszymy o kodzie bajtowym, co, przynajmniej dla mnie, oznacza, że mamy zapas mocy. Ale myślę, że w przypadku oprogramowania serwerowego go nie mamy. Ktoś będzie musiał za to zapłacić. serwery, na którym działa oprogramowanie, a liczba użytkowników, jaką serwer może obsłużyć na jedną maszynę, będzie dzielnikiem ich kosztów kapitałowych.
Myślę, że wydajność będzie miała znaczenie, przynajmniej w przypadku wąskich gardeł obliczeniowych. Będzie to szczególnie ważne w przypadku operacji wejścia/wyjścia, ponieważ aplikacje serwerowe wykonują wiele takich operacji.
Na koniec może się okazać, że bajtkod nie jest odpowiedzią. Sun i Microsoft najwyraźniej obecnie konkurują ze sobą na polu kodu bajtowego. Robią tak jednak dlatego, że bajtkod jest wygodnym miejscem do osadzenia go w procesie, a nie dlatego, że bajtkod sam w sobie jest dobrym pomysłem. Może się okazać, że cała ta bitwa pozostanie niezauważona. Byłoby zabawnie.
Pułapki i wpadki
1. Klienci
To tylko przypuszczenie, ale istotne jest to, że skorzystają na tym tylko te aplikacje, które w całości bazują na serwerze. Projektowanie oprogramowania, które opiera się na założeniu, że każdy będzie Twoim klientem, jest jak projektowanie społeczeństwa bazującego na założeniu, że wszyscy będą uczciwi. Z pewnością byłoby to wygodne, ale trzeba by się pogodzić z tym, że nigdy by się to nie zdarzyło.
Sądzę, że liczba urządzeń z dostępem do Internetu będzie szybko rosła i można śmiało założyć, że będą one obsługiwać podstawowy kod HTML i formularze. Czy masz przeglądarkę w telefonie? Czy Twój PalmPilot będzie miał telefon? Czy Twój BlackBerry będzie miał większy ekran? Czy będziesz mieć dostęp do Internetu ze swojego Game Boya? Z zegarka? Nie wiem. I nie będę musiał się o tym dowiadywać, jeśli obstawię, że wszystko będzie na serwerze. O wiele bardziej niezawodne jest umieszczenie wszystkich mózgów na serwerze. .
2. Programowanie obiektowe
Zdaję sobie sprawę, że to kontrowersyjne stwierdzenie, ale nie sądzę, żeby OOP było czymś wielkim. Myślę, że jest to odpowiedni paradygmat dla konkretnych zastosowań, które wymagają konkretnych struktur danych, takich jak systemy okienkowe, symulacje, systemy CAD. Ale nie widzę powodu, dla którego miałoby to być odpowiednie dla wszystkich programów.
Myślę, że ludzie w dużych firmach lubią programowanie obiektowe częściowo dlatego, że dzięki niemu wiele rzeczy wygląda jak praca. To, co w naturalny sposób można przedstawić na przykład jako listę liczb całkowitych, można teraz przedstawić jako klasę z różnego rodzaju rusztowaniami, niosąc ze sobą sporo hałasu i zamieszania.
Kolejną atrakcyjną cechą programowania obiektowego jest to, że metody dają pewien efekt funkcji pierwszorzędnych. Ale dla programistów Lispa nie jest to żadna nowość. Gdy dysponujesz prawdziwymi funkcjami pierwszorzędnymi, możesz po prostu używać ich w dowolny sposób odpowiadający zadaniu, zamiast umieszczać wszystko w szablonie klas i metod.
Myślę, że dla projektowania języków oznacza to, że nie należy zbyt głęboko wbudowywać programowania obiektowego. Być może odpowiedzią jest oferowanie bardziej ogólnych, podstawowych rozwiązań i umożliwienie ludziom projektowania dowolnych systemów obiektowych jako bibliotek.
3. Projektowanie przez komitet
Jeśli twój język został zaprojektowany przez komisję, jesteś w pułapce, i to nie tylko z powodów, które są wszystkim znane. Powszechnie wiadomo, że komisje mają tendencję do tworzenia niejednolitych i niespójnych projektów językowych. Ale myślę, że największym niebezpieczeństwem jest to, że nie podejmują ryzyka. Kiedy jedna osoba jest odpowiedzialna, podejmuje ryzyko, na jakie komisja nigdy by się nie zgodziła.
Czy trzeba podejmować ryzyko, aby stworzyć dobry język? Wiele osób może podejrzewać, że projektowanie języka to dziedzina, w której należy trzymać się konwencjonalnych zasad. Założę się, że to nieprawda. We wszystkim, co robią ludzie, nagroda jest proporcjonalna do ryzyka. Dlaczego więc projektowanie języka miałoby być inne?
Źródło: www.habr.com
