Na co zwracają uwagę projektanci języków? [Zamknięte]

38

Celem tego pytania nie jest zebranie listy prania funkcji języka programowania, bez których nie można żyć, lub które nie byłyby dostępne w głównym wybranym języku. To pytanie ma na celu ukazanie kącików obłędnego projektowania, o których większość projektantów języków może nie myśleć. Zamiast więc myśleć o funkcji języka X, pomyśl trochę bardziej filozoficznie.

Jednym z moich uprzedzeń, i być może może być kontrowersyjnym, jest to, że bardziej miękka strona inżynierii - po co i dlaczego - jest wiele razy ważniejsza niż strona bardziej konkretna. Na przykład Ruby został zaprojektowany z myślą o poprawie szczęścia programistów. Chociaż twoje opinie mogą być różne w zależności od tego, czy zostały dostarczone, czy nie, fakt, że był to cel, oznacza, że ​​na niektóre z wyborów w projektowaniu języka wpłynęła ta filozofia.

Nie publikuj:

  • Składniowe wojny płomieniowe. Spójrzmy prawdzie w oczy, mamy swoje preferencje, a składnia jest ważna, ponieważ dotyczy projektowania języka. Chcę tylko uniknąć epickich bitew o naturę emacs vs. VI (o których ogromna liczba ludzi w dzisiejszych czasach nic nie wie).
  • „Jakikolwiek język, który nie ma funkcji X, nie zasługuje na istnienie”, wpisz komentarze. Istnieje co najmniej jeden powód istnienia wszystkich języków programowania - dobry lub zły.

Proszę zrobić wpis:

  • Filozoficzne pomysły, za którymi wydają się tęsknić projektanci języków.
  • Koncepcje techniczne, które wydają się być źle wdrażane częściej niż nie. Podaj przykład bólu, który powoduje, a jeśli masz jakieś wyobrażenie o tym, jak wolałby on działać.
  • Rzeczy, które chciałbyś mieć we wspólnej bibliotece platformy, ale rzadko są. Ten sam token, rzeczy, które zwykle znajdują się we wspólnej bibliotece, których nie chcesz.
  • Funkcje koncepcyjne, takie jak wbudowana obsługa testów / asercji / kontraktów / błędów, które mają być poprawnie wdrażane i definiowane we wszystkich językach programowania.

Mam nadzieję, że będzie to zabawny i stymulujący temat.

Edycja: Wyjaśnienie, co mam na myśli, przez Syntax Flame Wars. Nie staram się unikać wszelkiej dyskusji na temat składni, zwłaszcza że składnia jest podstawową częścią projektowania języka programu.

Berin Loritsch
źródło
Mówienie, że składnia jest tylko szczegółem implementacji, jest po prostu błędne. Projektowanie składni jest fundamentalnie ważną częścią projektowania języka. I wiele punktów, które chcesz zobaczyć, może faktycznie obejmować składnię. Szkoda. Wydawało się, że to interesujące pytanie.
Konrad Rudolph
To, czego chcę uniknąć, to wojna płomieni. Jeśli możesz omówić składnię bez rozpoczynania wojny z płomieniami, idź na całość.
Berin Loritsch,

Odpowiedzi:

49

Obsługa Unicode domyślnie

W dzisiejszych czasach opracowywane są programy do użytku międzynarodowego lub przy założeniu, że mogą być one używane na arenie międzynarodowej. Oni muszą zapewnić wsparcie dla swoich zestawów znaków lub czynią programów napisanych w tym języku bezużyteczne.

Malfist
źródło
2
+1 W rzeczywistości sam język powinien umożliwiać użycie dowolnego znaku w identyfikatorach. Nie wszyscy jesteśmy Anglikami.
Berin Loritsch,
13
@Berin: W rzeczywistości, mimo że jestem Francuzem, zdecydowanie wolę programy w języku angielskim. Problem polega na komunikacji, jeśli piszesz programy z węgierskim, hiszpańskim lub portugalskim identyfikatorem, nie oczekuj, że kiedykolwiek będę w stanie wskoczyć ... w kontekście internacjonalizacji niezwykle ważne jest, aby programiści mogli komunikować się między sobą , a to oznacza używanie wspólnego języka dla identyfikatorów, komentarzy i dokumentacji. Angielski jest lingua franca programistów.
Matthieu M.
11
Dodałbym, że obsługa Unicode powinna być naturalna podczas używania języka. Jeśli to możliwe, nie trzeba podejmować żadnego dodatkowego wysiłku, aby „dodać”, powinno „po prostu działać” (w uzasadnionych przypadkach).
RHSeeger
4
W związku z tym język powinien wprowadzać podstawowe rozróżnienie między danymi tekstowymi (sekwencja znaków) a danymi binarnymi (sekwencja bajtów). C # robi to dobrze za pomocą stringi byte[]. Podobnie jak Python 3.x z stri bytes. C (++) charrobi to okropnie źle.
dan04
1
@RHSeeger - rzeczywiście !!! Nawet w Pythonie musisz pisać u'My Unicode Štring'. Chciałbym, żebyś mógł po prostu zapomnieć, z jakim typem łańcucha masz do czynienia, i cholernie napisz kod.
orokusaki
25

Mam parę:

  • Ogólne / szablony. Na przykład, generyczne Java są potężne, ale niekoniecznie elastyczne. Ponadto, ponieważ używają usuwania typu, widziałem problemy z ich abstrakcyjną implementacją, szczególnie w interfejsach. A kompilator nie powinien ostrzegać, gdy używany jest nieokreślony rodzajowy (jak Hashmapzamiast Hashmap<String, int>). Myślę, że można je znacznie poprawić. Dobre szablony są bardzo przydatne, ale często zaniedbywane.

  • Obsługa Good Date w standardowej bibliotece. Mam na myśli to, że mogę dodawać i odejmować daty, godziny i minuty i nie muszę radzić sobie z liczbą milisekund od 1 stycznia 1970 roku.

Michael K
źródło
2
„dobre wsparcie na randki” to jednak dość stromy wymóg! co to w ogóle znaczy? Myślę, że daty i godziny to jedna z tych rzeczy, w których nie można tego dobrze zinterpretować. albo uczynisz to prostym i złym, albo uczynisz to dobrym i bezbożnym skomplikowanym. NAPRAWDĘ trudno trafić na dobry środek ziemi.
sara,
@kai Chodzi o to, że obsługa dat jest zwykle dość straszna. Stare java.util.Datema prawie wszystkie możliwe problemy i problemy. Znam tylko część nowego java.time.*pakietu, ale jest czysty, łatwy w użyciu i wolny od błędów AFAICT. Bardziej zaawansowani użytkownicy mogą znaleźć problemy, ale to ogromna poprawa. +++ Problem wydaje się polegać na tym, że jest to skomplikowany problem, a pierwsza wersja jest popędzona i zepsuta.
maaartinus
24

Udostępnij swój język do analizy / audytu dla osób zajmujących się bezpieczeństwem komputerowym.

Pracownicy ochrony muszą być w stanie znaleźć luki w zabezpieczeniach programu przed jego wysłaniem. Najlepiej, gdy jesteśmy wzywani wcześnie i możemy komentować bazę kodu w miarę jej rozwoju, ale często nie.

Gdy pojawi się nowa wersja języka lub bibliotek podstawowych, rzeczy, które wcześniej były bezpieczne, mogą już nie być:

  1. biblioteki mogą stać się potężniejsze: np. biblioteka URL obsługuje teraz javascript:
  2. mogą istnieć nowe sposoby konwertowania ciągów lub bajtów na kod: np. evalbiblioteki deserializacji
  3. techniki refleksji językowej mogą stać się silniejsze: np. ujawnianie zmiennych lokalnych

