Dlaczego w rozwoju jednego produktu lub oprogramowania używa się wielu języków programowania?

114

Jestem studentem ostatniego stopnia, który chce rozpocząć studia magisterskie z informatyki. Natknąłem się na wiele projektów typu open source, które naprawdę mnie intrygują i zachęcają do brania w nich udziału (CloudStack, OpenStack, moby i Kubernetes, aby wymienić tylko kilka). Jedną z rzeczy, które większość z nich łączy, jest używanie wielu języków programowania (takich jak Java + Python + Go lub Python + C ++ + Ruby). Patrzyłem już na to drugie pytanie, które dotyczy sposobu, w jaki wiele języków programowania ma się ze sobą komunikować: Jak współdziałać dwa różne programy z dwoma różnymi językami?

Chcę zrozumieć wymóg, który zachęca przedsiębiorstwa do używania wielu języków programowania. Jakie wymaganie lub rodzaj wymagania sprawia architekt oprogramowania lub kierownik projektu: „Proponuję użyć języka X dla zadania 1 i języka Y dla zadania 2”? Nie rozumiem powodu, dla którego wiele języków programowania jest używanych w tym samym produkcie lub oprogramowaniu.

Parth Patel
źródło
14
Jako kolega z inżynierii komputerowej dodam, że w szczególności w przypadku kodu badawczego często chodzi o to, „jaki język autor (student) znał najlepiej, kiedy zaczął”. Projekty badawcze, zwłaszcza te jednorazowe, które nie prowadzą do większych projektów badawczych, zwykle cenią wyniki nad „poprawnością” (z mojego doświadczenia).
tonysdg
16
@tonysdg: Powiedziałbym, że „poprawność” jest bardziej istotna w środowisku akademickim, a nie mniej. To, co na ogół nie jest istotne, to łatwość konserwacji, wrażenia użytkownika i / lub dokumentacja. W szczególności mieszanie języków wpływa na łatwość konserwacji; ogranicza liczbę wykwalifikowanych opiekunów.
MSalters
2
@MSalters: Utrzymanie jest słowem, którego chyba szukałem w tym czasie --- zgadzam się ze wszystkim, co napisałeś!
tonysdg
19
Różne narzędzia do różnych zadań. Zauważysz, że architekci i inżynierowie budynków używają różnych narzędzi do budowy jednego domu.
Paul D. Waite,
17
Kiedy jedziesz na wakacje, z domu na lotnisko, a następnie na lotnisko zagraniczne, potem do hotelu, a następnie na plażę, czy korzystasz z tego samego środka transportu na każdym odcinku podróży?
Wyścigi lekkości na orbicie

Odpowiedzi:

17

Ta odpowiedź ma doskonały zasięg i linki do tego, dlaczego różne języki mogą zapewnić wyraźne korzyści dla projektu. Jednak w projektach używających wielu języków jest coś więcej niż tylko przydatność językowa.

Projekty wykorzystują wiele języków z sześciu głównych powodów:

  1. Korzyść z ponownego użycia kodu napisanego w innych językach;
  2. Konieczność uwzględnienia i dostosowania starszego kodu;
  3. Dostępność koderów dla określonych języków;
  4. Potrzeba specjalnych języków dla potrzeb specjalnych;
  5. Uprzedzenia językowe starszego typu; i
  6. Słabe zarządzanie projektem (nieplanowane użycie w wielu językach).

Powody 1-4 są pozytywnymi powodami w tym sensie, że bezpośrednie zajęcie się nimi może pomóc w szybszym, bardziej efektywnym zakończeniu projektu dzięki produktowi wyższej jakości i łatwiejszemu długoterminowemu wsparciu. Powody 5 i 6 są negatywne, objawy oporności na potrzebne zmiany, złe planowanie, nieskuteczne zarządzanie lub kombinacja wszystkich tych czynników. Te negatywne czynniki są niestety częstymi przyczynami „przypadkowego” używania wielu języków.

Powód 1 , korzyści wynikające z ponownego użycia, stał się coraz silniejszym powodem pozwalającym na użycie wielu języków w projekcie, zarówno ze względu na większą rolę oprogramowania typu open source, jak i ulepszone możliwości znalezienia odpowiednich składników kodu w Internecie. Filozofia „zróbmy to wszystko wewnętrznie” z ostatnich dziesięcioleci nadal zanika w obliczu realiów gospodarczych i zasadniczo nigdy nie jest najbardziej opłacalnym podejściem dla każdego nowego projektu. To z kolei sprawia, że ​​możliwości ścisłego egzekwowania użycia jednego języka w ramach projektu są mniej powszechne.

Zwłaszcza w przypadku ponownego wykorzystania dobrze zarządzanych komponentów open source użycie wielu języków może przynieść ogromne korzyści w zakresie kosztów ogólnych, ponieważ ponownie wykorzystane komponenty są ukryte za dobrze zaprojektowanymi interfejsami i są niezależnie obsługiwane przez grupy zewnętrzne o zerowych kosztach. W najlepszych przypadkach mieszanie języków za pomocą tego rodzaju ponownego użycia nie jest bardziej kosztowne dla projektu niż użycie komponentów systemu operacyjnego. Nie znam lepszego przykładu wartości tego podejścia niż przyjęcie przez Microsoft na szeroką skalę oprogramowania open source w swoich przeglądarkach.

Powód 2 , konieczność dostosowania starszego kodu, jest ignorowany na ryzyko każdego dużego projektu. Jednak wiele problemów może powodować starsze kody, naiwne zakładanie, że można go łatwo zastąpić nowym kodem w nowym języku, może być niezwykle ryzykowne. Starszy kod, nawet zły, starszy kod, często obejmuje to, co stanowi dorozumiany „kontrakt” funkcji oczekiwanych przez społeczność korzystającą ze starszego produktu. Ta społeczność dość często stanowi główne źródło dochodów firmy lub główny cel wsparcia oprogramowania rządowego. Po prostu odrzucenie tej dorozumianej umowy może ścigać świadomych klientów w masie i może zbankrutować firmę z dnia na dzień, jeśli inne opcje są łatwo dostępne.

