Czy języki dynamiczne są zawsze interpretowane?

18

Patrząc na większość (jeśli nie wszystkie) dynamiczne języki (np. Python, PHP, Perl i Ruby), wszystkie są interpretowane. Popraw mnie, jeśli się mylę. Czy jest jakiś przykład dynamicznego języka, który przechodzi przez fazę kompilacji? Czy język dynamiczny jest identyczny z językiem interpretowanym?

Joshua Partogi
źródło
4
Zdefiniuj język dynamiczny, czy jest on dynamicznie wpisywany?
BenjaminB
3
Cel C wykazuje wiele właściwości „dynamicznych”.
Edward Strange
4
@Job, można to robić z Lispem przez dziesięciolecia. I jest zarówno skompilowany, jak i dynamicznie wpisany. Tak więc nigdy nie było dokładnej granicy między kompilacją a interpretacją.
SK-logic
2
@Darien Możesz to skompilować w czasie wykonywania, a następnie wykonać kod. Ściśle mówiąc, nie jest to interpretacja.
xmm0
3
@Darien Nic nie stoi na przeszkodzie, aby kompilator przechowywał informacje z tablicy symboli w skompilowanym pliku binarnym i generował kod, aby uzyskać do nich dostęp w czasie wykonywania. To prawda, że ​​niektóre języki nadają się do interpretacji bardziej niż kompilacji, ale chodzi o to, że można mieć kompilator dla tego języka. Inną ważną rzeczą do odnotowania jest to, że niektórzy ludzie zakładają, że kompilator musi wygenerować jakiś kod maszynowy. W praktyce istnieją kompilatory, które po prostu wykonują transformację na poziomie źródła w dwóch językach (lub nawet w tym samym języku, jak niektóre minizowniki Javascript).
xmm0

Odpowiedzi:

33

Patrząc na większość (jeśli nie wszystkie) dynamiczne języki [tj. Python, PHP, Perl i Ruby], wszystkie są interpretowane.

Nie prawda. Możesz skompilować źródło Pythona. To jeden dowód egzystencjalny.

Istnieją interpretery dla języków o typie statycznym i kompilatory do języków o typie dynamicznym. Te dwie koncepcje są ortogonalne.

Uwaga dodatkowa: Ogólnie rzecz biorąc, język jest po prostu tym: językiem z zestawem konstrukcji składniowych do wyrażania semantyki. Jeśli piszesz Python na tablicy, nadal nazywa się Python! Jest to implementacja, która może być tłumaczem lub kompilatorem. Bycie statycznym lub dynamicznym (rodzaj hybrydy obu) jest właściwością języka, podczas gdy wykonywanie programu przez interpretację lub kompilację jest właściwością implementacji.

xmm0
źródło
19
Do jakiej precyzji muszą wcięcia pasować na tablicy, aby Python był poprawny pod względem składniowym? ;)
edA-qa mort-ora-y
1
Nie można skompilować Pythona. PYC przyspiesza tylko obciążenie modułu. Py2exe po prostu osadza interpretator w pliku exe z plikiem źródłowym.
BenjaminB
8
@ Ubiquité: .pycpliki są kodem bajtowym. Kod źródłowy Pythona został przeanalizowany, zoptymalizowany i skompilowany w celu ich utworzenia. Instrukcje kodu bajtowego są stosunkowo wysokie, a najpopularniejszą jego implementacją jest zwykły interpreter (dla kontrastu, spójrz na PyPy, który JIT kompiluje kod bajtowy do bardzo sprytnego kodu maszynowego w czasie wykonywania), ale Python nie jest mniej skompilowany niż Java lub DO#. Python jest „nieskompilowany” tylko wtedy, gdy „kompilacja” została ograniczona do natywnej kompilacji z wyprzedzeniem , ale nikt nic o tym nie powiedział i ogólnie może odnosić się do dowolnej transformacji języka na język.
4
@ Ubiquité: Tak, to prawda, ale nie ma to związku z twierdzeniem, że „Nie można skompilować Pythona” lub czy można skompilować Pythona. Przede wszystkim miksujesz, Pythona CPythonpodczas gdy ten drugi jest implementacją tego pierwszego, tak też jest PyPy.
phant0m
2
@ClemC WSZYSTKIE właściwości języka są wbudowane w kompilator lub interpreter, w przeciwnym razie interpreter lub kompilator jest czymś innym.
Pieter B
15