Każda z tych zmian może zwiększyć liczbę uprawnień nadużycia, jakie ma program, ale ponieważ ilość uprawnień, z których korzysta program (w kontaktach z nie-złośliwymi klientami), nie uległa zmianie, pracownicy ochrony są zmuszeni dowiedzieć się o tym bez intensywnego ponowny audyt.

Proszę więc pomyśleć o nas przy projektowaniu i wersjonowaniu języka. Poniżej znajduje się kilka wskazówek:

Zdefiniuj kilka prymitywów, na które program może zostać rozłożony.

HTML5 jest szczególnie zły w ten sposób. Oczywiście poświęcili wiele uwagi bezpieczeństwu i mają bardzo inteligentnych ludzi, ale zamiast określać nowe elementy programu, takie jak <video>stare, lub tworzyć wspólną abstrakcję, którą można określić zarówno nowe, jak <video>i stare <img>, <video>to jeszcze kolejny jednorazowy element programu z własnymi konsekwencjami bezpieczeństwa.

Uczyń swój język podatnym na analizę statyczną (nawet jeśli nie jest statycznie wpisany).

Specjaliści od bezpieczeństwa często używają analizy statycznej, aby znaleźć wzorce i spróbować wykluczyć części programu, aby mogli skupić się na naprawdę trudnych bitach.

Powinno być oczywiste, które identyfikatory są zmiennymi lokalnymi, a które nie.

Np. Nie popełniaj tego samego błędu co w starych wersjach JavaScript, które uniemożliwiały stwierdzenie, czy xponiżej znajduje się odwołanie do zmiennej lokalnej (zgodnie z dosłownym odczytem starej wersji specyfikacji):

if (Math.random() > 0.5) {
  Object.prototype.x = 0;
}

function f() {
  var x = 1;
  (function () {
    alert(x);  // Might alert 0, might alert 1.
  })();
}

Pozwól na bezpieczeństwo rozkładalne

Wiele bezpiecznych systemów zostało zaprojektowanych wokół bezpiecznego jądra, które zachowuje właściwości bezpieczeństwa, dzięki czemu osoby zajmujące się bezpieczeństwem mogą skoncentrować swoje wysiłki na analizie niewielkiej ilości kodu i uwolnić większość programistów od konieczności radzenia sobie z osobami zajmującymi się bezpieczeństwem {irytujące, pedantyczne, paranoiczne} .

Powinno być możliwe napisanie takiego jądra w twoim języku. Jeśli jedną z właściwości bezpieczeństwa twojego języka jest to, że kiedykolwiek zostanie pobrany tylko pewien podzbiór adresów URL, czy pisarze jądra mogą zrobić coś, by skierować wszystkie pobieranie adresów URL przez swój kod? Lub może statyczne kontrole kompilacji (np. Patrząc na import) pełnią tę samą funkcję.

Niektóre języki, takie jak Newspeak, używają modelu możliwości obiektu. To niesamowity i świetny sposób na uzyskanie bezpieczeństwa rozkładalnego.

Ale jeśli nie możesz tego zrobić, uczynienie z wykresu modułu artefaktu, który można analizować statystycznie, może przynieść ci wiele korzyści. Jeśli mogę udowodnić, że moduł nie może dotrzeć do modułu we / wy pliku (z wyjątkiem wywoływania kodu w module w TCB), to mogę wykluczyć całe klasy problemów z tego modułu.

Ogranicz uprawnienia wbudowanych języków skryptowych

Wiele przydatnych systemów jest zorganizowanych jako statyczny rdzeń, który odpycha dużo kodu napisanego w dynamicznych (nawet funkcjonalnych) językach.

Osadzanie języków skryptowych może znacznie rozszerzyć system.

Ale język skryptowy nie powinien mieć pełnych uprawnień maszyny wirtualnej.

Jeśli zdecydujesz się zezwolić na wbudowane języki skryptowe, ułatw inwokatorowi ograniczenie tego, co mogą zrobić. Model właściwości obiektowych (patrz komentarz do Newspeak powyżej) jest tutaj bardzo odpowiedni; dlatego podczas oceny kodu w języku skryptowym wywołujący powinien przekazać kod do wykonania i wszystkie zmienne globalne dla tego kodu.

Traktuj evaljako język osadzający się jako język skryptowy

Jeśli Twój język może wywoływać własny kompilator w celu przekształcenia łańcucha w kod, pozwól, aby został on piaskowiony tak samo, jak każdy osadzony język skryptowy.

Użyj prostego modelu współbieżności

My, ochroniarze, nie chcemy martwić się warunkami wyścigowymi, próbując dowiedzieć się, czy własność bezpieczeństwa jest utrzymywana.

Zanim zdecydujesz się na wątki, rozważ alternatywę dla wątków jako prawie niemożliwą do zabezpieczenia domyślną opcję.

Jednym prostym jest współbieżność pętli zdarzeń, taka jak w E, Verilog i JavaScript.

Nie zachęcaj do pomieszania cytatów

Niektóre języki są językami kleju i kończą się na napisach w wielu różnych językach.

Na przykład JavaScript często składa się z ciągów HTML, CSS, XML, JSON, a nawet JavaScript. Bardzo trudno jest programistom pamiętać o prawidłowym kodowaniu ciągów tekstowych podczas ich łączenia w celu tworzenia ciągów w innych językach, więc programy JS, jak można się było spodziewać, mają wszelkiego rodzaju problemy z pomijaniem cytatów: XSS jest najgorszy.

Jeśli chcesz uwzględnić funkcje kompozycji ciągów, spróbuj zmniejszyć obciążenie programisty. DSL, higieniczne makra i osadzone języki szablonów mogą być świetnym sposobem na to, przenosząc ciężar prawidłowego ucieczki do twórców bibliotek lub języków z dala od programisty końcowego.

Mike Samuel
źródło
Piękna awaria.
Qix
23

Niektóre z najlepszych języków zostały zaprojektowane przez ludzi, którzy chcieli stworzyć język dla siebie.

Myślę więc, że projektanci języków powinni mniej zwracać uwagę na swoich użytkowników. Nie możesz zadowolić wszystkich, podobnie jak nie powinieneś.

dan_waterworth
źródło
4
To może być do pewnego stopnia prawdziwe. Jeśli jednak nigdy nie słuchasz użytkowników, nigdy nie wiesz, jaki ból im zadajesz, gdy próbują użyć twojego mózgu. Bez słyszenia / odczuwania bólu nigdy nie wpadniesz na kolejny świetny pomysł, który rozwiązuje ten problem i inne. Żaden człowiek nie jest wyspą. Ból może być świetnym czynnikiem motywującym do innowacji.
Berin Loritsch
5
@Berin: Nie sądzę, że chodzi o to, że nigdy nie powinieneś słuchać swoich użytkowników, ale nie słuchaj użytkowników, którzy chcą używać języka do czegoś, co nie zostało zaprojektowane. Jeśli zaprojektowałeś język w celu rozwiązania określonego zestawu lub problemów, powinieneś zaspokoić potrzeby użytkowników, którzy również muszą rozwiązać te problemy. Jednak zajmujesz się ekstremalnie, a czasami język może znaleźć niszę w nowej domenie, więc +1.
Jeremy Heiler
2
@Jeremy, tak, właśnie o tym mówię, ale myślę, że rzadko zdarza się, aby język działał dobrze w domenie, dla której nie został zaprojektowany.
dan_waterworth
@dan_waterworth: Udane języki zwykle działają, często dobrze, w domenach, dla których nie zostały zaprojektowane.
David Thornley,
8
Zamiast „nie słuchaj użytkowników” rada jest lepiej sformułowana jako „nie słuchaj użytkowników, których nie masz”.
chrisaycock
16