Jednocześnie, nie zastępując stary kod w starym języku może być równie niebezpieczne, jak zastąpienie go hurtowej. Najgorszym przykładem jest Administracja Weteranów USA, która ma dużą liczbę ważnych systemów zakodowanych w języku o nazwie MUMPS (bez żartów), który został zaprojektowany przez lekarzy, a nie informatyków. Nikt nie chce się uczyć MUMPS, a ci, którzy go znają, dosłownie umierają. Programiści muszą zatem uwzględniać MUMPS, nawet gdy starają się korzystać z innych, bardziej popularnych, wydajniejszych i lepiej obsługiwanych języków.

Ten rodzaj użytkowania w wielu językach wymaga starannego planowania. To planowanie musi poruszać się na krawędzi noża między utratą dziesięcioleci wiedzy klientów z jednej strony, a utratą zdolności do obsługi oprogramowania z drugiej. Pomocne mogą być techniki, które izolują stary kod za dobrze zdefiniowanymi interfejsami i które pozwalają nowemu, bardziej wydajnemu kodowi zastąpić stary kod po dobrze udokumentowanym jego zachowaniu. Jednak ten tradycyjny scenariusz nigdy nie jest łatwy i był (i nadal będzie) przyczyną upadku wielu firm i organizacji o szerokim spektrum rozmiarów.

Powód 3 , dostępność koderów dla różnych języków, jest pragmatycznym czynnikiem, który projekty ignorują na własne ryzyko. Niezależnie od tego, jak bardzo organizatorzy projektu mogą uważać (poprawnie lub niepoprawnie), że dany język jest najlepszy dla ich celów, jeśli ten język stoi w sprzeczności z dostępną pulą wiedzy specjalistycznej, zarówno harmonogram, jak i jakość produktu ucierpią na nauce zakrzywiony programistów próbujących nauczyć się nowego języka.

Bardziej racjonalnym podejściem jest analiza potrzeb językowych projektu w oparciu o obszary funkcjonalne. Na przykład dokładne przyjrzenie się projektowi może wykazać, że istnieje tylko niewielki „wierzchołek” kodu o wysokiej wartości, np. Do implementacji zastrzeżonego algorytmu, który wymaga specjalistycznej wiedzy na temat kodowania w nieco rzadziej używanym języku. Inne części każdego dużego projektu są często łatwo dostępne dla bardziej popularnych języków lub (jeszcze lepiej) dla dobrze zarządzanych produktów open source. Analiza projektu pod kątem potrzeb językowych może w ten sposób zapewnić znacznie bardziej realistyczne i opłacalne podejście do zatrudniania lub wynajmu specjalnej wiedzy specjalistycznej w językach specjalnych, a także może pomóc wyostrzyć interfejsy między językami w ramach jednego projektu.

Powód 4 , używając różnych języków dla różnych potrzeb, wynika natychmiast i bezproblemowo z przeprowadzeniem tego rodzaju analizy potrzeb projektu. Należy również zachować ostrożność, ponieważ wybranie zbyt wielu języków do wsparcia w ramach jednego projektu może spowodować kombinatoryczną eksplozję złożoności zarówno pod względem obsługi, jak i interfejsów między komponentami. Najbezpieczniejszą trasą pod względem kosztów jest zawsze znalezienie maksymalnych możliwości ponownego wykorzystania, zwłaszcza jeśli istnieją dobre pakiety, które mogą zaspokoić potrzeby projektu poprzez niewiele więcej niż dostosowanie. Następnie należy podjąć decyzję dotyczącą niewielkiej liczby języków, które mogą zaspokoić większość zidentyfikowanych potrzeb. W przypadku intensywnego ponownego wykorzystania często będzie to rodzaj kodu kleju.

Zasadniczo nie jest dobrym pomysłem wybór wielu języków o bardzo podobnych możliwościach tylko dlatego, że niektórzy członkowie projektu lubią jeden, a drugi inny. Jeśli jednak istnieje dobrze określony, dobrze zdefiniowany podzbiór możliwości, który skorzystałby ze specjalnych umiejętności językowych, może to być dobry powód do używania wielu języków do tworzenia nowego kodu.

Powód 5 , opór wobec potrzebnych zmian w używanych językach, może być przyczyną poważnych zakłóceń projektu i wewnętrznych sporów. Jako użytkownik DaveoJak wskazano w komentarzu do tej odpowiedzi, zmiana może być bardzo trudna dla niektórych pracowników projektu. Jednocześnie opór przed zmianami nigdy nie jest prostym problemem i właśnie dlatego może powodować wiele konfliktów. Wykorzystanie starszych umiejętności językowych może znacznie zwiększyć produktywność projektu, jeśli starszy język jest wystarczająco mocny i może prowadzić do produktu o doskonałej jakości w zespole, który działa płynnie i szanuje jakość. Jednak starsze umiejętności językowe muszą być zrównoważone z faktem, że wiele starszych języków nie może już uzupełniać nowszymi językami pod względem zaawansowanych funkcji, dostępności komponentów, opcji open source i obsługi inteligentnego zestawu narzędzi.

Zarówno wtedy, jak i teraz, najczęstszym (i jak na ironię, najczęściej poprawnym) argumentem za dalszym używaniem słabszego, mniej czytelnego lub mniej produktywnego starszego języka było to, że starszy język umożliwia tworzenie bardziej wydajnego kodu. Jest to stary argument, który sięga aż do lat 50. XX wieku, kiedy użytkownicy języka asemblerowego, często z goryczą, pojawiali się programowania w FORTRAN i LISP. Przykład, w którym nawet teraz argument wydajności kodu może mieć ważność, można zobaczyć w kodzie intensywnie przetwarzającym, takim jak jądro systemu operacyjnego, gdzie C pozostaje językiem wybieranym niż C ++ (choć z powodów, które wykraczają poza prostą wydajność).

