Dlaczego studiowanie interpretera seplenienia w seplenienie jest tak ważne?

30

Widziałem wiele programów CS i sugestii dotyczących uczenia się dla nowych programistów, którzy wzywają początkującego programistę do studiowania interpretera lisp, który jest specjalnie napisany w lisp. Wszystkie te witryny mówią coś podobnego do „to intelektualna rewelacja”, „jest to oświecenie, które powinien mieć każdy poważny programista” lub „pokazuje relacje sprzętowe / programowe” i inne niejasne stwierdzenia, szczególnie z tego artykułu zaczerpniętego z ten renomowany poradnik .

Ogólne zdanie mojego pytania brzmi: w jaki sposób seplenienie osiąga powyższe cele i dlaczego seplenienie? Dlaczego nie jakiś inny język?

Pytam o to, ponieważ właśnie skończyłem pisać interpreter schematów w schemacie (wzięty z SICP http://mitpress.mit.edu/sicp/ ), a teraz piszę interpretera schematów w schemacie i walczę o to, by legendarne objawienie który ma pochodzić konkretnie z tego pierwszego. Szukam konkretnych szczegółów technicznych między dwoma językami, które mogę wykorzystać w swoich tłumaczach schematów, aby uzyskać zrozumienie na temat działania programów.

Dokładniej:

Dlaczego akcentowanie nauki tłumacza napisanego w języku, który interpretuje, jest tak podkreślone - czy to tylko świetne ćwiczenie umysłowe, aby zachować oryginalny język i język zbudowany, czy też istnieją konkretne problemy, których rozwiązania można znaleźć tylko w naturze Oryginalny język?

W jaki sposób tłumacze lisp demonstrują dobre koncepcje architektury dla przyszłego projektowania oprogramowania?

Czego bym przegapił, gdybym wykonał to ćwiczenie w innym języku, takim jak C ++ lub Java?

Jakie jest najczęściej używane na wynos lub „narzędzie mentalne” z tego ćwiczenia? **

** Wybrałem odpowiedź zrobiłem, bo nie zauważyłem, że zyskały więcej od tego ćwiczenia umiejętności w projektowaniu narzędzi analizowania w głowie niż jakikolwiek inny jednym narzędziu i chciałbym znaleźć różne metody przetwarzania, które mogą działać lepiej dla programu interpreter niż interpreter python.

Ma-at
źródło
4
@gnat Niezupełnie rada dotycząca kariery, raczej pytanie „co jest takiego wspaniałego w Lisp”.
Robert Harvey
1
@RobertHarvey, że ten link służy nie tylko karierze, ale także poradom edukacyjnym , miałem na myśli to. Ale, cóż, Lisp-is-so-great jest również prawdopodobnie dobrym dopasowaniem
komnata
1
Wygląda na to, że pytasz, czego nauczysz się podczas określonego ćwiczenia. Twoja powściągliwość jest znakiem lenistwa, kluczem do dobrego programisty, ale niezależnie od tego, jedynym sposobem, aby dowiedzieć się, czego nauczysz się podczas ćwiczenia, jest zrobienie tego i zobaczenie. Nikt nie może ci powiedzieć, czego się nauczysz, po prostu musisz to zrobić.
Jimmy Hoffa
2
Chociaż to pytanie dotyczy edukacji jako całości, nie sklasyfikowałbym jej jako „porady edukacyjne” w sposób „Jakiego języka powinienem się nauczyć?” jest. Oznacza to, że nie jest on specyficzny dla określonego rodzaju kursu lub pracy. W rzeczywistości, jeśli usuniesz niektóre z modnych słów edukacyjnych, jest to pytanie o języki programowania jako całość, których odpowiedzi omawiają cechy językowe. To naprawdę nie jest specyficzne dla Lisp, ale może być zastosowane do innych języków homoiconic, takich jak xslt. Nie powiem więc, że jest to idealne pytanie, tylko że nie jest to po prostu „rada kariery”.
TheRubberDuck

Odpowiedzi:

17

Ryzykując odpowiedź „ja też”, jeśli spróbujesz, zobaczysz ...

Jeśli uczysz się języków komputerowych, możesz odnieść wrażenie, że przynajmniej w połowie chodzi o analizę. Jeśli nauczysz się Lisp, zdasz sobie sprawę, że analiza składni powierzchni jest niczym więcej niż wygodą dla ludzi (jak większość z nas), którzy nie lubią wielu irytujących pojedynczych nawiasów.

Wtedy możesz zdać sobie sprawę, że za tę wygodę zapłacono wysoką cenę. W Lisp tworzenie programu i uruchamianie go jest trywialne. W innych językach jest to technika zaawansowana, np. Mnożenie cyframi rzymskimi.

Oczywiście prawie wszyscy pytają „kto musi to zrobić?” Cóż, bardzo dobrze widać, że otwiera całą perspektywę rzeczy, o których nigdy nawet nie zdawałeś sobie sprawy, że nie możesz tego zrobić wcześniej. Możesz to zrobić w innych językach, ale nie tak łatwo.

WSTAWIONO, aby odpowiedzieć na komentarz Izkaty:

  • Program do zrozumienia języka naturalnego SHRDLU działał, tłumacząc angielskie stwierdzenie lub pytanie na program w dialekcie Lisp o nazwie MICRO-PLANNER i wykonując go.
  • Programy manipulujące programami, na przykład w celu ich uproszczenia lub udowodnienia, że ​​są poprawne, są naturalnie napisane w Lisp.
  • Użyłem generowania programu w programie do zrozumienia scen wizualnych, w których musiał on poradzić sobie ze wszystkimi symetriami zdolnymi do tworzenia trójwymiarowych obiektów, bez mnożenia kodu.
  • Wszystko, co ma związek z logiką i dowodzeniem twierdzeń, dotyczy manipulacji wyrażeniami logicznymi, które są formą programu.
  • Matematyka symboliczna, taka jak całka symboliczna lub rachunek różniczkowy, polega na manipulowaniu wyrażeniami matematycznymi, które są jak miniaturowe programy.
  • Każdy problem związany z generowaniem kodu lub bardziej terminową „częściową oceną” jest naturalny w Lisp. Zrobiłem to dawno temu dla programu mostkowego bazy danych. Zrobiłem to w C, co nie było tak łatwe jak Lisp, ale wpadłem na pomysł od Lisp. Uznano to za technikę, której prawie nikt w tym czasie nie mógł (zwłaszcza głowice COBOL). Może więcej teraz, mam nadzieję.

... to tylko kilka ...

Wtedy zdajesz sobie sprawę, że niektóre rzeczy, które są dziś uważane za „nowoczesne”, były w Lisp od 40 lat. Jak programowanie funkcjonalne. Jak śmieci. Jak zamknięcia.

Nie oznacza to, że współczesne języki nie mają nowych dobrych pomysłów, takich jak OOP itp. Ale jeśli nauczysz się Lisp, poszerzy to twoją perspektywę.

Mike Dunlavey
źródło
You can do it in other languages, but not nearly so easily.- Lubić? (Wydaje mi się, że pytanie jest takie, ponieważ takie wypowiedzi są często wypowiadane, ale prawie nigdy nie są bardziej szczegółowe)
Izkata
Najpierw pomyślałem, że świat został zrewolucjonizowany, kiedy zdałem sobie sprawę, że javascript może wydrukować swój własny kod źródłowy, a obiekty można przechodzić w celu uzyskania literału łańcuchowego, który można wywołać w literale obiektowym. Potem zdałem sobie sprawę, że Perl miał to wszystko razem z $ Data :: Dumper :: Deparse, a potem zdałem sobie sprawę, że lisp miał to na zawsze. Zrozumienie interpretatorów odblokowuje moc, która zawsze służyła do budowania żywych modułów, aw Lisp jest to bardziej dostępne niż w jakimkolwiek innym języku.
Dmitry
zabawne jest to, że programiści Lisp znający wewnętrzne elementy Lisps mogą zawsze tworzyć własne nakładki Lisp na dowolny dynamiczny język, od javascript po bash, perl lub python; ładnie ładuje bootpapy z dostępnego środowiska.
Dmitry
19

Prostą odpowiedzią na twoje pytanie jest wypróbowanie Lisp, najlepiej w połączeniu z SICP . Wtedy zostaniecie oświeceni.

To mówi...

Kod to dane
Większość języków dokonuje wyraźnego rozróżnienia między kodem a danymi; Lisp nie. Umożliwia to na przykład trywialne pisanie parsera Lisp w Lisp i manipulowanie kodem Lisp w Lisp. Najlepszy opis tego oświecenia, jaki znalazłem, to Natura Lisp .

Jest to częściowo prawdą, ponieważ składnia języka jest tak prosta. Umożliwia Lisp (np. Metaprogramowanie) rzeczy, które w innych językach są niepraktyczne, ponieważ przeszkadza w tym składnia.

Dalsza lektura
Pokonywanie średnich

Robert Harvey
źródło
3
Drugi akapit nie ma sensu: homoiconicity! = Prosta składnia; prosta składnia ułatwia napisanie parsera Lisp w dowolnym języku (zobacz to ). Trzeci akapit jest niejasny, wymaga przykładów.
@MattFenwick to prawda, że ​​homoikoniczność można osiągnąć za pomocą złożonej składni, ale byłoby to niezwykle trudne. Można słusznie założyć, że jeśli masz do czynienia ze składnią homoikoniczną, będzie ona prosta, jeśli nie z innego powodu niż wymagana od niej spójność, która sprawi, że będzie ona niewiarygodnie łatwiejsza niż składnia niehomoniczna. Chociaż twój drugi punkt jest dobry, LISP jest łatwy do przeanalizowania, ponieważ jest to prosta składnia, a nie z powodu homoiconicity (nawet jeśli homoiconicity jest przyczyną tej prostoty)
Jimmy Hoffa
1
W każdym razie, nałożenie wartości danych i interpretowanie jej jako programu jest niewielkie. To miła rzecz. Programowanie według konfiguracji jest proste, gdy wszystko, co musisz zrobić, to napisać interpreter dla danych konfiguracyjnych. Zaawansowane transformacje matematyczne (trudne do zaimplementowania w stanowych wersjach językowych) są często „redukowane” do zwykłych syntaktycznych transformacji czystego fragmentu Lisp.
nomen
1
@MattFenwick: Usunąłem słowo „Homoiconicity” z mojej odpowiedzi.
Robert Harvey
1
Chciałbym dać więcej niż +1 za The Nature of Lisp; Nigdy nie widziałem tak wspaniałego wyjaśnienia.
Doval
9

Dlaczego akcentowanie nauki tłumacza napisanego w języku, który tłumaczy?

Ogólnie rzecz biorąc, studiowanie tłumacza daje wgląd w jego język i funkcje. Ogólnie rzecz biorąc, nauka kodu w języku programowania jest jak ćwiczenie języka mówionego poprzez słuchanie i czytanie: zapoznaje cię z tym, co potrafi ten język, jak jest używany i jakie są typowe „idiomy”. Mówiąc dokładniej, Lisp jest językiem homoiconic, co oznacza, że jego składnia wyrażeń jest taka sama jak składnia danych. Pisanie kodu w Lisp wygląda okropnie, jakbyś spisywał listę i odwrotnie. Zatem interpretacja kodu Lisp za pomocą kodu Lisp jest tak prosta, jak przeglądanie list za pomocą cari cdr.

Jak powinienem wykorzystać to ćwiczenie, aby jak najlepiej wykorzystać je koncepcyjnie?

Pomyśl o tym, jak interpreter interpretuje siebie - w wielu meta-kołowych implementacjach interpretera (w których interpretuje się język homoiconic) może po prostu „przejść” przez funkcję. Na przykład Aby wdrożyć car, wystarczy wziąć carargument. Odciąża to mechanizmy przechowywania danych i skupia się na funkcjonalności.

W jaki sposób tłumacze lisp demonstrują dobre koncepcje architektury dla przyszłego projektowania oprogramowania?

Tłumacze ustni mogą być bardzo skomplikowani, co zachęca do dobrej architektury przy ich projektowaniu. Mając to na uwadze, ten jest bardziej zależny od indywidualnego tłumacza.

Czego bym przegapił, gdybym wykonał to ćwiczenie w innym języku, takim jak C ++ lub Java?

Te języki nie są homoikoniczne, więc nie korzystają z wdzięku i prostoty meta-okólnego tłumacza Lisp. To sprawia, że ​​ćwiczenie jest trudniejsze i być może mniej powszechne, ale nie powiedziałbym, że jest tak naprawdę mniej korzystne.

Jakie jest najczęściej używane na wynos lub „narzędzie mentalne” z tego ćwiczenia?

Nie jestem pewien, czy mam na to dobrą odpowiedź; po prostu to, że pomaga zobaczyć, jak działa tłumacz, i, co ważniejsze, majstrować przy nim, aby zobaczyć, jak można łatwo wprowadzić niewielkie zmiany w języku.

TheRubberDuck
źródło
5

Sam LISP ma taką strukturę, że bardzo łatwo go analizować. Jeśli spróbujesz napisać kompilator, zauważysz, że o wiele łatwiej jest, jeśli wszystko w twoim języku jest wyrażeniem i ma niski poziom dwuznaczności. LISP wymusza wszędzie nawiasy, aby wyeliminować dwuznaczności i nie ma żadnych instrukcji, tylko wyrażenia.

Sam fakt, że LISP jest bardzo łatwy do parsowania, zachęca użytkowników do parsowania własnego kodu źródłowego i wykonywania z nim magicznych sztuczek. Granica między danymi a kodem zaciera się i możesz łatwo robić rzeczy, które normalnie wymagają sporo wysiłku, takie jak odbicie, dynamiczne przepisywanie kodu, wtyczki i serializacja.

To jest sedno tego. Ćwiczenie prawdopodobnie ma na celu dać ci wgląd w to, co jest możliwe, gdy kod można łatwo oddzielić od siebie.

Alexander Torstling
źródło
To nie jest Lisp, który łatwo analizować. Wyrażenia S można łatwo przeanalizować. Ponadto musisz następnie przeanalizować Lisp.
Rainer Joswig
@Rainer: Czy to nie tylko nitpicking? W moim świecie parsowanie oznacza przejście od tekstu do AST, co nie mówi nic o interpretacji poleceń.
Alexander Torstling
W C ++ analizator składni wykryje nieprawidłową składnię deklaracji funkcji. W Lisp nie. Czytelnik nie wie nic o języku programowania Lisp. Parser C ++ zna pełną składnię C ++. Czytnik Lisp zna tylko wyrażenia s.
Rainer Joswig
Ach, więc rozumiem, co masz na myśli. To prawda, chociaż nadal uważam, że prosty ewaluator lisp byłby łatwiejszy do zbudowania niż zwykły c ++. Tak robią w SICP, prawda? (Minęło trochę czasu, odkąd to przeczytałem)?
Alexander Torstling
język używany w SICP jest bardzo prosty, nawet pełny. Tłumacz dla małego języka C powinien być również prosty. C ++ jest duży. Niektóre z jego trudności wynikają ze stosunkowo dużej liczby wbudowanych składni. W typowym systemie Lisp większość składni jest zbudowana z makr - poza interpreterem. Makra implementują składnię i mechanizm rozszerzenia dla transformacji źródłowych. Dzięki temu rdzeń jest mniejszy. Ale makra mogą być ogromne. Na przykład implementacja konstrukcji LOOP zawiera ponad 2000 wierszy złożonego kodu makr.
Rainer Joswig
4

Nie jestem pewien, czy to naprawdę ważne dla wszystkich. Możesz odnieść sukces jako programista, nie wiedząc, jak działa interpreter Lisp. Studiując informatykę, należy jednak nauczyć się podstawowych pomysłów Lisp.

Tłumacze Lisp są ważni dla programistów Lisp. Muszą zrozumieć, jak działa Interpreter ([i kompilator] 1 ), aby w pełni zrozumieć, jak używać języka.

Tłumacz języka Lisp jest często używany jako narzędzie w informatyce, aby nauczyć uczniów kilku rzeczy:

Jako narzędzie do nauczania pomocny jest tłumacz Lisp, ponieważ można się go nauczyć i zrozumieć w krótkim czasie. Ponieważ niewielu uczniów już wie o Lisp, uczniowie są na poziomie, jeśli chodzi o naukę ponad koncepcjami.

Rainer Joswig
źródło