Tylko 5-10% czasu spędza na pisaniu kodu. Projektanci języków powinni zwracać uwagę na trudności z faktycznym uruchomieniem oprogramowania, co oznacza naprawianie błędów i błędów.

Oznacza to, że od samego początku powinien istnieć dobry debugger. Żadne narzędzie z tajemną składnią i klawiszami, które jest tylko nieznacznie lepsze niż tony instrukcji print.

Jaka jest nazwa?
źródło
2
+1. Debugowanie jest jednym z miejsc, w których niektóre języki są lepsze od innych - a niektóre IDE robią różnicę między użytecznym językiem a tym, który staje ci na drodze.
Berin Loritsch
2
Dodam trochę do tego i powiem, tam gdzie to możliwe, przydatne ślady stosu. Jeśli wystąpi błąd (lub niewyłapany wyjątek lub cokolwiek innego, w zależności od języka), chcę mieć możliwość wyświetlenia całego stosu wywołań, który do niego dotarł, wraz z wartościami użytych argumentów. Tcl robi to wyjątkowo dobrze .. ale, żeby być uczciwym, w Tcl wszystko jest ciągiem, więc możesz drukować wartość wszystkiego z względną łatwością.
RHSeeger
1
Nie tylko debugowanie, ale utrudnianie pisania błędów. Byłem bardzo szczęśliwy, kiedy Java wprowadziła automatyczne sprawdzanie granic tablic ... ale tutaj, 15 lat później, nadal popełniamy te błędy w innych językach.
Alex Feinman
3
Czy nie byłoby lepiej mieć język, który wykryje błędy podczas kompilacji? Na przykład, kiedy używam Ada, spędzam znacznie mniej czasu w debuggerze niż wtedy, gdy używam C lub C ++.
Martin
12

Myślę, że powinni zwrócić uwagę na Pythona, który robi więcej rzeczy właściwie niż jakikolwiek inny język, z którym się spotkałem (i to nawet jeśli nie lubisz niektórych funkcji). Nie oznacza to, że powinni emulować Python, ale ważne jest, aby wiedzieć, co Python zrobił dobrze, nawet jeśli w ogóle nie chcesz tworzyć języka takiego jak Python.

Jeśli chodzi o istotne tam filozoficzne pomysły, są to najważniejsze z Zen Pythona:

  • Jawne jest lepsze niż niejawne.
  • Liczy się czytelność.
  • Przypadki specjalne nie są wystarczająco wyjątkowe, aby złamać zasady.
  • Chociaż praktyczność przewyższa czystość.
  • Powinien być jeden - a najlepiej tylko jeden - oczywisty sposób na zrobienie tego.
  • Jeśli implementacja jest trudna do wyjaśnienia, to zły pomysł.
  • Przestrzenie nazw to jeden świetny pomysł - zróbmy ich więcej!

Myślę, że język zgodny z tymi regułami musi być całkiem OK, ale znam tylko jeden, który to robi, a to jest Python. Pomimo wszystkich podobieństw do implementacji np. Ruby, Ruby omija takie rzeczy jak czytelność i zaprasza do gry w golfa z kodem, co jest zabawne, ale nie przydatne w profesjonalnym otoczeniu.

Jedyną funkcją techniczną, za którą tęsknię w Pythonie, jest instrukcja „do” (jak podczas, ale nie testowanie wyrażenia za pierwszym razem). Istnieje wiele rzeczy w standardowych bibliotekach Pythona i innych językach, które można ulepszyć, ale nie są to wyłącznie języki , więc to inne pytanie. :-)

Lennart Regebro
źródło
4
Uważam dwie inne rzeczy za ważniejsze, szczególnie na poziomie projektowania językowego: „Specjalne przypadki nie są na tyle wyjątkowe, by łamać zasady”. ponieważ język z tysiącem specjalnych przypadków lub tajemnych reguł jest trudny w użyciu, w połączeniu z „Chociaż praktyczność bije czystość”. bo inaczej dryfujesz w królestwo Turinga.
15
Jeśli jawne jest lepsze niż niejawne, dlaczego nie musisz deklarować zmiennych? Kiedy prosta literówka może powodować trudne do debugowania błędy (w przeciwieństwie do błędów wychwytywanych w czasie kompilacji lub błędów środowiska wykonawczego, które są oczywiste i łatwe do debugowania), jest to poważne uderzenie w język IMO.
Mason Wheeler,
4
@Mason Wheeler: Jedynym powodem, dla którego musisz zadeklarować zmienne w innych językach, jest to, że musisz zadeklarować ich typ. Python jest dynamiczny, więc deklaracja typu nie jest potrzebna, a zatem deklaracja nie jest potrzebna. Nie rozumiem, jak to ma coś wspólnego z niejawnym / jawnym. Typy w Pythonie są jawne. Podobnie jak zmienne. Po dziesięciu latach literówka nigdy nie powoduje trudnego do debugowania błędu. W rzeczywistości są one łatwe do debugowania.
Lennart Regebro
8
+1 za listę, -1 za fanboyność. Zwrócenie uwagi na wszystkie języki, które odniosły znaczący sukces, i próba włączenia lub przynajmniej analizy stosowalności tych elementów wydaje się bardziej pragmatycznym podejściem.
Steven Evers
3
@ Lennart: Powiedziałbym, że możliwość (ale nie jest to wymagane, patrz reguła 4) jawnego określania typów funkcji jest dobrą rzeczą. Jest podobny do projektu na podstawie umowy. Właśnie o tym chcę powiedzieć.
Theo Belaire
11

Możliwość dostosowania języka do własnych potrzeb jest dla mnie duża. Dla Lisp, który jest wykonywany z makrami, dla Tcl z wyższym poziomem. W mniejszym stopniu Ruby używa lambd i tym podobnych. Chcę po prostu dodać nowe struktury kontrolne, które pasują do problemu, zamiast formować moje problemy wokół dostępnych struktur kontrolnych. Jako prosty przykład, konstrukcja „do .. do”, która istnieje w niektórych językach, ale nie w innych, jest czystszym sposobem obsługi niektórych przypadków niż „while”, możliwość dodania nowych struktur w celu spełnienia innych przypadków jest niezwykle przydatna.

W bardziej ogólnym sensie jest to metaprogramowanie ... ale używam go głównie do budowy nowych struktur kontrolnych.

RHSeeger
źródło
Ciekawy. Dobra obsługa metaprogramowania może być trudna do uzyskania, ale bardzo potężna, gdy jest. Słyszałem od ludzi, którzy lubią Lisp, że wdrożenie Lisp jest jednym z najlepszych - ale tak mówią o wszystkim w Lisp. Czy są jakieś przykłady tego, co według Ciebie jest wykonywane, meta-programowanie?
Berin Loritsch
„Metaprogramowanie zrobione właściwie” musi być tam, gdzie łatwo jest zrobić dobrze (dobrze, dla rozsądnej prostej czynności) i gdzie wynik końcowy wydaje się naturalną częścią języka.
Donal Fellows
1
Nie tylko modyfikowalna, ale modyfikowalna. Jeśli przemapowałeś coś w języku, ja jako czytelnik powinienem być w stanie szybko to rozgryźć. Adnotacje lub inne zewnętrzne znaczniki mogą w tym pomóc.
Alex Feinman
Myślę, że Mata-Lua lub Template Haskell wykonują dobrą robotę, zapewniając to. (Nie tak ładne jak makra Scheme, ale to jest to, za co płacisz za używanie więcej niż parens w języku)
Theo Belaire
10