Common Lisp jest dynamicznie (i silnie) typowany i zwykle kompilowany .

Ponieważ tę dynamikę osiąga się w czasie wykonywania, istnieje kilka dyrektyw, których można użyć w kodzie źródłowym, aby zapewnić kompilator, że symbol będzie zawierał tylko określony rodzaj wartości, dzięki czemu kompilator może zoptymalizować wygenerowany kod i zwiększyć wydajność.

Federico klez Culloca
źródło
12

C # 4.0 obsługuje typy dynamiczne (późne wiązanie) i jest kompilowany.

Matt H.
źródło
4

node.js jest oparty na silniku javascript Google V8. Wersja 8 wykonuje kompilację środowiska wykonawczego. V8 jest niesamowicie szybki, biorąc pod uwagę ten fakt. Wystarczy sprawdzić http://shootout.alioth.debian.org i porównać V8 z dowolnym z wyżej interpretowanych języków.

LLeo
źródło
3

Nie - z pewnością można skompilować języki dynamiczne.

Istnieje nawet kilka dynamicznych języków, które zawsze są kompilowane zgodnie z projektem (np. Clojure).

Pytanie dotyczy jednak ważnego pokrewnego punktu: chociaż można dynamicznie kompilować języki dynamiczne, często nie można kompilować dynamicznych języków do kodu, który jest tak wydajny jak język o typie statycznym . Wynika to z faktu, że istnieją pewne nieodłączne cechy dynamicznych języków, które wymagają sprawdzania czasu wykonywania, które byłyby niepotrzebne w statycznie skompilowanym języku.

Przykład: języki, które pozwalają na łatanie w czasie wykonywania obiektów (np. Ruby) często wymagają inspekcji obiektu (z wyszukiwaniem mieszającym lub podobnym) za każdym razem, gdy wywołujesz metodę na obiekcie. Nawet jeśli zostanie to skompilowane, kompilator będzie musiał wygenerować kod, aby wykonać wyszukiwanie metody w czasie wykonywania. W pewnym stopniu wyszukiwanie tej metody nie różni się od tego, co musiałby zrobić tłumacz.

Dodaje to znaczny narzut w porównaniu do wywołania metody w języku takim jak Java, gdzie poprawna metoda może zostać ustalona przez kompilator na podstawie definicji klasy i zredukowana do prostego wywołania funkcji w kodzie natywnym.

Uważam, że ten efekt bardziej niż cokolwiek innego powoduje, że dynamiczne języki mają średnio niższą wydajność niż ich statycznie skompilowane odpowiedniki. Jak widać z wadliwych testów , to języki o typie statycznym (C, Java, Fortran itp.) Są najszybsze w przypadku języków dynamicznych (Perl, Python, Ruby, PHP itp.) Na dole rankingu.

mikera
źródło
2

Dawno, dawno temu, BASIC był interpretowany. Niektóre warianty BASIC-a miały dynamiczne pisanie. Możesz też uzyskać dla nich kompilatory.

(Było to w czasach 100 000 dyskietek, kiedy dinozaury wciąż wędrowały po ziemi i zjadały niczego nie podejrzewających programistów na śniadanie).

szybko. teraz
źródło
... ale tylko wtedy, gdy używali GOTO. (Co było oczywiście dość powszechne, jeśli rozwijały się w języku BASIC. AHA! To wyjaśnia!)
Mason Wheeler
BASIC w czasie projektowania był językiem skompilowanym.
AProgrammer
2

