Co to znaczy, że „język A jest pisany w języku B”?

31

Często słyszę termin, że język A jest napisany w języku B. Na przykład PHP zostało napisane C , C # jest napisane w C ++ .

Czy ktoś może wyjaśnić, co to znaczy i czy to w ogóle jest poprawne? Czy to ma coś wspólnego z kompilatorem tłumacza używanym przez język?

Ponadto na jakich czynnikach opiera się wybór języka implementacji?

Songo
źródło
19
Ściśle mówiąc, „PHP zostało napisane w C” jest błędne. Język jako taki jest formalną definicją, dlatego nie jest napisany w innym języku programisty (ale raczej w języku angielskim); tylko kompilator, interpreter i / lub biblioteka mogą być napisane w C, C ++ lub cokolwiek innego. W praktyce dla wielu języków istnieje jeden dominujący kompilator lub tłumacz, a nie wprowadza się rozróżnienia między definicją języka a implementacją.
user281377,
Co ciekawe, BCPL napisano głównie w BCPL
OldCurmudgeon,
7
PHP „per se” nie jest formalną definicją. To jest program C.
Kaz
8
s/written/implemented/i jest o wiele wyraźniejsze.
TMN
2
@ugoren Było wiele kompilatorów C napisanych w asemblerze. Jednak nie w tym wieku.
Ross Patterson

Odpowiedzi:

30

Większość języków programowania można podzielić na dwie kategorie: języki interpretowane i skompilowane.

Skompilowany język jest tłumaczony przez kompilator na kod maszynowy , język, który CPU wykonuje bezpośrednio krok po kroku. Z kolei język interpretowany korzysta z pośrednika, tłumacza , do uruchomienia kodu języka. Interpreter sam jest innym programem, zwykle sam skompilowanym do kodu maszynowego.

PHP jest językiem interpretowanym. Potrzebujesz osobnego programu do uruchomienia kodu PHP, komputer nie uruchamia programu bezpośrednio. Ten osobny program, interpreter PHP, jest napisany w C.

C # jest językiem skompilowanym, ale nie jest skompilowany do kodu maszynowego. Zamiast tego jest kompilowany do specjalistycznego języka, kodu bajtowego, do uruchomienia na maszynie wirtualnej. Java jest kolejnym przykładem takiej konfiguracji. Można to postrzegać jako hybrydę kompilacji i interpretacji, gdzie maszyna wirtualna jest tłumaczem. Maszyna wirtualna dla C # (CLI lub Common Language Infrastructure ) jest napisana w C ++.

Inne przykłady to:

  • Python: Interpreter języka Python kompiluje kod Pythona do kodu bajtowego Pythona, a następnie interpretuje kod bajtowy. Sam interpreter jest napisany w C. Od tego czasu dodano nowe implementacje, w tym kompilację Pythona do uruchamiania na tym samym interfejsie CLI używanym w języku C #, o nazwie IronPython , i taką, która działa na maszynie wirtualnej Java, Jython . Aby ukończyć okrąg, istnieje wersja Python napisana w (podzbiorze) Python, PyPy .
  • Ruby: Ruby początkowo był czysto interpretowanym językiem, ale najnowsza wersja została zmieniona na używanie kodu bajtowego. Również dla Ruby istnieje projekt, który kompiluje się do CLI, o nazwie IronRuby , i jeden dla VM VM, JRuby .