Najważniejsze jest to, że Twój język musi mieć „styl”. Na przykład nazwałbym C językiem programowania systemów opartych na wskaźnikach. Nazwałbym Erlang wysoce funkcjonalnym językiem programowania. Niektóre inne języki (takie jak C ++ i prawdopodobnie Java) są tym, co Allan Kay nazwał językami „aglutynacyjnymi”: języki Frankensteina składały się z wielu połączonych ze sobą funkcji.

Następnie najważniejsze jest, aby zmiany w samym języku były ostatecznością. Nawet najbardziej łagodne brzmienie może stać się skomplikowane w połączeniu z innymi funkcjami języka. Powiedziałbym, że aby wprowadzić nową funkcję w języku, musisz:

  1. Udowodnij, że jest to naprawdę konieczne.
  2. Udowodnij, że nie można tego zrobić w bibliotece.
  3. Udowodnij, że należy do języka.
Jason Baker
źródło
2
Innymi słowy, język powinien mieć jedną nadrzędną zasadę projektowania, a język powinien być zgodny z tą zasadą. Komentarze na temat ewolucji języka są uzasadnione (widziałem to kilka razy).
Berin Loritsch
1
Przypomina mi mój ulubiony cytat z C ++ ... Ośmiornica zrobiona przez przybicie psa dodatkowymi nogami.
ocodo
4
Udowodnij, że nie można tego zrobić w bibliotece . +1
Qix
2
Lubię smakołyk z biblioteki. To fajne, że języki takie jak haskell nie mają wbudowanych elementów kontroli przepływu, takich jak pętle, wyjątki lub kontynuacje. są po prostu bardzo łatwe do zdefiniowania w języku, utrzymując bardzo czystą składnię i promując rozszerzalność i możliwość komponowania, zamiast tworzenia sprytnych funkcji językowych.
sara,
10

Dzięki za świetne pytanie. Otrzymujesz całkiem dobre odpowiedzi.

Nie glazurować na twoich oczach, ale patrzę na programistę jako kanał informacyjny. Pomysły / koncepcje / wymagania idą z jednej strony, a kod wychodzi z drugiej.

Jeśli weźmiesz zestaw wymagań (bez względu na to, jak są one określone) i zestaw kodu na ogromnej tablicy i narysujesz linie odwzorowujące każde wymaganie na kod, który go implementuje, złożoność tego wykresu będzie zależeć od tego, jak dobrze kod wyraża wymagania. Idealnie byłoby, gdyby był bezpośredni i jeden do jednego, ale trudno jest go wdrożyć w praktyce.

Zmierzam specyficzność domenową języka jako stopień, w jakim upraszcza on ten wykres. Jest to niezwykle pożądana właściwość i można do niej podchodzić na wiele sposobów, od zdefiniowania odpowiednich klas / procedur (rzeczowników / czasowników), poprzez makra, po napisanie własnego parsera i interpretera / kompilatora.

Podam tylko przykład tego, co mam na myśli. W przypadku problemu tworzenia elastycznych interfejsów dialogowych użytkownika technika ta eliminuje konieczność pisania procedur obsługi zdarzeń, przenoszenia danych i większości rzeczy zwykle wykonywanych w interfejsach użytkownika. Powoduje również zmniejszenie kodu źródłowego o około rząd wielkości. Metajęzyk to tak naprawdę tylko kilka procedur i makr w C / C ++ / Lisp, a także zrobiłem to w językach bez makr.

Jeśli zaimplementowanie wymagania można wykonać za pomocą 5-punktowej edycji kodu lub za pomocą 10, zrobienie tego za pomocą 5 oznacza nie tylko mniej kodu, ale także mniejsze szanse na pominięcie kroku i popełnienie błędu. Zatem im bardziej język jest specyficzny dla domeny, tym mniejszy, łatwiejszy w utrzymaniu i pozbawiony błędów kod. Myślę, że musimy wiedzieć, jak do tego dążyć. To nie nie znaczy, że kod jest bardziej czytelny, chyba że czytelnik zainwestował w krzywej uczenia się zrozumieć technikę.

Mike Dunlavey
źródło
9

Ograniczone i różne typy liczb całkowitych, takie jak w Pascal i Adzie. Szczerze mówiąc: jak często potrzebujesz pełnego zakresu dowolnej liczby całkowitej? Myślę, że w prymitywnych typach jest wiele do poprawienia, aby lepiej reprezentowały rzeczywisty świat.

Jaskółka oknówka
źródło
2
Ograniczone typy liczb całkowitych, takie jak C, C ++, D, Java, C # itp. Mają swoje miejsce na pewno. Niektóre rodzaje programowania nie dbają i po prostu potrzebują jedynie rozróżnienia liczb całkowitych i zmiennoprzecinkowych. Nawet wtedy być może potrzebujemy tylko typu liczb i martwimy się później o jego integralną część? Krótko mówiąc, programowanie biznesowe jest mniej wrażliwe na konkretny typ liczb całkowitych niż na fakt, że liczba jest liczbą całkowitą. Podczas wdrażania protokołu na niskim poziomie reguły zmieniają się drastycznie.
Berin Loritsch
2
To, co myślałem, gdzie typy jak w Adzie, gdzie możesz po prostu powiedzieć type Date_Of_Month is 1 .. 31;i zostawić decyzje takie jak 16 lub 32 bity optymalizatorowi. Ale co ważniejsze, przypisanie 32 lub 0 lub -5 do zmiennej tego typu daje ci RANGE_ERROR.
Martin
Zakresy działają dobrze dla rzeczy takich jak Date_Of_Month(lub Month_Of_Year), w których istnieje oczywisty zakres do użycia, ale wiele - prawdopodobnie większość - przypadków jest rozmytych. type Persons_Age is 0..120? Co jeśli ktoś pobije rekord długowieczności? type Year is 0..9999? Co jeśli jesteś egiptologiem?
dan04
Jeśli jesteś egiptologiem, nie potrzebujesz niczego type Egyptian_Year is -9999 .. 300;. Z mojego doświadczenia wynika, że ​​przez większość czasu można znaleźć przydatne granice liczb całkowitych. W związku z tym powinieneś rozważyć type Scrolls_Found is array Egyptian_Year of Natural;Nie możesz / nie powinieneś mieć nieograniczonego typu jako indeksu tablicy. Jest to po prostu wektor ataku dla hakera. BTW: Ada pozwala na obliczanie granic zasięgu w czasie wykonywania.
Martin
1
@kai nikt nie powiedział, że ta szczególna cecha systemów typu musi być używana wszędzie bez wyjątków. Jestem pewien, że Ada pozwala również na używanie „zwykłych” typów numerycznych. Ograniczone typy liczbowe są z pewnością przydatne w przypadku niektórych (raczej powszechnych) problemów.
Sarge Barszcz
8

