Dziesiąta zasada Greenspun (właściwie jedyna reguła) mówi, że:
Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
Pamiętam, że jest kilka artykułów na ten temat, być może dla projektu Quattro (arkusza kalkulacyjnego) Borlanda i być może innych. Google nie jest pomocny, być może nie przychodzą mi do głowy odpowiednie wyszukiwane hasła. Szukam ewentualnych artykułów lub artykułów na poparcie tego roszczenia.
c
language-design
lisp
fortran
casualcoder
źródło
źródło
Odpowiedzi:
Stwierdzenie to hiperbola. Ale są oczywiste oznaki zazdrości Lisp w innych językach. Spójrz na C # i jak staje się on bardziej funkcjonalny z natury. Spójrz na różne platformy zarządzania procesami biznesowymi, workflow i EAI, które robią wszystko, aby umożliwić programowanie systemu bez zmiany programu.
Jest książka na temat języków specyficznych dla domeny autorstwa Martina Fowlera, która mówi o tym, jak robić metaprogramowanie w językach zorientowanych obiektowo. Hiperbola zawiera pewną prawdę.
Paul Graham nazwał Lisp najpotężniejszym językiem, patrząc na listę nowości, które pojawiły się w Lisp , łatwo zrozumieć, dlaczego wiele języków jest bladych w porównaniu.
Sposób na dziesiątą zasadę to programowanie w poliglocie. Uświadomienie sobie, że jeden język / środowisko nie jest złotym młotem. Następnie zamiast tworzyć słabą implementację Lisp ad hoc, możesz po prostu użyć Lisp.
źródło
„Dziesiąta reguła” Greenspuna była trochę nieuczciwym warknięciem. Jeśli rozciągnie się wystarczająco daleko, jeśli sprawisz, że obejmie on „dowolny system skryptowy lub konfiguracyjny”, wtedy odpowiedź na to pytanie będzie musiała brzmieć „tak”, ponieważ konfiguracja jest czymś, co w pewnym stopniu wymaga każdy nietrywialny program i skryptowanie jest tylko nieco mniej powszechny, gdy przesuwasz się w górę skali złożoności.
Z drugiej strony, spójrz na GOAL , wariant Lisp wymyślony przez Naughty Dog do programowania gier. W ogóle nie przypomina bardzo „klasycznego” Lispa. Jest to bardzo imperatywny system z funkcjami zorientowanymi obiektowo, bez interpretera, minimalną obsługą zbierania elementów bezużytecznych (zamiast tego polegającą na ułatwieniach czyszczenia na poziomie środowiska wykonawczego) oraz szeroką obsługą wbudowanego montażu.
Innymi słowy, kiedy próbowali wykorzystać Lisp do wystarczająco złożonego projektu, odkryli, że aby zrobić coś pożytecznego, musieli zmienić język w ad-hoc, nieformalnie określoną implementację połowy C ++! ;) (I ostatecznie musieli przestać go używać po tym, jak odszedł facet, który zaprojektował GOAL, ponieważ nikt nie rozumiał jego kodu.)
źródło
Co ciekawe, jedna odpowiedź na to pytanie jest już w Programmers SE .
Aby zacytować odpowiednią część:
Aby wyjaśnić tę część, Michael odpowiedział na komentarz:
Biorąc pod uwagę, że ta odpowiedź składa się z odpowiedzi innej osoby w innym miejscu, jest to wiki społeczności.
źródło
Zasada jest żartem, ale jest w tym trochę prawdy. Każdy złożony system zawierałby wiele interpretowanych części (patrz, w jaki sposób „wzorzec interpretatora” jest popularny wśród tych, którzy wierzą we wszystkie te wzorce mumbo-jumbo). Każdy złożony system musi zapewniać pewne środki konfiguracji, często ustrukturyzowane, często interpretowane.
Każdy złożony system najprawdopodobniej będzie miał kilka przebiegów generowania kodu i różne niestandardowe preprocesory w procesie kompilacji (pomyśl o rzeczach takich jak
moc
w Qt lubtablegen
w LLVM).Wiele systemów żongluje złożonymi, podobnymi do drzew strukturami danych, używając zestawu (prawie zawsze) źle zaprojektowanych narzędzi do chodzenia i przekształcania drzew, bardzo przypominających funkcje bibliotek z Common Lisp.
Wszystkie te rzeczy są dostarczane za darmo z Lisp, aw większości przypadków wszystkie te ad hoc, nieplanowane, nie przemyślane wystarczająco dokładnie implementacje byłyby całkowicie gorsze.
źródło
Każdy wystarczająco złożony system będzie miał specyficzne dla domeny koncepcje i wymagania, które są niezwykle trudne do wyrażenia za pomocą abstrakcji języka, w którym pracujesz. To przypadkowo zmusza programistów do tworzenia abstrakcji specyficznych dla domeny, aby zmniejszyć ciężar wypełniania semantycznej luki między językiem programowania i konkretna domena. Kiedy jest już wystarczająco tych abstrakcji, w zasadzie masz tłumacza języka specyficznego dla domeny. Jest to nieunikniona część tworzenia oprogramowania.
źródło
Reguła mogłaby być prawdopodobnie dokładniejsza (i mniej zabawna), ponieważ „każdy duży system oparty na oprogramowaniu będzie wymagany do wdrożenia dynamicznego zachowania”.
Można to zrobić na dwa sposoby -
Duży złożony plik konfiguracyjny z dziesiątkami parametrów i setkami definicji.
Język skryptowy AD-HOC.
„sendmail” jest prawdopodobnie kanonicznym przykładem typu „1”. Nie mogę wymyślić żadnych dobrych przykładów typu „2”, które nie obejmowałyby osadzenia „prawdziwego” języka skryptowego np. Warcraft / LUA, a nawet Netscape / JavaScript.
Problem polega na tym, że dla kilku parametrów można to szybko i łatwo zrobić za pomocą pliku konfiguracyjnego, ale to rozwiązanie tak naprawdę nie skaluje się. Jednak w żadnym momencie nie będzie ekonomicznie zrzucać pliku konfiguracyjnego na korzyść podejścia skryptowego podczas dodawania jednej lub dwóch opcji do pliku konfiguracyjnego. Tak więc kod, który interpretuje plik konfiguracyjny, jest naprawdę źle napisanym interpretatorem.
źródło
To może być prawda, jak stwierdzili inni, wiele programów wymaga konfigurowalności, dlatego zawierają różne interpretery podobne do seplenienia.
Jednak stwierdzenie sugeruje również z uśmieszkiem, że wszystko, czego potrzebujesz, aby stworzyć program, to Lisp i że wszystkie inne języki są gorsze od niego.
Ale to źle, Lisp może być wyrazisty, ale jest też zbyt abstrakcyjny, próbuje ukryć szczegóły platformy i udawać, że w świecie komputerów istnieją tylko listy.
Rzeczywistość programowania o wysokiej wydajności polega na tym, że czasami musimy mieszać się z bitami i bajtami i robić rzeczy specyficzne dla systemu operacyjnego, więc nie jest możliwe zrobienie wszystkiego za pomocą Lisp, jak sugeruje to instrukcja.
Jest raczej na odwrót, bez względu na to, jak skomplikowany, sprytny lub wyrafinowany jest język, który wymyślisz, wszystko to ostatecznie jest po prostu innym sposobem na pisanie asemblera.
źródło
Niezależnie od tego, czy miał być traktowany poważnie, tak jest w przypadku największych projektów C i C ++, nad którymi pracowałem.
Nieprawdą jest to, że niestandardowe języki skryptowe przypominają Common Lisp. Pozytywne przykłady przypominają Scheme (ponieważ mądrzejsi projektanci zintegrowali Guile, SpiderMonkey i Lua zamiast wynaleźć własny język). Najbardziej godnymi DailyWTF przykładami był język podobny do Fortha i język podobny do MUMPSA.
Innym przykładem (nie jestem pewien, czy liczy się jako Greenspunning, ale z pewnością WTF) był interpreter XSLT używany do skryptów ogólnego zastosowania. Było to bardziej podobne do Lisp, ponieważ dodali pętlę sprzężenia zwrotnego, w której dane wyjściowe zostałyby przekształcone XSLT po raz drugi - więc teraz skutecznie masz makra.
Motywem tutaj nie było jednak uzyskanie dostępu do funkcji lispy, ale ominięcie procedur kontroli jakości kodu firmy (co dodawało 3 tygodnie opóźnienia do każdej poprawki błędu. XML uznano za „dane” i wyłączono z procesu).
źródło
Niestety nie!
Podczas gdy najlepiej jest po prostu osadzić prawdziwego interpretera lisp (y) (javascript lub lua alos wykonuje dobrą robotę), dodanie homebrew 4gl do projektu zmniejsza ogólny rozmiar przy jednoczesnym zwiększeniu elastyczności.
Projekty, które „kodują wszystko”, mają znacznie większą liczbę modułów i stają się nieporęczne i nieelastyczne.
źródło