Martijn Pieters
źródło
Przepraszam, czym różni się maszyna wirtualna od tłumacza? Nie rozumiem, jak użycie jednego jest w połowie drogi do kompilacji. Mówisz, że kod bajtowy jest w połowie skompilowany?
Philip,
1
@Philip: Kod bajtowy nie jest kodem maszynowym; więc zamiast dostarczać procesorowi bezpośrednich instrukcji, nadal potrzebujesz interpretera, aby pobrać kod bajtowy i zinterpretować go, przetłumacz go na instrukcje maszynowe. Zaletą jest to, że maszyna wirtualna jest łatwiejsza do przeniesienia na inne architektury i można zastosować sztuczki, takie jak kompilacja JIT .
Martijn Pieters,
Czy ktoś uważa, że ​​termin „skompilowany” został rozcieńczony w celach marketingowych?
Philip,
2
Zaraz! Cofam tamto. Przez jakiś czas szedłem tam złą drogą. Zakładałem, że „skompilowany” oznacza przekształcenie w kod maszynowy i tylko kod maszynowy, co w rzeczywistości nie jest prawdą. To tylko termin na przetłumaczenie kodu na inny kod. Może to być kod maszynowy, kod bajtowy lub dowolny inny język. Okazuje się, że istnieją kompilatory PHP, więc można powiedzieć tylko, że jest to „typowo” interpretowane.
Philip,
Również dobre źródło: youtube.com/watch?v=e4ax90XmUBc
Adam
34

Zasadniczo masz rację. Jeśli powiedziane jest, że Ruby jest napisane w C, oznacza to, że tłumacz języka i części podstawowej biblioteki są napisane w C.

Tak więc interpreter języka Ruby to program w języku C, który pobiera plik tekstowy jako dane wejściowe, przetwarza go, a następnie wywołuje funkcje znajdujące się w innym pliku tekstowym (jeśli jest napisany w języku Ruby) lub skompilowanym kodzie C, podobnie jak podstawowa funkcjonalność, która wymaga aby uzyskać bezpośredni dostęp do zasobów systemowych, takich jak pamięć, system plików i inne. I niektóre funkcje wymagające bardzo wysokiej wydajności.

Więc masz różne części języka, które mogą lub muszą być napisane w innych językach. Nic nie powstrzyma cię przed napisaniem interpretera w C i bibliotek w C ++ (choć może utrudni to kilka rzeczy). Możesz nawet mieć wiele kroków i użyć języka, który jest bardzo dobry w przetwarzaniu tekstu, aby wygenerować pewne dane pośrednie, które następnie są przetwarzane przez jakiś kod C.

Czynniki decyzji mogą być takie same jak w przypadku innych złożonych aplikacji. Wydajność jest jedna. Możliwość pisania kodu, który ma bezpośredni dostęp do zasobów systemowych. W większości przypadków musi to być język skompilowany (choć teoretycznie można napisać interpreter języka Ruby w Pythonie). Dostępność w różnych systemach jest ważna, jeśli chcesz, aby Twój język działał w systemach Linux, Win, OS X i innych.

Thorsten Müller
źródło
Czy ktoś wie, dlaczego widzę trzy głosy poparcia dla mojej odpowiedzi w chwili, gdy ją opublikowałem?
thorsten müller
1
Widzę teraz cztery, ale nie jestem pewien, o co pytasz? Czy opinie były zbyt szybkie? Jeśli tak, cóż, dużo oczu na pytanie (trzy prawie równoczesne odpowiedzi), a twoja odpowiedź jest dobra.
yannis,
Hmm, tak. Może zapisałem go, a następnie edytowałem, zapisałem ponownie i zapomniałem o pierwszym zapisie (starzeję się). Dla mnie wyglądało to tak, jakbym dostał pierwsze trzy głosy poparcia w momencie, gdy opublikowałem.
thorsten müller
@ thorstenmüller +1 za „Nic nie powstrzymałoby cię przed napisaniem interpretera w C i bibliotek w C ++” Chciałem cię o to zapytać. Czy istnieją jakieś znane implementacje, w których interpreter / kompilator jest w jednym języku, a biblioteki podstawowe w innym języku?
Songo,
@ thorstenmüller Zdarzyło mi się to kilka razy. Jeśli kilka osób przegląda pytanie podczas pisania, w ciągu sekundy lub dwóch z użytkowników, którzy przesłali wiadomość, pojawi się komunikat „Nowa odpowiedź została opublikowana”, aby mogli przejrzeć całą odpowiedź i wyrazić opinię w ciągu 10 sekund twojego opublikowania. Ponadto zmiany dokonane w ciągu 5 minut od opublikowania odpowiedzi nie pojawiają się w historii edycji, co może dodatkowo powodować niewielkie zamieszanie z Twojej strony.
Izkata,
10