Istnieją funkcje, które sprawiają, że języki programowania są łatwe w użyciu, gdy się ich nauczysz, i są funkcje, które ułatwiają ich naukę. Ponieważ użytkownicy języka mają idealną długoterminową relację z nim, optymalizacja pod kątem łatwości użytkowania jest lepsza niż optymalizacja pod kątem łatwości nauki. Nie rób rzeczy trudniejszych niż to konieczne, ale nie poświęcaj ekspresji (będąc w stanie napisać mały kod, który dużo robi) dla czytelności dla tych, którzy nie znają języka. Z drugiej strony, język nie powinien czytać jak szum linii dla ludzi, którzy pracowali z nim od lat; nie byłby łatwy w użyciu ani do nauki.

Larry Coleman
źródło
8

Konwencje nazewnictwa (patrzę na ciebie PHP)

Malfist
źródło
Jednak mniej problemów z projektowaniem języka. Jasne, zawsze musisz mieć oko na to, co wchodzi do standardowej biblioteki, ale projektanci języków nie mogą egzekwować konwencji nazewnictwa;)
3
Możesz dla standardowej biblioteki.
Malfist
3
Nawet nie wspominaj o PHP. Najgorszy powszechnie używany język. Nie zaprojektowany przez informatyka tylko facet, który chciał szablonów i sterydy zostały dodane.
Keyo
@delnan: niektóre języki, takie jak Mercury lub Eiffel, narzucają konwencje nazewnictwa (wszystkie nazwy klas kapitałowych, zmienne rozpoczynające się od wielkich liter itp.) i są egzekwowane przez kompilator. Fortran powiedział, że zmienne zaczynające się od i, j, k są liczbami całkowitymi (stąd tradycyjne użycie jako zmienne pętlowe w większości języków ...). I tak dalej. W pewien sposób denerwujące, jeśli nie podoba ci się konwencja, ale dobre dla przynajmniej spójności kodów źródłowych.
PhiLho
@PhiLho: To bardzo ograniczone. Nie może wymusić - tylko jeden przykład - konsekwentnego, znaczącego (dla ludzkich czytelników) użycia wielkich liter lub podkreśleń (mógłby spróbować, ale ryzykowałby rozsądek programistów w tym procesie).
7

Pierwszorzędna integracja ze środowiskiem programistycznym.

Obecnie kodowanie odbywa się w bogatym środowisku. W przypadku HTML / CSS / JS mamy Firebug i inne interaktywne narzędzia. Dla Java, Eclipse i IDEA oraz innych prawdziwych IDE. I tak dalej. Istnieje ekologia narzędzi, zaczynająca się od edytora, ale nie kończąca się na:

  • Organizacja kodu w plikach i między nimi
  • Inteligentne wyróżnianie
  • Inteligentne uzupełnianie / predykcyjne pisanie
  • Debugowanie statyczne (błędy składniowe flagowania, semantyczne i stylistyczne)
  • Tworzenie i korzystanie z szablonów i makr
  • Kontrola wersji (wersjonowanie, scalanie, rozgałęzianie, ...)
  • Rozproszony rozwój z wieloma autorami (komentarze, wbudowany dokument, adnotacje, ...)
  • Debugowanie w czasie wykonywania (ślady stosu, kroki, zegarki, ...)
  • Interaktywne debugowanie „na żywo” (jak Firebug - zachowanie edycyjne systemu na żywo)
  • ... nawet nie wiem co będzie dalej.

Języki powinny być budowane w celu zapewnienia wsparcia dla tych działań. Poczyniono pewne postępy - na przykład adnotacje w Javie, aby pomóc innym programistom zrozumieć cel kodu.

Ale głównie są to zhakowane rzeczy, takie jak użycie $ Id $ w komentarzu, aby źródło sterowane CVS mogło zawierać numer wersji. Dlaczego nie mogę zrobić czegoś takiego z samego języka?

Alex Feinman
źródło
Masz na myśli coś takiego jak ASIS (ISO / IEC 15291: 1999 „Ada Semantics Interface Specification”)? ASIS nie obejmuje wszystkiego, co chcesz, ale całkiem sporo. Często życzyłem sobie czegoś takiego jak ASIS dla innych języków programowania. Szczegółowe informacje można znaleźć na stronie sigada.org/wg/asiswg .
Martin
Niektóre z tych rzeczy są względnie tanie lub są dostępne bezpłatnie w twoim IDE: organizacja kodu, podświetlanie składni, składanie kodu, kontrola wersji, szablony / makra. Inne wymagają dużo więcej wysiłku: debugowanie w czasie wykonywania, debugowanie statyczne, inteligentne uzupełnianie / typowanie predykcyjne, refaktoryzacja itp. Choć często zaniedbywane, projektowanie spójnego języka jest znacznie trudniejsze, gdy musisz martwić się o wtyczki IDE.
Berin Loritsch
6

Obliczenia rozproszone

Bezpłatny obiad się skończył. Dzisiaj potrzebne są programy działające na wielu rdzeniach / wielu procesorach (aw szczególnych okolicznościach na wielu komputerach).

Niestety pisanie wielowątkowego kodu jest trudne koncepcyjnie, więc naprawdę nie ma potrzeby dodawania języka jako bariery.

Wykorzystanie przyszłości w C ++ 0x jest z pewnością interesujące, ponieważ zostało wprowadzone jako biblioteka i nie uwalnia cię od faktycznych problemów z synchronizacją (wiesz, te, które są tak łatwe do rozwiązania ...)

Naprawdę podoba mi się podejście Go do problemu: wielowątkowość jest wbudowana, a przyjęte podejście (kanały i goroutynki) pozwala na znacznie łatwiejsze podejście niż tradycyjne podejście semaforowe / muteksowe / blokujące. Nadal łatwo jest jednocześnie uzyskać dostęp do niezsynchronizowanej struktury (Go ma wskaźniki) lub do impasu (cykl oczekiwania na kanałach ...)

Myślę, że języki sprzyjające niezmienności danych, takie jak języki funkcjonalne, mogą mieć do tego prawo (choć lubię tam doświadczenie).

Ponadto, aktor model może być nasz następny cel. Był przeznaczony również do przetwarzania rozproszonego.

Matthieu M.
źródło
Innym przykładem może być Erlang. Powszechnym tematem wśród języków tego rodzaju jest wspólne podejście „ nic” , w którym stan jest zasadniczo przekazywany wraz z wiadomością. Podejście to dobrze się skaluje.
Berin Loritsch,
@Berin: Masz rację, mimo że nie cytowałem Erlanga w wiadomości, ponieważ niewiele o nim wiem, dobrze pamiętam, że implementuje model aktora.
Matthieu M.
6

Nazywaj mnie szalonym, ale jedną z najważniejszych cech językowych jest dostępność dobrych referencji online wraz z przykładami. Wiem, że mogę znaleźć dobre wyniki wyszukiwania dla dowolnego języka, ale naprawdę podoba mi się strona API MSDN i Java. Ułatwiają programowanie osobom, które nie mają dużego doświadczenia w danym języku.

apoorv020
źródło
JavaDoc, CppDoc, RubyDoc itp. Były doskonałym atutem w zrozumieniu standardowych bibliotek, a także bibliotek, które tworzysz. Nie wszystkie są sobie równe, a niektóre są łatwiejsze w nawigacji niż inne.
Berin Loritsch,
Uzgodnione, witryna Java API jest doskonałym zasobem. Wspaniale jest mieć także standardowy format do tworzenia dokumentacji API. Wzrost wydajności dzięki zastosowaniu IDE z wbudowaną obsługą analizy JavaDoc (netbeans) jest niesamowity. Chociaż mam okropne wspomnienie, więc prawdopodobnie przynosi mi to więcej niż inni.
toc777,
6

