Różnice architektoniczne między językami dynamicznymi i statycznymi

22

Czy istnieją jakieś poważne różnice architektoniczne podczas projektowania aplikacji, które będą budowane na językach statycznych (takich jak C # lub Java) i językach dynamicznych (takich jak Ruby lub Python)?

Jakie są możliwości projektowania, które mogą być dobrym wyborem dla jednego typu, który jest zły dla drugiego? Czy są jakieś przydatne funkcje, które można osiągnąć z jednym typem, który nie jest z drugim (oczywiście w projektowaniu i architekturze)?

Ponadto, czy istnieją jakieś dynamiczne wzorce projektowe?

Raphael
źródło
1
Niezależnie od tych różnic architektonicznych, dynamiczne języki - IronRuby i IronPython - z łatwością uzupełniają języki statyczne .Net.
IAbstract
3
Nie jestem pewien, ale jeśli metaprogramowanie jest łatwiejsze w językach dynamicznych (z pewnością wyglądało to łatwiej w Ruby niż Java, kiedy ostatnio patrzyłem), może to mieć wpływ na decyzje architektoniczne. Nie jestem pewien, jaki wpływ, ponieważ tak naprawdę nigdy nie pracowałem nad czymś tak dużym w tych dynamicznych językach.
FrustratedWithFormsDesigner

Odpowiedzi:

14

Wyjaśnijmy kilka rzeczy prosto:

  1. Interaktywne skrypty i języki statyczne nie wykluczają się wzajemnie. Zarówno F #, jak i Haskell mają interfejsy REPL.
  2. Dynamiczne języki i wysoka wydajność nie wykluczają się wzajemnie, choć niektóre optymalizacje są. JavaScript działa teraz bardzo szybko w większości przeglądarek.
  3. Nawet w dynamicznych językach nadal musisz dokumentować, zapamiętywać i myśleć o typach.
  4. Ze względu na rosnącą popularność wnioskowania o typach wiele języków statycznych nie musi już często notować typów. W językach statycznych z silnym wnioskowaniem typu, kompilator rozpoznaje typy z twojego kodu, więc przez większość czasu i mówi ci, jeśli kiedykolwiek zrobisz coś, co narusza definicje typów. Jeśli chodzi o składnię, zapewnia to najlepsze z obu światów.
  5. Języki OOP i dynamiczne nie wykluczają się wzajemnie. PHP obsługuje teraz klasy, a nawet dziedziczenie.

Pomijając te wszystkie zaskakujące podobieństwa, istnieją pewne praktyczne różnice, które wpływają na proces rozwoju:

  1. Dynamiczne języki pozwalają na ciekawe sposoby przekazywania danych w małych .
  2. Języki statyczne pozwalają zmniejszyć liczbę testów, które musisz wykonać, uniemożliwiając wiele rodzajów błędów.
  3. W tym samym stylu języki statyczne umożliwiają ciekawe funkcje sprawdzania poprawności i automatycznej konwersji, takie jak jednostki miary w F # .
  4. W skrajnych, statycznych językach dopuszcza się kontrakty kodu i formalną weryfikację, które mogą dokumentować i eliminować takie sytuacje, jak potencjalne dzielenie przez zera, nieskończone pętle, zerowe odwołania, niepoprawne rozmiary lub indeksy list, błędy zakresu i inne logicznie nieprawidłowe stany które możesz zdefiniować.
  5. Idąc jeszcze dalej, optymalizacje procesora można przeprowadzić w oparciu o te ograniczenia statyczne, co zapewnia jeszcze lepszą wydajność.

Istnieje również jeden typ programu, który nigdy nie powstałby bez pisania statycznego: Singularity , system operacyjny bez granic procesu sprzętowego. Jest napisany w niewielkiej ilości C, trochę C # i dialekcie C # o nazwie Spec #, który obsługuje kontrakty kodowe.

Pomimo tego, że napisane są w śmieciowym języku, wydajność wielozadaniowości i komunikacji międzyprocesowej w tym systemie operacyjnym jest w rzeczywistości lepsza niż cokolwiek innego, ze względu na fakt, że wszystkie procesy działają w jednej przestrzeni pamięci oraz dzięki formalnej optymalizacji weryfikacji I wspomniano powyżej. Nie można tego zrobić bez pisania statycznego, ponieważ aby programy nie były w stanie zagrozić reszcie systemu, obiekty komunikacyjne muszą być weryfikowalne statycznie.

Jednak przez większość czasu architektury powinny wyglądać tak samo. Języki statyczne mogą w wielu przypadkach ułatwić zrozumienie programów, ponieważ typy są dobrze zdefiniowane, ale dobrze napisany program w języku dynamicznym miałby również typy, które przynajmniej są dobrze zdefiniowane w umysłach programistów.

Rei Miyasaka
źródło
Czy Singularity może zapewnić gwarancję maksymalnego opóźnienia w czasie rzeczywistym?
Eonil
@Eonil Niezupełnie moja dziedzina, ale myślę, że pytasz, czy może to zrobić w czasie rzeczywistym. Nie sądzę, skoro wszędzie korzysta z wyrzucania śmieci. O ile wiem, osobliwość nie była aktualizowana od jakiegoś czasu, ale być może ktoś zrobił coś podobnego z śmieciarzem w czasie rzeczywistym.
Rei Miyasaka
Dzięki. Chciałem tylko sprawdzić. Słyszałem, że istnieją pewne implementacje GC w czasie rzeczywistym, ale nie słyszałem, jak są one stosowane praktycznie w branży…
Eonil
2

Istnieje znacząca różnica architektoniczna. Wydajność.

W zależności od budżetu na sprzęt, oczekiwanych obciążeń i umów dotyczących poziomu usług może nie być możliwe spełnienie wymagań za pomocą dynamicznego języka.

Najczęściej szybkość rozwoju i elastyczność zapewniana przez dynamiczne języki równoważą wolniejsze czasy reakcji, wyższe zużycie procesora i pamięci. Jednak w przypadku większych systemów z ograniczeniami dotyczącymi budżetu lub wydajności koszty dynamicznego języka mogą być wysokie.

James Anderson
źródło
1

Nigdy nie myślałem w tym kierunku. Kiedy powstał Google, blog Petera Norviga był jednym z najpopularniejszych hitów. Mówi, że niektóre wzorce projektowe są łatwiejsze do wdrożenia w językach dynamicznych niż tradycyjne języki obiektowe, takie jak C ++. Myślę, że powinny istnieć różnice w projektowaniu / architekturze, ponieważ zauważa, że ​​implementacja jest łatwiejsza w dynamicznych językach. Postaram się dodać więcej do odpowiedzi w miarę dalszych studiów.

vpit3833
źródło
1

Czy istnieją jakieś poważne różnice architektoniczne podczas projektowania aplikacji, które będą budowane na językach statycznych (takich jak C # lub Java) i językach dynamicznych (takich jak Ruby lub Python)?

Nie.

Nieco łatwiej jest pisać fantazyjne ramy dla dynamicznych języków. Ale to nie jest kwestia aplikacji.

Jakie są możliwości projektowania, które mogą być dobrym wyborem dla jednego typu, który jest zły dla drugiego?

Naprawdę brak.

Możesz pisać dobre rzeczy w obu językach.

Czy są jakieś przydatne funkcje, które można osiągnąć z jednym typem, który nie jest z drugim (oczywiście w projektowaniu i architekturze)?

Nie.

Różnica polega na tym, że języki dynamiczne to „pisz, uruchamiaj, napraw”. Możesz szybko eksperymentować i naprawiać.

Językami statycznymi są „pisz, kompiluj, buduj, uruchamiaj, naprawiaj”. Nie możesz tak łatwo eksperymentować.

Poza tym są prawie identyczne pod względem możliwości.

Czy istnieją jakieś dynamiczne wzorce projektowe?

Może. Pythoneval() i execfile()funkcje - w pewnym sensie - wskazują dynamiczną funkcję języka, która jest trudna (ale daleka od niemożliwej) do obsługi w języku statycznym. Byłoby o wiele więcej wierszy kodu do kompilacji i wykonania kodu w tej samej przestrzeni procesu.

Nie jest on specyficzny dla języka dynamicznego. To jest po prostu łatwiejsze.

S.Lott
źródło
2
„Nie możesz tak łatwo eksperymentować.” - To prawda, że ​​kompilator pomaga znaleźć błędy, podczas gdy w interpretowanych językach możesz nie znaleźć błędu, dopóki użytkownik nie wykona tego wiersza kodu.
Doug T.
4
@Doug T .: „kompilator pomaga znaleźć błędy”. Czasami. Niezbyt często. Ciekawe błędy w ogóle nie mogą zostać znalezione przez kompilator. Do tego służy testowanie jednostkowe.
S.Lott,
2
@ S.Lott Uważam, że interfejsy API napisane w dynamicznych językach wymagają nieco więcej dokumentacji. W języku statycznym podpis metody informuje, jakie typy argumentów są wymagane. W języku dynamicznym nie można tak łatwo stwierdzić - dokumentacja API musi powiedzieć, jakie obiekty są oczekiwane.
kwant
1
@quanticle: To nie jest tak naprawdę architektoniczne, prawda?
S.Lott,
2
„Nie możesz tak łatwo eksperymentować”. - F # i Haskell są językami statycznymi i mają pełnoprawne REPL i rzadko pytają cię o typ identyfikatora lub wyrażenia.
Rei Miyasaka,