Jednak w globalnie połączonych i wspieranych maszynowo środowiskach projektowych nowego tysiąclecia wydajność kodu jako główny argument za wyborem języka projektu wzrosła jeszcze bardziej. Ta sama eksplozja sprzętu komputerowego i sieciowego, która umożliwiła masowe wprowadzanie na rynek aplikacji sztucznej inteligencji, oznacza również, że koszty ludzkiego programowania mogą z łatwością przewyższyć koszty względnego nieefektywnego wykonania kodu na spektakularnie tanim sprzęcie i oprogramowaniu chmurowym. W połączeniu z większą dostępnością najnowszych bibliotek bibliotek komponentów, opcjami open source i zaawansowanymi inteligentnymi zestawami narzędzi liczba przypadków, w których utrzymanie języka tylko ze względów wydajnościowych staje się bardzo wąskie. Nawet w przypadkach, w których ma to zastosowanie,

Bardziej przekonujący powód, dla którego projekt pozostaje w dotychczasowych językach, występuje, gdy z jakichkolwiek powodów projekt nie ma wielu opcji zmiany personelu lub nie ma go wcale. Może się to zdarzyć na przykład, gdy duża starsza linia produktów jest całkowicie zakodowana w języku, w którym biegły jest tylko istniejący personel. W takich przypadkach projekt musi albo kontynuować próbę programowania w starym języku, albo próbować przeszkolić dotychczasowych pracowników w zakresie korzystania z nowego języka.

Szkolenie starszych pracowników języka w nowym języku może samo w sobie stanowić zagrożenie. Nadal pamiętam przypadek, w którym członek projektu, który właśnie został przeszkolony i przeszedł z C do C ++, szczerze narzekał, że po prostu nie rozumie zalet metod obiektowych. Kiedy spojrzałem na jego kod, przekonwertował wcześniejsze funkcje 103 C na 103 metody dla jednej klasy obiektów C ++ ... i słusznie nie widział, jak to pomogło.

Głębsze przesłanie jest takie, że kiedy ludzie programują w jednym języku i stylu językowym od lat lub dziesięcioleci, trudność zmuszenia ich do „myślenia” w nowy sposób może stać się prawie nie do pokonania, nawet przy dobrych programach szkoleniowych. W niektórych przypadkach może nie być innej opcji, jak tylko sprowadzić młodszych projektantów i programistów, którzy lepiej dostosowują się do aktualnych trendów i metod.

Powód 6 , złe zarządzanie projektem, mówi samo za siebie. Wybór języka i użycie w projekcie zawsze należy brać pod uwagę i oceniać w sposób wyraźny, a przypadek nie powinien mieć miejsca. Przynajmniej wybór języka może mieć ogromną różnicę w długoterminowym losie i kosztach wsparcia projektu, dlatego należy go zawsze brać pod uwagę i planować. Nie zostań MUMPSEM!

Terry Bollinger
źródło
Zgadzam się z tym wszystkim. Podczas gdy odpowiedź Basile'a koncentruje się głównie na kwestiach wydajności i wyrazistości, twoja odpowiedź pomaga każdemu zrozumieć perspektywę zarządzania stojącą za wyborem programowania polyglot.
Parth Patel
@ParthPatel Myślę, że powinieneś zaakceptować tę odpowiedź, jest to najlepsze samodzielne podsumowanie tutaj.
lewo około
2
+1: ale zapomniałeś Ego. Wiele osób odmawia nauki nowych języków i trzyma się tego, co wiedzą. Ten różny poziom dojrzałości z wieloma zespołami może prowadzić do wielu różnych technologii w ramach jednego projektu
Daveo
1
Powód 7: staram się, aby dział IT wyglądał seksownie do celów rekrutacyjnych. Nie żartując, w projekcie .Net, musieliśmy zastąpić jeden punkt końcowy z istniejącej usługi, aby korzystać z zupełnie nowej usługi w Go, tylko po to, aby mogli dodać „polyglot” do dodania pracy!
Chris Lee,
1
Heh! Nie mogę się nie zgodzić, że używanie wielu języków jest atrakcją dla osób, które obawiają się, że mogą dostać się w ślepy zaułek, pracę wyłącznie w języku COBOL. Po raz pierwszy słyszę o dodaniu języka tylko i specjalnie do tego celu, ale z pewnością istnieje wiele środowisk, w których posiadanie większej różnorodności narzędzi i języków jest postrzegane jako wskazówka, że ​​pracują z najnowszymi technologiami, i dlatego są bardziej progresywnym miejscem pracy. Dobry przykład, dzięki!
Terry Bollinger
158

Nie rozumiem powodu, dla którego wiele języków programowania jest używanych w tym samym produkcie lub oprogramowaniu?

To dość proste: nie ma jednego języka programowania, który byłby odpowiedni dla wszystkich potrzeb i celów.

Przeczytaj książkę Michaela L. Scotta Programing Language Pragmatics

Niektóre języki programowania sprzyjają ekspresji i deklaratywności (wiele języków skryptowych, ale także języki programowania wysokiego poziomu, takie jak Agda , Prolog , Lisp , Haskell, Ocaml, ...). Gdy ważny jest koszt rozwoju (czas ludzki i koszt programistów), warto z nich skorzystać (nawet jeśli wydajność środowiska wykonawczego nie jest optymalna).

Inne języki programowania sprzyjają wydajności w czasie wykonywania (wiele języków niskiego poziomu z zwykle skompilowanymi implementacjami, takich jak C ++, Rust, Go, C, asembler, a także języki specjalistyczne, takie jak OpenCL ...); często ich specyfikacja dopuszcza pewne nieokreślone zachowanie . Gdy liczy się wydajność kodu, lepiej jest używać tych języków.

Niektóre biblioteki zewnętrzne są napisane w określonym języku i ABI oraz dla konwencji, które są przeznaczone dla określonych konwencji . Być może będziesz musiał użyć tego innego języka i postępować zgodnie z konwencjami interfejsów funkcji obcych , na przykład pisząc kod kleju .

W praktyce jest mało prawdopodobne, aby język programowania był wysoce ekspresyjny (co poprawia wydajność programisty, zakładając wystarczająco wykwalifikowany zespół programistów) i bardzo wydajny w czasie wykonywania. W praktyce występuje kompromis między ekspresją a wydajnością.

Uwaga: jednak postępy w zakresie języków programowania są niewielkie : Rust jest bardziej ekspresyjny niż C, a może nawet C ++, ale jego implementacja jest prawie tak samo wydajna i prawdopodobnie poprawi się, aby wygenerować równie szybkie pliki wykonywalne. Musisz więc uczyć się nowych języków programowania podczas swojego życia zawodowego; jednak nie ma srebrnej kuli