Większa możliwość pomocy kompilatorowi w sprawdzaniu kodu.

Jako programista systemów wbudowanych zawsze używam C. Ale zawsze chciałbym mieć więcej / lepsze sposoby, aby powiedzieć kompilatorowi, czego oczekuję od mojego kodu, aby mógł go zweryfikować.

EG Mogę mieć funkcję

f(int x)

ale wolałbym

f(int range[-5..25] x)

EG Chciałbym móc pisać twierdzenia o funkcjach, używając jakiegoś języka funkcjonalnego wyższego poziomu, takiego jak Lisp lub Haskell. Nie byłyby one skompilowane w kodzie, ale mogłyby być użyte do analizy statycznej lub dynamicznej.

Rocketmagnet
źródło
Zasadniczo skuteczny sposób sprawdzania granic? To by było całkiem fajne. Chociaż chciałbym przynajmniej uwzględnić to podczas sprawdzania środowiska wykonawczego, a także sprawdzania czasu kompilacji. Podczas pobierania informacji z bazy danych lub interfejsu użytkownika zawsze gwarantujesz, że wartość będzie poprawna. Gdyby to była funkcja językowa, chciałbym jej również użyć do tych celów.
Berin Loritsch,
3
Powinieneś użyć Pascala. Możesz zdefiniować typ obejmujący dowolny zakres liczb, taki jak -5..25, który kompilator może zweryfikować w czasie kompilacji. (O ile oczywiście przypisujesz tylko stałe.)
Mason Wheeler,
1
@Kugel: Co jeszcze oprócz funkcji kompilatora jest potwierdzone? Test jednostkowy nie sprawdzi kodu w produkcji. A nie sprawdzanie produkcji jest jak zdejmowanie żywych łodzi po dziewiczej podróży. Aby zaoszczędzić paliwo i przyspieszyć statek.
Martin
1
Chciałbym użyć Ady, tyle że platforma, na której pracuję, nie ma kompilatora Ady. Ma tylko kompilator C, więc i tak jest to wszystko akademickie.
Rocketmagnet
1
Używam już wielu zapewnień, ale byłoby jeszcze lepiej mieć tę i inne rzeczy jako funkcje językowe.
Rocketmagnet
5

Mała składnia z jak najmniejszą liczbą słów kluczowych, ponieważ pełna składnia jest trudna do nauczenia i nie poprawia czytelności.

Najgorszym przykładem jest Ada:

procedure Hello is
begin
  Put_Line("Hello World!");
end Hello;

Wypełniające słowa, takie jak, ponieważ ... nie mają sensu w przypadku języków programowania.

Brainlag
źródło
4
Myślę, że najgorszym przykładem są języki, w których mówisz public static void.
Joey Adams,
1
Pomysł nie jest nowy i został już wdrożony w formie SmallTalk, która w ogóle nie zawiera słów kluczowych. Powinieneś więc użyć SmallTalk jako pozytywnego przykładu swojego roszczenia. BTW: Jeśli nie wiesz, do czego to ISsłuży, to nie rozumiesz Ady (czy programowałeś kiedyś Aę?): ISOddziela deklarację procedury od deklaracji zmiennych lokalnych, a także odróżnia specyfikację od implementacji. Oczywiście można zauważyć tylko przy porównywaniu specyfikacji i implementacji funkcji, aby zobaczyć, że ISma to sens i nie jest wcale wypełniaczem.
Martin
1
Zapomniałem wspomnieć: składnia SmallTalk pasuje również do tylnej części pocztówki. Spełnia więc również Twoje pragnienie „małego”. Oczywiście większość pomysłów jest już gdzieś zaimplementowana w jakimś języku i większość plakatów używa tych języków jako pozytywnego przykładu, zamiast tworzyć zły przykład negatywny. Głosowałbym za tobą, jeśli mam dość reputacji. Nie dlatego, że Twój pomysł jest zły - ale na przykład z negatywnego przykładu.
Martin
7
Wypełniające słowa mogą faktycznie służyć celowi, jeśli pomagają ujednoznacznić składnię. Na przykład, wolę if x then …się if (x) …. Wymieniliśmy parę nawiasów na kontekstowe słowo kluczowe. Ma to sens, ponieważ warunek xmoże być złożonym wyrażeniem z własnymi nawiasami. Wyeliminowanie najbardziej zewnętrznej pary może drastycznie zwiększyć czytelność. Alternatywą jest oczywiście użycie dwukropka tutaj, jak w Pythonie. W rzeczywistości uważam, że większość takich jednoznacznych wypełniaczy można zastąpić dwukropkami. Nie jestem pewien, którą metodę preferuję.
Konrad Rudolph
3
@Konrad: Jeśli rozbraja składnię, nie jest wypełniaczem. is Jest wypełniacz, ponieważ Ada może pozwoliły procedure Hello begin ... endbez niejednoznaczności.
dan04
4

Chciałbym zobaczyć więcej języków do nauki . Nie tylko języki dla początkujących z ograniczeniami bardziej świętymi niż wymóg między każdym tokenem , ale języki dla osób, które już znają programowanie i chcą nauczyć się nowych pojęć lub ogólnie lepiej programować.

Dla mnie Haskell jest doskonałym przykładem tego, co rozumiem przez „język uczenia się” (choć z biegiem lat zyskał również na popularności i ogólnej użyteczności). Porzucając znaną składnię C i mając operatory kompozycji funkcji wstecz (np. (+2) . (*3)Jest to funkcja, która mnoży się przez 3, a następnie dodaje 2), Haskell nauczył mnie pisać krótsze funkcje. Bezwzględny moduł sprawdzania typów pomógł mi szybciej nauczyć się języka i poprawił moją zdolność logicznego myślenia o kodzie. Obie te korzyści zostały rozszerzone na inne języki, nawet na montaż.

Cele uczenia się języków i języków ogólnego przeznaczenia są często sprzeczne. Nauka języka powinna być trudnym i satysfakcjonującym sposobem nauki, a także egzekwować określony styl, nawet jeśli ten styl nie jest najlepszy dla wielu aplikacji. Język ogólnego przeznaczenia powinien nadawać się do robienia rzeczy, a stosowanie abstrakcji powinno być starannie mierzone i „mieć sens”. Na przykład przy naprawianiu strony internetowej nauka o monadach byłaby ostatnią rzeczą, o której programiści myślą. Z drugiej strony, gdy ktoś uczy się programować, nie powinien przebrnąć przez nonsens „publicznej statycznej pustki”, jeśli jeszcze się nie nauczył o funkcjach.

Jeśli jesteś projektantem języka, zastanów się, czy Twój język jest językiem nauki, czy językiem stosowanym. To określi, w jakim stopniu będziesz chciał zastosować czystość w swoim projekcie.