Różne implementacje Smalltalk radzą sobie z tym inaczej, ale kilka z nich kompiluje się do kodów bajtowych działających na wysoko wydajnej maszynie wirtualnej.

Randy Coulman
źródło
2

W rzeczywistości większość tak zwanych języków „interpretowanych” przechodzi / pozwala na kompilację na czas, aby przyspieszyć jej działanie. Niektóre z nich muszą zostać skompilowane do kodu bajtowego, zanim będzie można je uruchomić.

W rzeczywistości dynamiczne i interpretowane są całkowicie 2 różnymi pomysłami, choć istnieje korelacja. Ponieważ kiedykolwiek pisanie dynamiczne sprawia, że ​​ich praca jest łatwiejsza i szybsza, nie mieliby nic przeciwko temu, by kod działał nieco wolniej, ale był przenośny.

użytkownik658991
źródło
1

Chrome, IE9 i Firefox 3.1+ kompilują JavaScript do natywnych plików binarnych, a JavaScript jest dynamicznie wpisywany.

Myślę, że powodem, dla którego języki dynamiczne były z reguły interpretowane, jest to, że dynamiczne pisanie i tłumaczenie (a ściślej brak kompilacji) są zwykle cechami użytecznymi dla języków skryptowych i ogólnie zadań skryptowych.

Wydajność również nie jest (nie była) przedmiotem zainteresowania programów, które zostały napisane w tych językach, więc znowu koszty dynamicznego pisania i tłumaczenia nie były tak duże, jak w przypadku języków ta wartość wydajności.

Rei Miyasaka
źródło
1

Python jest zazwyczaj kompilowany. Wprawdzie skompilowany do kodu bajtu, który jest następnie interpretowany.

Perl działa w podobny sposób.

Common Lisp zazwyczaj skompiluje się do kodu natywnego lub bajtowego. Różni się to między implementacjami (i do pewnego stopnia w ramach implementacji, w zależności od różnych ustawień optymalizacji).

Vatine
źródło
-5

Tak. Wszystkie języki dynamiczne są językiem interpretowanym (ale język interpretowany może nie być dynamiczny).

Powód jest prosty: jeśli jest dynamiczny, potrzebuje interpretera, aby wykonać dynamizm na poziomie kompilacji binarnej.

dawny. : kiedy wstawiamy dane do zmiennej PHP, a następnie innej zmiennej innego typu, nasz program nie mógł się skompilować do kodu binarnego, ponieważ każdy typ ma swój własny format reprezentacji binarnej; interpreter dynamicznie zarządza zmianami na poziomie binarnym

Czysty umysł
źródło
2
Źle. Języki dynamiczne mogą być kompilowane (a czasem bardzo wydajnie, np. Przy użyciu JIT i adaptacyjnych technik kompilacji)
Basile Starynkevitch
„Z grubsza, kompilacja JIT łączy szybkość kompilowanego kodu z elastycznością interpretacji, z narzutem interpretera ...” en.wikipedia.org/wiki/Just-in-time_compilation twój program nie kompiluje: jest kompilowany przez tłumacz dla ciebie
ClearMind
Przeczytaj artykuły związane z SELF
Basile Starynkevitch
Pewnie. Twój link wspomina: „Jedną z cech Self jest to, że jest oparty na tym samym systemie maszyn wirtualnych, co wcześniejsze systemy Smalltalk. Oznacza to, że programy nie są samodzielnymi jednostkami, ponieważ są w językach takich jak C, ale potrzebują ich całe środowisko pamięci w celu uruchomienia. ” not stand-alone = nie skompilowany binarnie maszyna wirtualna jest potrzebna do wykonania kompilacji binarnej
ClearMind
1
Twoja definicja kompilatora jest zbyt restrykcyjna. Nie każdy kompilator tworzy binarny plik wykonywalny. Dla ostatniego kontrprzykładu, zbadaj implementację SBCL . Przeczytaj najnowszą Dragon Book i Lisp In Small Pieces
Basile Starynkevitch