Zwróć uwagę, że koszty rozwoju są dziś coraz bardziej znaczące (nie było tak w latach 70. XX wieku - wtedy komputery były bardzo kosztowne - lub w niektórych aplikacjach wbudowanych - z dużą ilością produktu). Zasadą (bardzo przybliżoną) jest to, że wykwalifikowany programista jest w stanie napisać około 25 tysięcy wierszy (debugowanego i udokumentowanego) kodu źródłowego każdego roku i nie zależy to w dużej mierze od używanego języka programowania.

Powszechnym podejściem jest osadzanie języka skryptowego (lub języka specyficznego dla domeny ) w dużej aplikacji. Konstrukcja ta idea (związane język dziedzinowy) zostały wykorzystane przez dziesięciolecia (dobrym przykładem jest Emacs kod źródłowy edytor , za pomocą Elisp skryptów od 1980 roku). Następnie użyjesz łatwo osadzalnego interpretera (takiego jak Guile , Lua , Python, ...) w większej aplikacji. Decyzja o umieszczeniu tłumacza w dużej aplikacji musi być podjęta bardzo wcześnie i ma poważne konsekwencje architektoniczne. Następnie użyjesz dwóch języków: dla rzeczy niskiego poziomu, które muszą działać szybko, jakiegoś języka niskiego poziomu takiego jak C lub C ++; w przypadku skryptów wysokiego poziomu inny język DSL lub język skryptowy.

Zauważ również, że dane oprogramowanie może działać w większości obecnych systemów operacyjnych (w tym Linux, Windows, Android, MacOSX, Hurd, ...), w kilku współpracujących procesach przy użyciu pewnego rodzaju technik komunikacji między procesami . Może nawet działać na kilku komputerach (lub wielu z nich), wykorzystując techniki przetwarzania rozproszonego (np. Przetwarzanie w chmurze , HPC, serwer klienta, aplikacje internetowe itp.). W obu przypadkach łatwo jest korzystać z kilku języków programowania (np. Kodować każdy program działający na jednym procesie lub komputerze we własnym języku programowania). Czytaj Systemy operacyjne: trzy łatwe elementy, aby uzyskać więcej. Również interfejsy funkcji obcych(np. JNI ), ABI , konwencje wywoływania itp. ... ułatwiają mieszanie kilku języków w tym samym programie (lub pliku wykonywalnym ) - a znajdziesz generatory kodu, takie jak SWIG, które pomogą.

W niektórych przypadkach trzeba wymieszać kilka języków programowania: aplikacje internetowe muszą JavaScript lub Webassembly (jedynymi językami działa wewnątrz większości przeglądarek internetowych) na część działa w przeglądarce (istnieją ramy generujące nich, np ocsigen ). Kod jądra wymaga częściowego zapisu (np. Harmonogramu lub obsługi przerwań niskiego poziomu) w asemblerze, ponieważ C lub C ++ nie mogą wyrazić tego, co jest tam potrzebne, zapytania RDBMS powinny używać SQL, GPGPU potrzebuje jądra komputerowego zakodowanego w OpenCL lub CUDA zarządzany przez kod hosta C lub C ++ itp. Niektóre języki zostały zaprojektowane w celu ułatwienia takiej mieszanki (np. asminstrukcje w C,fragmenty kodu w moim późnym GCC MELT itp.).

W niektórych przypadkach używasz technik metaprogramowania : niektóre części dużego projektu oprogramowania miałyby kod (np. W C lub C ++) generowany przez inne narzędzia (być może specyficzne dla projektu) z formalizacji ad-hoc: generatory parsera (niepoprawnie nazywane kompilatorem przychodzą na myśl kompilatory), takie jak Bison czy ANTLR , ale także SWIG lub RPCGEN. I zauważ, że GCC ma w sobie kilkanaście wyspecjalizowanych generatorów kodu C ++ (jeden dla każdego wewnętrznego DSL w GCC). Zobacz także ten przykład. Zauważ, że trudno jest znaleźć metabugi . Przeczytaj także o kompilatorach ładujących oraz o homoikoniczności i refleksji(warto nauczyć się Lisp , grać z SBCL i czytać SICP ; zajrzyj również do bibliotek kompilujących JIT, takich jak GCCJIT ; w niektórych dużych programach możesz wygenerować trochę kodu przy ich użyciu; pamiętaj o dziesiątej regule Greenspun ). Zapoznaj się również z przemówieniem na temat cyklu mniej podróżowanych na FOSDEM2018.

Czasami chcesz dostarczyć formalne adnotacje do swojego kodu (np. Aby pomóc dowódcom, analizatorom statycznym, kompilatorom), używając jakiegoś specjalistycznego języka adnotacji (który może być postrzegany jako część DSL). Zajrzyj do ACSL z Frama-C, aby dodać adnotacje do programów C (krytycznych dla bezpieczeństwa) lub pragm OpenMP dla HPC. Zastrzeżenie: pisanie takich adnotacji może wymagać dużo umiejętności i czasu na rozwój.

BTW, sugeruje to, że niektóre umiejętności dotyczące kompilatorów i interpretatorów są przydatne dla każdego programisty (nawet bez pracy wewnątrz kompilatorów). Przeczytaj więc Dragon Book, nawet jeśli nie pracujesz na kompilatorach. Jeśli kodujesz własnego tłumacza (lub projektujesz DSL), przeczytaj także Lisp In Small Pieces .

Zobacz też to i to i to i że odpowiedzi z kopalni związane z Twoim pytaniem.

Zapoznaj się również z kodem źródłowym kilku dużych projektów wolnego oprogramowania (na github lub z Twojej dystrybucji Linuksa ), aby uzyskać inspirację i oświecenie.

Ponadto niektóre języki programowania ewoluowały, dodając adnotacje (jako pragmy lub komentarze ) do istniejących języków. Na przykładach myśleć ACSL (komentarzu-extension opisywanie programów C, aby umożliwić ich dowodów przez Frama-C ) lub OpenCL (C dialekt zaprogramowania GPGPUs) lub OpenMP lub OpenACC #pragmas lub Common Lisp adnotacje typu .