Joey Adams
źródło
2
W jaki sposób kompozycja funkcji Haskella jest w jakikolwiek sposób wsteczna? To bezpośrednie tłumaczenie (f ∘ g)(x) = f(g(x)).
Jon Purdy
@Jon Purdy: Oznacza to, że musisz pisać funkcje w odwrotnej kolejności do ich zastosowania. W obu postaciach gnajpierw stosuje się argument, a następnie f. Jeśli chcesz posortować listę, pogrupować ją i uzyskać pierwszą pozycję z tych list, napisz (map head . group . sort) listlub map head $ group $ sort listlub map head (group (sort list)). We wszystkich przypadkach kończy się pisanie operacji wstecz. Nawiasem mówiąc, importowanie Control.Arrowpozwala powiedzieć (sort >>> group >>> map head) list, ale >>>operator wydaje mi się dość niezręczny i gadatliwy.
Joey Adams,
2
Nie wiem, nadal uważam, że od prawej do lewej ma sens. (map head . group . sort) listczyta się jako „pierwszy element każdej grupy w rodzaju list”, co jest całkiem naturalne - i, moim zdaniem, bardziej funkcjonalne niż (sort >>> group >>> map head) list, co brzmi raczej imperatywnie i wstecz jako „sortuj, a następnie grupę, a następnie weź pierwszy element z każdej grupy. .. list”.
Jon Purdy,
@JoeyAdams - te >>>spojrzenia operator raczej niewygodne i gadatliwy - Kilka nowszych języków funkcyjnych zaczęła używać |>jako lewy-prawy operatora łańcuchowym, który jest być może trochę łatwiej na oczy ...
Jules
4

Ponieważ jesteśmy w 2011 roku,

  • absolutnie kompletna specyfikacja. nie ma dziur zależnych od projektu, jak w C
  • obsługa wielowątkowości; nie tylko funkcje synchronizacji (blokady), ale także funkcje językowe, które sprawiają, że wielowątkowość jest tak łatwa jak pisanie pętli:

    all (o w myCollection) {o.someMethod ()}

  • wieloparadygmat; pozwól mi, programiście, zdecydować, czy chcę zapewnić bezpieczeństwo w czasie kompilacji języka statycznego lub zwięzłość języka dynamicznego, na podstawie poszczególnych przypadków; daj mi funkcje obiektowe, funkcje funkcjonalne itp.

  • spójność (wiem, że wymaga trochę zarówno spójności, jak i paradygmatu ...)

użytkownik 281377
źródło
Jestem z tobą w 100% za pełną specyfikację. Wiele paradygmatów i konsekwencja z pewnością będą działaniem równoważącym. Możesz określić zestaw zachowań dla dynamicznego paradygmatu jako podzbiór zachowań do sprawdzania statycznego - ale myślę, że te dwa podejścia mogą nadawać się do bardzo różnych stylów programowania. W tym momencie naprawdę nauczyli się być oddzielnymi językami. Być może para spójnych języków o 100% kompatybilności byłaby tym, czego szukasz?
Berin Loritsch
Języki takie jak Scala (a może Haskell? Nie znam tego wystarczająco dobrze) mają silny system typów statycznych i zwięzłość, dzięki wnioskowaniu o typ i implikacjom.
PhiLho
2
Funkcje zależne od architektury działają dobrze, gdy język pozwala programiście określić, co jest ważne, a co nie. Co sprawia, że ​​C jest okropny, ponieważ nie ma możliwości zadeklarowania „typu numerycznego, który otacza modulo 65536”; nawet jeśli platforma implementuje uint16_t, standard wymaga, aby niektóre implementacje uznawały różnicę między dwiema uint16_twartościami za podpisane, a inne uznawały różnicę za niepodpisaną; nie pozwala programiście określić, które zachowanie jest pożądane.
supercat
Nie zgadzam się na multiparadygmat; pozostawia to zbyt wiele miejsca na bitwy w stylu kodowania. Biblioteka A jest napisana z szeregiem dynamicznych paradygmatów . Biblioteka B jest napisana z szeregiem statycznych paradygmatów . Cóż, teraz Biblioteka A musi rozmawiać z Biblioteką B; gdzie jest środek ziemi? Jeśli musisz pisać klej między dwoma fragmentami kodu w tym samym języku, język jest z natury wadliwy IMO.
Qix
3

Lekkie procesy

Chciałbym mieć lekkie procesy jak w Erlang. Jest to głównie problem dla środowiska wykonawczego. Tego brakuje w JVM i .NET CLR. LWP pomaga w tworzeniu masowo współbieżnego oprogramowania. Idealnie byłoby, gdyby proces nie był droższy, ponieważ polega on na stworzeniu obiektu w języku. Chciałbym stworzyć miliony procesów w moich aplikacjach.

Jest zaimplementowany jako pula wątków z harmonogramem preemtive, więc jedno zadanie nie blokuje drugiego zadania, a zadania można zaplanować na dowolnym dostępnym rdzeniu procesora.

Wsparcie dla rekurencji ogona

Chciałbym poprzeć rekursję ogona. Może to również stanowić problem dla środowiska wykonawczego. Np. JVM nie obsługuje rekursji ogona.

Łatwe programowanie rozproszone

Chciałbym mieć wsparcie dla send ( ! ) I odbierać prymitywy do części aplikacji działających na innych komputerach na tym samym netword jak w Erlangu. Ułatwia to tworzenie skalowalnych aplikacji, np. Rozproszonych magazynów danych. Dodanie do tej serii wbudowanej w język jest również bardzo pomocne, jak w erlang. I nie tak jak w Javie, muszę to zrobić ręcznie.

Jonas
źródło
Rekonstrukcja
Berin Loritsch
Scala ma rekurencję ogona i jest kompilowany do JVM. Kompilator IBM Java również może czasami rekurencję.
Martin
3

Ułatwienie metaprogramowania.

ogranicz formy specjalne

W Pythonie nie ma dobrego powodu, aby drukować go nie jako wbudowaną funkcję. Wygląda i działa jak funkcja, z wyjątkiem tego, że nie chce mieć nic wspólnego z parens.

Czy naprawdę potrzebujemy for, foreach, whilea jak każdy jako własnej specjalnym formularzu. Co powiesz na jeden konstrukt zapętlający i kilka domyślnych makr, aby zapewnić cukier składniowy wariantów postaci zapętlonych.

metaprogramowanie formularzy specjalnych

form['if'](test-fn, body-fn)

dietbuddha
źródło
Ruby ma „specjalne formy” do zapętlania, przynajmniej w tym sensie, że iterowalne obiekty zwykle mają taką metodę, eachktóra przyjmuje blok kodu jako argument. (Ruby ma również fori whilepętle, ale żaden szanujący się programista Ruby faktycznie korzysta z nich.)
mipadi
@mipadi: Jestem wielkim fanem bloków Ruby i związanych z nimi idiomów.
dietbuddha
może myślą: - Wystrzelisz z siebie. :) Myślę, że było to skojarzenie was wszystkich potężnych „Python” i „nie ma dobrego powodu, dlaczego”. Niemniej jednak metaprogramowanie jest ważnym problemem projektowania języka, który jest często zaniedbywany. Z tego powodu będę głosować za tym.
Berin Loritsch,
@Berin: Używam i jestem fanem Pythona, co czyni go bardziej zabawnym.
dietbuddha
Jeden rodzaj pętli spowodowałby, że przepływ kodu byłby niejasny. Jak na przykład do..whilewyglądałaby pętla, gdyby istniał jeden typ pętli, który miał ocenę na górze? To nie wyglądałoby jak pętla do… podczas.
Qix
2

Możliwości sieciowe

Język, który jest dostarczany bez wsparcia sieci, jest dość kiepski w dzisiejszym świecie.

Większość aplikacji w świecie rzeczywistym musi komunikować się przez sieć:

  • automatyczna aktualizacja
  • dostęp do bazy danych
  • usługi internetowe

Oczywiście jest to także podstawa obsługi przetwarzania rozproszonego / w chmurze.