Oznacza to po prostu, że większość rdzenia języka A ​​jest napisana w języku B. Jaki „rdzeń języka A” może różnić się w zależności od języka, ale ogólnie rzecz biorąc, zgadujesz, to znaczy, że jest to kompilator lub tłumacz. Decydującym czynnikiem przy wyborze języka, w którym ma być napisany inny język, jest, jak w prawie każdym projekcie, w jakich językach programiści są bardziej zaznajomieni.

To powiedziawszy, „język A jest napisany w języku B” jest nadmiernym uproszczeniem dla większości współczesnych języków. Jeśli weźmiemy Python jako przykład, podczas gdy implementacja referencyjna, CPython , rzeczywiście została napisana w C, istnieją implementacje napisane w innych językach, takich jak Jython (napisany w Javie), IronPython (napisany w C #), PyPy (napisany w Python), CLPython (napisany w Common Lisp), Stackless Python (napisany w C i Python) i Unladen Swallow (napisany w C ++).

Język programowania jest definicją, a jak pokazuje przykład w Pythonie, tak naprawdę nie ma żadnych ograniczeń co do języków, w których można pisać jego kompilator, interpreter i biblioteki. Oczywiście język może być również napisany sam w sobie, poprzez proces o nazwie bootstrapping .

Yannis
źródło
2
Nie nazwałbym Psyco inną implementacją, ponieważ działa jako rozszerzenie CPython.
Martijn Pieters,
@MartijnPieters Według strony jest to również martwy projekt. Oddalony.
yannis,
@YannisRizos Czy Unladen Swallow nie jest również martwy ?
Andres F.,
1
@Songo: Poza tym string.lower(s)jest to funkcja python, która deleguje to do return s.lower(), to jest poprawne. W CPython 3,3 strunowe przypadków operacje są realizowane w C.
Martijn Pieters
3

Z perspektywy używania języka programowania, język programowania jest tylko programem. Może to być kompilator, może to być interpreter lub maszyna wirtualna. Wszystkie te rzeczy są tylko programami komputerowymi i dlatego można je pisać w dowolnym języku.

Tak więc, jeśli chcesz stworzyć własną wersję PHP, możesz zacząć od dowolnego języka, w którym jesteś najbardziej biegły. Następnie napisałbyś program, który potrafi czytać kod sformatowany w PHP i robić wszystko, co mówi specyfikacja PHP . W ten sposób tworzysz język PHP w języku X.

Bryan Oakley
źródło
Ciekawy punkt Więc w zasadzie, jeśli mam wbudowaną funkcję w PHP, explodektóra pobiera Stringi zwraca a Array, jej implementacja (tj. Kod, który będzie działał na łańcuchu w celu wytworzenia tablicy) jest zapisana w C , prawda?
Songo,
@Songo: poprawne. Znów PHP to tylko program, nie różniący się od Worda, Apache, Notatnika, vi czy emacsa. Wczytuje dane i analizuje je zgodnie ze specyfikacją języka, a następnie robi wszystko, co mówi specyfikacja języka.
Bryan Oakley,
Ta odpowiedź źle łączy język z implementacją.
Russell Borogove,
Myślę, że jest to najprostsza i najbardziej bezpośrednia odpowiedź i nie rozumiem, jak to się z nią łączy. Sugeruje nawet, że może istnieć więcej niż jedna implementacja PHP. Jest tak naprawdę kilka oryginalnych PHP i Facebook, a mogą być też inne.
Warren P,
@ RussellBorogove: czy nie uważasz, że „z perspektywy używania języka programowania” pomaga wyjaśnić odpowiedź? Pamiętaj, że mamy do czynienia z absolutnym początkującym z tym pytaniem, więc poświęcenie małej precyzji w celu zilustrowania tej kwestii jest uczciwe, IMO.
Bryan Oakley
3

Bardzo podobnym sformułowaniem o zupełnie innym znaczeniu jest „pisanie języka A ​​w języku B”, np. „Pisanie C w Javie”.

Opisuje kod, który jest poprawny pod względem składniowym w jednym języku, ale używa struktur, idiomów i konwencji z innego języka. W przykładzie „pisania C w Javie” oznakami tego byłyby deklaracje wszystkich zmiennych lokalnych na górze każdej metody, przy użyciu stałych całkowitych zamiast wyliczeń, przy użyciu identyfikatorów_z_podpisami itp.

Zazwyczaj dzieje się tak, gdy ktoś długo pracował z jednym językiem (szczególnie, gdy pracował tylko z tym językiem) i jest zupełnie nowy w obecnym języku (lub nie jest zainteresowany pisaniem czystego kodu).

Michael Borgwardt
źródło
„CPython jest napisany w C” zdecydowanie nie oznacza „ten użytkownik pisze w Pythonie tak, jak to było w C”. Oznacza to, że CPython (Python.exe w systemie Windows, / usr / bin / python w systemie Unix) jest napisany w C.
Warren P
@Warren P: jasne, ale frazy są bardzo podobne, więc ludzie, którzy nie znają żadnego z nich, mogliby łatwo znaleźć tutaj wyjaśnienie.
Michael Borgwardt,
3

Technologia jest z natury iteracyjnym procesem. Zaczynamy od prostych narzędzi, a następnie używamy tych narzędzi do tworzenia lepszych. Językami pierwszego zestawu były prawie 1: 1 tłumaczenia znormalizowanych kodów bajtowych instrukcji dla układu; architektura 8086 i jej asembler stały się dominujące w stosunku do innych architektur, takich jak Z80, RISC itp., i dlatego zaczęliśmy opracowywać języki, które można trawić w zestawie 8086, takich jak FORTRAN, COBOL, Pascal i C. Program, który interpretuje kod źródłowy języki te muszą być napisane w coś bardziej prymitywnego, w przeciwnym razie skończysz na kłótni z kurczakiem i jajkiem; jeśli kod źródłowy pierwszego kompilatora C został napisany w C, to co skompilowało ten kod źródłowy C i czy z definicji nie byłby to pierwszy kompilator C?

Zasadniczo należy rozumieć, że „C # jest napisany w C ++”, co oznacza, że ​​pierwszy i / lub najpopularniejszy kompilator oraz biblioteki wykonawcze / podstawowe, które są zgodne ze specyfikacją języka C # (te są Microsoft .NET Framework i kompilatorem wiersza poleceń program CSC.exe) są napisane w C ++.

KeithS
źródło
0

„Język A jest napisany w języku B” oznacza, że ​​jedyną implementacją języka A ​​(lub jedynym powszechnie używanym) jest ten, który jest faktycznie projektem opracowanym w języku B i jedynym kompletnym, aktualnym specyfikacja A jest kodem źródłowym B, który implementuje go w taki sposób, że jeśli dokumentacja i program B nie zgadzają się, program B jest zwykle uważany za prawidłowy.

Kaz
źródło
Nie ma jednej wiarygodnej implementacji C ++. W przypadku C ++ specyfikacja jest poprawna, a niezdefiniowane zachowanie w specyfikacji może zrobić cokolwiek w twojej implementacji. Więc nie, to nie jest poprawne.
Warren P,
Nie rozumiem, co poprzedni komentarz ma wspólnego z moją odpowiedzią. Nie wypowiedziałem się ogólnie o wszystkich językach, więc kontrprzykład C ++ nie ma zastosowania. Stwierdzenie w formie „A jest napisane w B”, gdzie A oznacza „C ++”, nie ma sensu, z wyjątkiem sytuacji, gdy B jest „angielski”.
Kaz