PS: istnieją również powody społeczne, organizacyjne lub historyczne, aby mieszać języki programowania; Ignoruję je tutaj, ale wiem, że w praktyce takie powody są dominujące. Przeczytaj także Miesiąc mitycznego człowieka

Basile Starynkevitch
źródło
6
Dla mnie to poprawna odpowiedź. Możesz wziąć na przykład procedury montażu w programach C. Powłoka UNIX jest zaśmiecona wieloma językami programowania i często znajdziesz awk(który jest innym językiem programowania) używany w skryptach bash, tylko dlatego, że lepiej pasuje do zadania). Punkt @ amona wciąż jednak pozostaje ważny.
MayeulC
8
BTW, świetny programista czasami potrafi usuwać wiersze kodu ... (zastępując wiele kiepskich wierszy kodu niewielkimi kilkoma dobrymi wierszami)
Basile Starynkevitch
12
Świetna odpowiedź, ale jedna prośba: doceniam chęć wskazania „na bok”, prezentując je w mniej widoczny sposób, ale proszę nie nadużywać znacznika HTML SUP tylko dlatego, że ma efekt uboczny renderowania w mniejszej czcionce. To musi być koszmar dostępności, a jak mówi standard HTML5: „Te elementy muszą być używane tylko do oznaczania konwencji typograficznych konkretnymi znaczeniami, a nie do prezentacji typograficznej dla samej prezentacji. [...] używaj tych elementów tylko, jeśli brak tych elementów zmieniłby znaczenie treści. ”
FeRD
4
@FeRD: usunięto, <sup>ale z żalem
Basile Starynkevitch
6
@BasileStarynkevitch Doceniony. Tak jak powiedziałem, doceniam zamiar i jako sam nadmiernie gadatliwy, skłonny do stycznych pisarz, zdecydowanie chciałbym, aby StackExchange dostarczył obsługiwaną metodę stylizacji tekstu mniejszą lub być może zwiniętą w pojemniku typu „kliknij, aby odsłonić”. Jednak indeks górny długości akapitu nie jest odpowiedzią na ten brak.
FeRD
29

Wiele projektów nie jest budowanych z wieloma językami programowania. Jednak do pomocy w oprogramowaniu często używa się skryptów w innych językach.

  • Narzędzia administracyjne, które są oddzielnymi programami, są czasami pisane w innym języku.
  • Biblioteki i interfejsy API często oferują powiązania dla wielu języków, dzięki czemu programiści mogą używać dowolnego języka.
  • Skrypty budowania i powiązane skrypty programowania często używają specjalistycznych języków.
  • Kompleksowe testy aplikacji nie muszą używać tego samego języka.

Niektóre projekty wykorzystują wiele języków w aplikacji, np. Rdzeń w języku niższego poziomu, który może integrować wtyczki z językiem skryptowym. W niektórych ekosystemach (np. JVM lub .NET) dokładny używany język nie jest zbyt ważny, ponieważ wiele języków w tym samym języku wykonawczym ma dobrą interoperacyjność. Na przykład mógłbym napisać projekt w Scali, który wykorzystuje istniejące biblioteki Java i integruje funkcjonalność skryptową z Groovy.

Jeśli projekt składa się z wielu narzędzi, można je również opracować w różnych językach. Chociaż spójność byłaby dobra, zwłaszcza w przypadku projektów typu open source, dostępne wysiłki rozwojowe mogą stanowić wąskie gardło. Jeśli ktoś chce opracować przydatne narzędzie, ale nie zna głównego języka, być może to narzędzie jest cenniejsze niż konsekwencja.

amon
źródło
3
Jest to komplementarne do odpowiedzi @ Basile. Skrypty perla z jądra Linuksa nie są częścią jądra, podobnie jak Makefile. Używając C do tego, nie ma nic do zyskania. Co więcej, te skrypty perla mogą być używane niezależnie od jądra Linuksa. Dość często można je uważać za ściśle powiązany, ale odrębny projekt . Zazwyczaj używasz jednego języka do jednego zadania.
MayeulC
20

Ma to dwie formy i wiele organizacji, które mieszczą się między nimi:

Zła forma - organizacja to bałagan i nikt nie upewnia się, że istnieje jedna technologiczna wizja tego wysiłku. Twórcy najprawdopodobniej używają języka, w którym są najwygodniejsi, lub ostatnio eksperymentowali z nowym frameworkiem lub językiem i postanowili po prostu zacząć używać tego z powodu naiwnego optymizmu.

Dobra forma - organizacja ma naprawdę dobrą, czystą architekturę, która dobrze nadaje się do programowania w poliglocie; rozdzielanie aplikacji na niezależne komponenty o ściśle określonym kontekście ograniczającym, a ta kombinacja pozwala im wybrać język programowania, który najprościej pozwala im napisać ten konkretny komponent.

Rzeczywistość - zwykle jest bardziej tym pierwszym niż drugim. Widziałem kilka firm, które wybrały jeden język dla swojej domeny biznesowej i inny dla swojego serwera internetowego, a często trzeci dla administrowania bazą danych, co jest technicznie w porządku, ale wkrótce ich brak zrozumienia technicznego (lub odmowa wysłuchania ich pracowników) oznacza to, że kończą się one rozmyciem w wielkim bałaganie i często wprowadzają jeszcze więcej języków, które są odpowiednie do rozwiązania określonych części bałaganu.

Ben
źródło
20

Mogę podać przykład projektu programistycznego, który był realizowany od 32 lat i wydaje się, że wciąż jest w nim dużo życia. Jest raczej komercyjny niż open source.

Rdzeń jest napisany w języku specyficznym dla domeny, stworzonym specjalnie dla projektu. Okazało się to niezwykle przydatne, zwłaszcza dlatego, że integruje wycofywanie z podstawową architekturą, ale kompiluje się do kodu C, który następnie kompilujemy z kompilatorem platformy. W tym czasie obsługiwał około dwudziestu platform, nie licząc odmian 32- i 64-bitowych, a obecnie jest dostępny na sześciu z nich.