Matthieu M.
źródło
8
Ale może to być standardowa funkcja biblioteki .
Donal Fellows
@Donal: Nigdy nie powiedziałem inaczej (a przynajmniej tak nie myślałem), pytanie jest otwarte zarówno na funkcje językowe, jak i biblioteczne. Chodzi mi o to, że jeśli otrzymasz pakiet językowy i nie ma w nim możliwości sieci, szybciej wypełnisz ból wcześniej niż później :)
Matthieu M.,
3
Standardowa biblioteka jest naprawdę częścią doświadczenia językowego i powinna być traktowana z taką samą troską i szacunkiem. Zgadzam się również z tym wymogiem dla standardowej biblioteki.
Berin Loritsch,
1

Lubię język programowania, który jest łatwy do nauczenia i łatwy do łączenia w celu tworzenia nowych rzeczy.

Na przykład, chociaż atrakcyjne jest posiadanie wielu sposobów na napisanie czegoś, myślę, że lepiej jest mieć tylko jeden lub dwa sposoby na napisanie tego. W ten sposób program jest łatwiejszy w utrzymaniu.

Język, którego koncepcje mogą dotyczyć wszystkich elementów, jest bardzo pomocny (myślę, że nazywa się to ortogonalnością). Więc następnym razem, gdy napotkasz nową funkcję językową, możesz wydedukować, jak z niej korzystać.

Rozumiem, że czasami składnia języka musi przeszkadzać w osiągnięciu lepszych wyników w fazie kompilacji / interpretacji, ale czasami wydaje mi się, że projektant języka przekazuje tę pracę programistom. Na przykład ciągi wielowierszowe w Javie lub JavaScript.

Wreszcie, składnia języka jest interfejsem użytkownika i jako taka powinna być przejrzysta, zwięzła, intuicyjna, łatwa w użyciu i szanować twoje nawyki.

OscarRyz
źródło
Ortogonalny oznacza, że ​​każda funkcja robi coś innego. Spójrz na narzędzia takie jak grep lub awk. Robią jedną rzecz, cóż. Następnie łączysz je w różnych rozkazach, aby zrobić wszystko, czego potrzebujesz.
Theo Belaire,
1
  • Czytelność : im mniej / najmniej symboli używanych w gramatyce, tym czystsze i lepsze.
  • Typy obiektowe : metody, a nie funkcje.
  • Zrozumiałość : Wbudowane płynne interfejsy, kompleksowe i krótkie nazwy klas bibliotek / interfejsów i rodzajów.
dukeofgaming
źródło
1
Przepraszam, ale muszę dać ci -1 za to, że całkowicie się mylisz. Terseness pomaga szybciej pisać kod, ale zdecydowanie nie sprawia, że ​​kod jest bardziej czytelny, niż pewne minimum. Pewien poziom szczegółowości sprawia, że ​​kod jest znacznie łatwiejszy do odczytania, ponieważ te dodatkowe słowa i symbole coś znaczą i przekazują programiście znaczące informacje, zwłaszcza jeśli zostały pierwotnie napisane przez kogoś innego, a ty nie masz przewagi, że masz już umysł model tego w twojej głowie.
Mason Wheeler
Dla mnie czysty kod to kod czytelny. Powiedziałem także najmniejsze: posiadanie „:” zamiast „=>” w tablicach PHP lub posiadanie „.” zamiast „->”, z pewnością byłaby poprawa (i już lubię PHP).
dukeofgaming
4
@Mason: Ja i wielu dobrych pisarzy technicznych (np. William Zinsser) nie zgadzam się. Gadatliwość jest wrogiem czytelności, a nie zwięzłości.
Konrad Rudolph
2
Wybieram formę zwięzłości, która jest zdefiniowana za pomocą symboli . Jestem jednak całkiem zadowolony z symboli wieloznakowych, o ile są to rzeczy, które czytelnik naturalnie traktuje jako pojedynczy symbol (np. Słowo jest symbolem).
Donal Fellows
1
Twój pierwszy punkt bezpośrednio koliduje z twoimi dwoma ostatnimi.
Qix
1

Dodanie funkcji do istniejącego języka programowania. Tak więc nowy język B jest starą wersją językową A i cechą X.

Istniejące przykłady:

  1. C dodając klasy => C ++
  2. Java dodaje trochę rzeczy => C #
umlcat
źródło
2
To ogromne uproszczenie. O wiele lepszym przykładem byłaby różnica między C a celem C.
Jon Purdy,
0

Jeśli chodzi o technologię / platformę / język / bazę danych itp., W większości przypadków chodzi o wydajność. W przyszłości wiele dzisiejszych programów może być projektowanych w języku graficznym, ponieważ mamy moc obliczeniową.

Mam nadzieję na dzień, w którym będziemy mieli moc obliczeniową i język, w którym projektujesz swoją aplikację i nie musisz się martwić o szczegóły językowe .

Aktualizacja: wysyłam link do takiego języka LabView

Aktualizacja: powinienem bardziej wyjaśnić, co rozumiem przez „moc obliczeniową”. Wydajność skompilowanego oprogramowania może nie być tak duża, jak skompilowane oprogramowanie oparte na języku składni. Myślę o programowaniu graficznym jako o wyższym poziomie programowania i może być więcej kosztów ogólnych. Dzisiejsze komputery mogą i łatwo uruchamiają graficzne języki programowania.

Amir Rezaei
źródło
3
Komputery są już wystarczająco potężne, aby to zrobić. To po prostu niepraktyczne, ponieważ z jakiegoś powodu musisz zagłębić się w kod .
Jeremy Heiler
2
Nadal jest swego rodzaju językiem. Podjęto więcej niż jedną próbę urzeczywistnienia tego. Narzędzia UML wygenerują pewną ilość kodu, ale gdy model jest wystarczająco szczegółowy, aby wytworzyć działający produkt, nie jest już dłużej przydatny do zrozumienia kodu. Wierzę, że w środowisku Unixa było coś do graficznego okablowania aplikacji, ale wymagało to dużej konfiguracji, aby uzyskać poprawność. Silniki przepływu pracy używają tej metafory, aby umożliwić programistom zaprojektowanie przepływu pracy.
Berin Loritsch,
1
Krótko mówiąc, chociaż poważnie wątpię w użyteczność tego podejścia w ujęciu ogólnym, istnieją konkretne aplikacje, w których jest ono obecnie używane i działa dobrze dla tej aplikacji. Re: twoje punkty ... 1. Komputery mają moc obliczeniową, strona techniczna nie stanowi problemu. 2. Problem polega na zapewnieniu języka wizualnego, który jest wystarczająco wyrazisty, aby wykonywać pracę w sensie ogólnym bez zagubienia się w szczegółach. Poza niszowymi aplikacjami tekst wydaje się być znacznie bardziej zwartą reprezentacją programu. Głosowałem za tym, ponieważ dotyczy to postawionego pytania.
Berin Loritsch,
1
@Amir: Następnie wyjaśnij, dlaczego komputery muszą być bardziej wydajne, aby „programowanie graficzne” napędzało rozwój oprogramowania?
Jeremy Heiler
7
@Amir: Mylicie ograniczenia techniczne z bardziej fundamentalnymi. Powodem, dla którego nie mamy wielu graficznych języków komputerowych, jest to, że nie wiemy, jak zrobić to dobrze (i nie wiemy, czy da się to zrobić dobrze). Jestem świadomy LabView i słyszałem dość dziwek na temat robienia skomplikowanych rzeczy lub zmieniania prostych rzeczy. Nie potrzebujemy też mocniejszych komputerów do zaprojektowania takiego języka, więc spróbuj naszkicować przykładowe programy w tak hipotetycznym języku.
David Thornley,