Ma dodatek napisany w C ++, który został uruchomiony, gdy poprzedni kierownik projektu przekonał się, że C ++ / MFC / Windows / x86 zamierza wyprzeć wszystkie inne architektury i platformy, więc konieczne było zaoferowanie pracy w C ++ móc zatrudnić personel. Sprawy nie potoczyły się tak, jak się spodziewał.

Oprócz języka domeny i C ++ programiści pracują w LISP, który służy do pisania przypadków testowych, używając interpretera wbudowanego w wiązkę testową. W pewnym momencie zastanawialiśmy się nad zastąpieniem LISP Javą, ale okazało się, że na szczęście nie.

Ma również opakowanie dla głównego interfejsu API, napisane w języku C #. Dokonano tego, gdy klienci tego zażądali, aby mogli ponownie napisać swoje aplikacje w języku C #. Jest tworzony przez skrypt Perla, który odczytuje pliki nagłówkowe C dla API oraz znaczący plik konfiguracyjny i zapisuje kod C # dla opakowania. Wykonanie całego przetwarzania tekstu w Perlu było po prostu łatwiejsze niż w C ++.

Ma własne systemy kompilacji i potrzebuje ich, ponieważ język domeny nie jest przystosowany do systemów kompilacji opartych na tworzeniu. Ten dla platform typu UNIX jest napisany w skryptach powłoki, Perlu i niektórych małych programach w języku domeny. Ten dla platform Windows jest napisany w języku wsadowym, Perlu i tych samych małych programach w języku domeny. Stary system kompilacji VMS został napisany w DCL, ale nie był używany od ponad dekady.

W kompilatorze jest język programowania YACC / Bison. Istnieje kod testowy dla platform Apple napisany w Objective-C ++. Niektóre wewnętrzne strony internetowe zespołu (używane do zarządzania projektami, nie będące częścią rezultatów) są napisane w ASP, a inne jako skrypty CGI w Perlu.

Zasadniczo zaczął się jako projekt mający na celu rozwiązanie trudnego problemu, dlatego warto było stworzyć specjalistyczne narzędzia, które nadal wydają się bardziej odpowiednie do tego zadania niż cokolwiek innego dostępnego. Zespół uważa, że ​​programowanie jest umiejętnością nieco niezależną od używanego języka, więc są gotowi użyć nowego języka, jeśli ułatwi to zadanie. Moda nie znajduje się jednak wysoko na liście priorytetów, więc nie rozdrobnią zadania, wprowadzając nowy język za darmo.

Funkcją tego kodu jest modelowanie matematyczne, stosowane na stacjach roboczych i serwerach (mogę mówić nieco swobodniej, jeśli nie zidentyfikuję produktu). Obecnie jest to około 25 milionów LoC, przy całkowitej wielkości zespołu wynoszącej około pięćdziesięciu.

John Dallman
źródło
Byłoby miło powiedzieć coś więcej o tym oprogramowaniu: jaka domena przemysłowa (na przykład roboty neurochirurgiczne to nie to samo, co handel o wysokiej częstotliwości)? Jaki przybliżony rozmiar (w milionach wierszy kodu)? Jaki rozmiar zespołu?
Basile Starynkevitch
@BasileStarynkevitch: dodano szczegóły.
John Dallman
To. Właśnie dlatego projekty mają wiele języków - od dobrych po złe do brzydkich.
Jared Smith
15

W niektórych przypadkach konieczne jest użycie narzędzia (takiego jak zestaw narzędzi interfejsu użytkownika systemu operacyjnego), które jest najłatwiej dostępne z danego języka. Na przykład na iOS i macOS, jeśli chcesz pisać aplikacje GUI przy użyciu UIKit i AppKit, pisanie w Swift lub Objective-C jest najszybszym i najłatwiejszym sposobem na zrobienie tego. (Mogą istnieć powiązania dla innych języków, ale mogą one być związane z najnowszą wersją systemu operacyjnego, na której budujesz, więc mogą nie oferować wszystkich funkcji).

Tak często zdarza się, gdy aplikacja jest wieloplatformowa, podstawowa logika aplikacji jest napisana w jakimś języku, który jest dostępny dla obu języków, a elementy specyficzne dla interfejsu użytkownika / systemu operacyjnego są pisane w dowolnym języku, w którym działają natywnie.

Więc jeśli piszesz aplikację dla systemu Windows i macOS, możesz napisać podstawową logikę w C ++ i użyć C # dla interfejsu użytkownika w systemie Windows i Swift dla interfejsu użytkownika w systemie macOS. To oszczędza czas, ponieważ nie musisz pisać logiki podstawowej dwa razy i radzić sobie z różnymi zestawami błędów w obu aplikacjach itp. Ale pozwala także na prawdziwy natywny interfejs użytkownika, który nie spełnia najniższego wspólnego mianownika między platformami, takiego jak używanie zrobiłby to wieloplatformowa biblioteka interfejsu użytkownika.

użytkownik1118321
źródło
MVC FTW! Nawet zabranie się za posiadanie jednego rdzenia wieloplatformowego z aplikacjami otoki dla każdego systemu operacyjnego / środowiska ... lub we współczesnym świecie łączności przenoszącym go do architektury klient / serwer
ivanivan
1
To pasuje do mojego własnego doświadczenia. Każdy projekt o znacznej wielkości, nad którym pracowałem, wykorzystywał wiele języków i nigdy nie zapewniało to korzyści wielu językom. Powodem było zawsze to, że poszczególne części musiały być napisane w określonych językach, aby można było połączyć się z określonymi narzędziami.
Owen,
Jako były programista iOS mogę potwierdzić, że to zrobiliśmy. Mieliśmy API napisane w PHP, które komunikowało się w JSON, front-end WWW napisany w PHP, który miał także część JavaScript / HTML5, front-end Androida napisany w Javie i front-end iOS napisany w Objective-C . Później nowsze projekty zostały napisane w Swift, ale nasze wewnętrzne ramy były nadal napisane w Objective-C. W pewnym momencie jedna z naszych aplikacji została napisana w PHP, Javie, Objective-C, Swift, JavaScript i HTML5 i dostępna na 3 platformach.
Belle-Sophie
10

Oprócz tego, że niektóre języki programowania mogą być lepiej dostosowane do niektórych konkretnych zadań, istnieje praktyczna rzeczywistość.

W praktyce należy wziąć pod uwagę 2 szczególnie ważne kwestie:

  1. Ludzie mają różne doświadczenia i poziomy zainteresowania różnymi językami programowania. - Umożliwienie ludziom pracy w językach, które lubią i są biegli, może w pewnych okolicznościach prowadzić do lepszych rezultatów końcowych niż zmuszanie ich do wspólnego języka.
  2. Duże bazy kodowe budowane są przez długi czas przez różnych ludzi. - Nie ma sposobu, aby uzyskać fundusze lub liczbę ochotników potrzebnych do przepisania całego projektu, kiedy wyjdzie język, który jest bardziej odpowiedni dla niego.

I oczywiście są często określone części aplikacji, które mają zupełnie inne potrzeby, takie jak:

  • Obszary wrażliwe na wydajność opracowane w skompilowanym języku. Przykładowy język: C ++
  • Obszary, które muszą być tanie, łatwe do zmiany i potencjalnie konfigurowalne, opracowane w języku skryptowym. Przykładowy język: Lua.
  • Układ GUI. Przykładowy język: HTML
  • Instalator Przykładowy język / narzędzie: WiX.
  • Budować. Przykładowy język / narzędzie: Zbyt wiele, by je wymienić, zwykle kilka z nich jednocześnie.

Ponadto istnieje wiele narzędzi wykorzystywanych przez wyrafinowaną bazę kodu, z których wiele umożliwia niezbędne dostosowanie i wtyczki w jeszcze innym języku.

Piotr
źródło
8
HTML nie jest językiem programowania
Bergi
1
@Bergi poprawnie. Peter nie twierdzi, że tak jest. To jest język znaczników.
Belle-Sophie
1
HTML, XAML, QML itp. To języki używane przez programistów w projektach programowych do informowania komputera, co mają robić - języki zwykle nie są absolutnie konieczne, ponieważ programiści mogliby teoretycznie napisać cały projekt, w tym interfejs użytkownika, w jednym języku. To sprawia, że ​​ma to znaczenie w kontekście tego pytania.
Peter
5

Oprócz poprawnych innych stwierdzeń:
z doświadczenia wynika, że ​​wiele decyzji dotyczących języka lub środowiska jest podejmowanych przez „jeśli masz młotek, wszystko wygląda jak gwóźdź”, co oznacza, że ​​ludzie używają znanych im narzędzi.

Ponadto wprowadzenie nowego środowiska, a nawet języka, jest poważną inwestycją w licencje, szkolenia, może sprzęt i wiąże się z dużymi stratami produktywnego czasu - zamawiania, instalowania, konfigurowania, szkolenia każdego tygodnia w większej firmie, a po prostu kończysz z grupą początkujących programistów.
Zasadniczo nigdy nie ma czasu na „inwestowanie” w bardziej nowoczesne lub lepiej dopasowane środowisko lub język, więc trzymają się tego, co mają, dopóki nie będzie już w stanie działać.

Konkretnie na twoje pytanie, jeśli wiele osób / zespołów bierze udział w opracowywaniu rozwiązania, każda grupa ma tendencję do trzymania się tego, co wiedzą najlepiej, więc ogólne rozwiązanie ma potencjalnie wiele języków i rozwija się w wielu środowiskach.

Aganju
źródło
5

To pytanie (i niektóre odpowiedzi) wydaje się zakładać, że aplikacje są monolitycznymi blokami kodu - niekoniecznie tak jest.

Twoja typowa strona internetowa, taka jak Stack Exchange, jest w rzeczywistości zbiorem różnych usług, z których wszystkie działają niezależnie od siebie, z pewnego rodzaju komunikacją między nimi. Usługi te mogą być (i zazwyczaj są) wdrażane w różnych językach, z których każdy ma swoje zalety.

Pracuję na niewielkim kawałku platformy bankowości internetowej, skierowanej do mniejszych banków społeczności i kas kredytowych. Ta platforma ma wiele komponentów - interfejs WWW, warstwę bazy danych, warstwę komunikacyjną innej firmy itp. Są to niezależne aplikacje działające na różnych serwerach z różnymi systemami operacyjnymi. W przeglądarce masz JavaScript działający po stronie klienta, po stronie serwera Perl buduje strony, masz wiele usług napisanych w C ++ działających jako warstwa abstrakcji między kodem Perl a głównym procesorem banku, innym zestawem aplikacji C ++, które kieruj wiadomości między różnymi warstwami, rozproszenie aplikacji C ++ i skryptów Perla, aby monitorować kondycję różnych procesów i zgłaszać ich stan wewnętrznemu monitorowi itp. itd. itp.

Aplikacje monolityczne nadal istnieją, ale nawet one mogą korzystać z różnych języków z różnych powodów. Możesz napisać 90% aplikacji w Javie, ale użyj JNI, aby wykorzystać C lub C ++ do bardziej krytycznych sekcji.

John Bode
źródło
Dziwię się, że nikt nie wspomniał o SQL (lub wybranym przez ciebie języku zapytań), większość aplikacji ma teraz co najmniej jakąś architekturę „stosową”.
user3067860
3

Chciałbym zwrócić uwagę na bardzo konkretny przykład motywu „różne języki mają różne mocne strony”: FORTRAN.

Fortran został pierwotnie opracowany, aby ułatwić inżynierom wykonywanie analiz numerycznych, a od tego czasu wiele wysiłku włożono w to, aby kompilatory Fortran emitowały bardzo wydajny kod numeryczny. Z drugiej strony, od tych wczesnych dni korzystanie z komputerów eksplodowało w tysiącach kierunków, z których żaden nie wymaga analizy numerycznej, a rozwój języków programowania w dużej mierze poszedł w ślady ignorowania „prawdziwego” świata [przepraszam grę słów].

SO: Dziś jest i pracujesz dla firmy z dość rozległym produktem, w większości napisanym w (powiedzmy) Javie (mówię tutaj z własnego doświadczenia) . Ale okazuje się, że jedną z podstawowych cech produktu będzie jakaś forma analizy numerycznej, a wszystkie najlepsze kody dla tej konkretnej analizy są już dostępne w Internecie - w Fortran. Więc co robisz? Pobierasz jeden z tych kodów Fortrana, wymyślasz jego interfejs [tj. Argumenty najwyższego podprogramu], tworzysz dla niego opakowanie JNI w C i pakujesz jako klasę Java. BAM! Właśnie musiałeś się uczyć w trzech językach jednocześnie. [szczególnie jeśli okaże się, że kod Fortran używa bloków WSPÓLNYCH - tj. przechowywania statycznego - i musi zostać zmodyfikowany w celu zabezpieczenia wątków]

PMar
źródło
4
Albo twój sprawdzony rdzeń obliczeniowy FORTRAN zostałby ulepszony przez wywołanie w pewnym momencie nowego algorytmu, który zależy od robienia sortowania stosów na wskaźnikach, które już napisałeś w C. I masz złożone pliki wejściowe do skanowania, więc piszesz skaner flex. Aha, a może chcesz GUI na górze, które musisz wywołać z C ++. Albo klient naprawdę chciałby nazwać to wszystko podprogramem Matlaba ...
jamesqf 30.04.2018
3

Ponieważ programowanie nie jest jednym zadaniem. Nawet stworzenie produktu nie jest jednym zadaniem. Istnieje wiele rodzajów zadań, które najlepiej wyrażać w różnych językach.

Aby uczynić to bardziej konkretnym, załóżmy coś prostego jak samodzielna aplikacja (dla aplikacji rozproszonych jest więcej zadań do wykonania).

Produkt musi być

  • napisany
  • połączone (dotyczy to zarówno kompilacji, jak i gromadzenia zasobów, takich jak obrazy, czcionki itp. do wdrożenia)
  • rozmieszczony
  • skonfigurowany
  • monitorowane

Język, który może być dobry do napisania środowiska uruchomieniowego produktu, jest mało prawdopodobne, aby był równie dobry do złożenia produktu razem. I tak dalej.

Jednak nawet proces pisania produktu może nie być optymalnie przeprowadzony w 1 języku.

Załóżmy, że w produkcie jest wiele uporządkowanych danych. Czy struktura danych jest znana w momencie pisania? Jeśli tak, będziesz chciał skonfigurować bazę danych w momencie wdrażania. Jest to optymalnie wykonane w języku, który może wygenerować język, który będzie się kompilował w czasie wykonywania.

Co teraz, jeśli struktura danych może się zmieniać od czasu do czasu? Potrzebujesz uporządkowanego sposobu przekształcania nowych konstrukcji danych w konfigurację kodu i bazy danych. Najlepiej zrobić to w innym języku.

Czy możesz to zrobić w tym samym języku? Pewnie. Ale o Twojej skuteczności decyduje szybkość ukończenia projektu i odporność na zmiany. Jeśli duża część pracy może zostać zautomatyzowana za pomocą już istniejących narzędzi, to ktoś, kto zajmie Ci 3 miesiące, może wykonać ktoś inny w ciągu 2 dni. Ale ten ktoś używałby innych języków do automatyzacji tego, co zrobiłbyś przez powtarzanie.

Grovkin
źródło
„Język, który może być dobry do napisania środowiska uruchomieniowego produktu, jest bardzo mało prawdopodobny”… języki programowania nie powstają z przypadkowego procesu, więc mówienie o prawdopodobieństwie w ten sposób jest trochę dziwne . Języki programowania mają na celu rozwiązanie niektórych zadań. Teraz chodzi o to, że język prawdopodobnie również nie rozwiąże przypadkowo innego problemu, którego nie zaprojektowano do rozwiązania. Twierdziłbym jednak, że istotą programowania jest streszczenie wszystkich problemów, które można chcieć rozwiązać, a zatem naprawdę dobrze zaprojektowany język powinien być równie dobry do każdego zadania.
lewo około
@leftaroundabout powszechnym błędem jest mylenie tego, co potrafi język i co dobrze wyraża. Celem języka wysokiego poziomu nie jest rozwiązanie problemu. Ma działać jako składnia wyrażania rozwiązania problemu w taki sposób, że niektóre narzędzia mogą przekształcić to wyrażenie w zadanie, które komputer może wykonać. Biorąc to pod uwagę, ważne jest, aby pamiętać, że faktyczną pracą wyrażania są ludzie. Ludzie używają różnych abstrakcji do opisywania rozwiązań problemów z różnych dziedzin.
grovkin
Pewni ludzie używają różnych abstrakcji. Chodzi mi o to, że dobry język powinien być w stanie wyrazić wszystkie te abstrakcje.
lewo około
@leftaroundabout, wcale nie. Wyrażenie wszystkiego dobrze wymaga umiejętności skierowania uwagi na rzecz. Próba dobrego wyrażenia wszystkich rodzajów abstrakcji oznaczałaby zwrócenie na nie uwagi. A to rozproszyłoby uwagę i spowodowało, że pomysły były źle wyrażane. Nie ma nic złego w wyborze tego, co należy podkreślić i skoncentrowaniu się na tym.
grovkin
Możliwość skierowania uwagi gdzieś nie jest tym samym, co faktycznie to robi.
lewo około
1

Rozwój oprogramowania postępuje do tego stopnia, że możesz używać różnych języków programowania w tym samym projekcie i możesz sprawić, by działał.

Następnie pojawia się pytanie, dlaczego miałbyś używać więcej niż jednego języka.

Jednym z powodów jest to, że języki stają się przestarzałe i powoli zastępowane nowszymi, a jeśli masz szczęście, możesz to zrobić krok po kroku. Twój projekt będzie więc mieszanką starego i nowego języka.

Innym powodem jest sytuacja, w której język X jest bardzo używany na platformie A, język Y jest bardzo podobny do platformy B, ale język Z jest obsługiwany na obu platformach. Tak więc wspólny kod jest napisany w języku Z, który jest następnie łączony z X lub Y, w zależności od platformy.

A ludzie lubią używać kodu napisanego przez innych (innymi słowy kodu, na który nie musieli poświęcać czasu na pisanie go sami). Mogą swobodnie korzystać z kodu napisanego przez innych w dowolnym języku, a następnie dodawać kod w języku, który preferują.

gnasher729
źródło
8
O pierwszym zdaniu: programy w różnych językach są znane od ponad 50 lat.
Blrfl