Czy statyczne i dynamicznie pisane języki mogą być postrzegane jako różne narzędzia dla różnych rodzajów zadań?

9

Tak, zadawano podobne pytania, ale zawsze w celu ustalenia „które z nich jest lepsze”.

Pytam, ponieważ pojawiłem się jako programista przede wszystkim w JavaScript i tak naprawdę nie mam dużego doświadczenia w pisaniu w statycznie pisanych językach.

Mimo to zdecydowanie widzę wartość w nauce języka C do obsługi wymagających operacji na niższych poziomach kodu (co, jak zakładam, ma wiele wspólnego ze statycznym vs dynamicznym na poziomie kompilatora), ale tym, co próbuję ominąć jest to, czy istnieją specyficzne konteksty projektu (może pewne typy dynamicznych operacji intensywnie wykorzystujących dane?) obejmujące rzeczy inne niż wydajność, w których znacznie bardziej sensowne jest używanie Java lub C # w porównaniu z Pythonem.

Erik Reppen
źródło
5
Odpowiedź brzmi tak". Każdy rodzaj języka - a właściwie każdy język - ma swoje mocne i słabe strony, dlatego lepiej nadaje się do niektórych zadań niż do innych.
ChrisF
ciekawe jest to, że używasz C jako przykładu, ponieważ jest to rodzaj najsłabiej napisanego języka, który możesz zrozumieć i nadal nazywać go statycznie. C nie jest szybki ze względu na system typów, sprawdzanie typu odbywa się w czasie kompilacji. C jest szybki, ponieważ istnieje niewiele środków bezpieczeństwa i kontroli, które uniemożliwiają strzelanie sobie w stopę. i ponieważ kompiluje się do natywnych plików binarnych.
sara,

Odpowiedzi:

10

Tak, zdecydowanie.
Pisanie dynamiczne ma zdecydowane zalety w przypadkach, w których chcesz traktować wszystko jako jeden typ. Serializacja / deserializacja jest jednym z klasycznych przykładów. Dlatego tak dużo programowania WWW wykonuje się w dynamicznie pisanych językach skryptowych: są one dobrze dostosowane do zadania, które wymaga dużej ilości konwersji wszelkiego rodzaju danych na i z łańcuchów.

Z drugiej strony do programowania aplikacji języki statyczne działają znacznie lepiej, ponieważ próba traktowania wszystkiego jako jednego typu nie jest często wymagana. Często chcesz mieć wydajne struktury danych, w których dane są przedstawiane jako same i nie są bardzo często przekształcane w inne typy. To sprawia, że ​​funkcje dynamicznego pisania są wadą, a nie korzyścią, dlatego aplikacje są prawie wyłącznie pisane w językach o typie statycznym.

Mason Wheeler
źródło
3
@Erik: Nie jestem pewien, czy bym to powiedział. Rzeczy zmieniają się podczas rozwoju. Wymagania mogą się zmienić lub okaże się, że nie wdrażasz poprawnie wymagań, a kod musi zostać zaktualizowany. Możliwość zmiany jednej rzeczy i wykorzystania wynikowych błędów kompilatora, aby pokazać, gdzie znaleźć wszystko, co należy zmienić, zapewnia ogromny wzrost wygody i szybkości rozwoju, którą tracisz w językach, w których ta technika nie jest dostępna. To jeden z powodów, dla których po prostu nie widzisz skomplikowanych aplikacji tworzonych w dynamicznych językach.
Mason Wheeler,
9
@Mason Wheeler: Bardzo dobra odpowiedź. + 1 Chciałbym dodać, że sprawdzanie typu statycznego pomaga również wcześniej znaleźć błędy, mając poprawność typu sprawdzania kompilatora. Np. Wczoraj debugowałem 200-liniowy program Ruby i były dwa błędy związane z typem, które mogłem wykryć tylko po uruchomieniu programu. Nie chcę myśleć, co dzieje się w projekcie na 100 000 linii. Tak więc dynamiczne pisanie daje większą elastyczność, co jest dobre w opisanych kontekstach, za cenę, której nie można znaleźć w czasie kompilacji pewnych błędów. Tak więc typowanie statyczne wiąże się nie tylko z wydajnością, ale także z poprawnością.
Giorgio
1
@MasonWheeler Dwa lata i znacznie więcej C # i Java, niż się później spodziewałem, teraz nie zgadzam się z kilkoma rzeczami. Złożone aplikacje internetowe są tworzone w całości przy użyciu dynamicznych języków. Kompilacja vs. czas wykonywania nie ma znaczenia, gdy można wprowadzać zmiany, które są widoczne natychmiast. I rozwinąłem opinię, że wszystkie zamieszanie nad typami ma o wiele większy sens w języku proceduralnym niż w języku, który powinien być sterowany przez OOP, w którym dane nie powinny ciągle zmieniać rąk.
Erik Reppen
1
@Erik: * wince * Po pierwsze, ocenianie pisania statycznego jako koncepcji przez Javę jest jak ocenianie samochodów jako koncepcji przez Pinto. Po drugie, wszystko, gdzie zmiany mogą być „natychmiast widoczne”, z definicji nie jest programem bardzo złożonym, ponieważ nawet przy nowoczesnym sprzęcie złożone programy zajmują sporo czasu na przygotowanie kodu, niezależnie od tego, czy jest to kompilator, czy interpreter ( lub kompilator JIT) przygotowujący. Nawet najbardziej imponujące aplikacje internetowe są zwykle bardzo prostymi programami wspieranymi przez bardzo złożone bazy danych, co jest zupełnie inną sprawą.
Mason Wheeler
1
Zdolność do tworzenia złożonych abstrakcji jest ortogonalna do posiadania układu typu statycznego vs. Istnieją systemy typu statycznego, które pozwalają na niezwykle potężne (choć czasem tajemne) abstrakcje. Wprowadzanie zmian, które pojawiają się natychmiast, jest również niezależne od systemu typów: z pewnością możesz budować interpretatory dla języków o typie statycznym.
Rufflewind
4

Patrząc na to, jeśli potrafisz naturalnie pracować w języku o typie statycznym, to dobrym rozwiązaniem jest pisanie statyczne. Ogólnie rzecz biorąc, celem systemu typów jest zapobieganie wykonywaniu operacji z niezdefiniowaną semantyką (string) "hello" + (bool) true. Dodatkowy poziom bezpieczeństwa uniemożliwiający wykonywanie tych operacji może być dobrym sposobem na uniknięcie błędów w kodzie, nawet bez obszernych testów jednostkowych. Oznacza to, że bezpieczeństwo typu zapewnia kolejny poziom pewności co do poprawności semantycznej kodu.

Ale systemy typów są bardzo trudne do prawidłowego działania. Nie wierzę, że jest to doskonały układ typu w przyrodzie w momencie pisania tego tekstu. (Przez „idealny system typów” mam na myśli ścisły system typów, który nie wymaga pełnych adnotacji kodu, który nie generuje fałszywych błędów typu, i których błędy typu są łatwe do zrozumienia dla programisty.) Ponadto, może trudno jest zrozumieć naprawdę dobre systemy typu, które istnieją. Kiedy uczyłem się Haskell, nie mogę powiedzieć wam liczby niejasnych błędów typu, które wystąpiły podczas próby napisania czegoś, co wyglądało (dla mnie) jak poprawny kod. Zwykle kod nie był właściwie poprawny (co jest zaletą dla systemu typów), ale zabrał dużo czasupracy, aby zrozumieć komunikaty o błędach z kompilatora, abym mógł rozwiązać podstawowe problemy. W językach OO możesz w końcu pomyśleć: „ten argument powinien być sprzeczny z typem wejściowym, a nie kowariantnym!” Lub (bardziej prawdopodobne) powrócić do typecastów, aby uciec od granic systemu typów. Systemy typów mogą być znacznie trudniejsze, niż myślisz.

Jeśli chodzi o to, co warto, rozumiem, że trudność w znalezieniu dobrych systemów typu jest częścią tego, co zmotywowało Gilada Brachę do włączenia wtykowej obsługi systemu typów w Newspeak.

Aidan Cully
źródło
Testy jednostkowe WRT, całkowicie się zgadzam. Zawsze widzisz ludzi mówiących „jeśli masz dobre testy jednostkowe, mogą zweryfikować poprawność typu dla Ciebie”. Zawsze mi to przypominało, że Paul Graham (który jest głęboko przekonany, że dynamiczne pisanie jest zawsze dobrą rzeczą) mówi, że język zmuszający cię do ręcznego wykonywania pracy kompilatora jest błędny. Sorta sprawia, że ​​zatrzymujesz się i myślisz ...
Mason Wheeler,
Myślę, że wiele obaw związanych z „niebezpieczeństwami” dynamicznie pisanych języków nie uwzględnia sposobu, w jaki piszemy te rzeczy. Wiele Python i JS można napisać w stylu konsoli. Skompiluj kompilację vs. czas wykonywania, mogę wypróbować ją teraz i zobaczyć, co się stanie. Myślę jednak, że masz jeden bardzo dobry punkt. Nic nie sprawia, że ​​jestem bardziej szalony w tworzeniu stron internetowych po stronie klienta niż wtedy, gdy wszyscy rzekomo dobrzy producenci przeglądarek dają mylące przekazywanie okropnego kodu, podczas gdy IE6 lub 7 robi to nieoczekiwane, czyli do bzdur, kiedy powinno, a nie tylko ... ssanie w bardziej typowy sposób.
Erik Reppen,
@ Niedopasowane typy mason-wheeler są trywialnymi błędami i nie jest tak, że języki dynamiczne nie sprawdzają typów, tylko w czasie wykonywania. Z mojego doświadczenia wynika, że ​​większość języków statycznych ma taki sam poziom pokrycia testów jednostkowych, nie tracą żadnych testów po wcześniejszym sprawdzeniu typów kompilatora, a języki dynamiczne nie muszą dodawać konkretnych testów do sprawdzania typów , system wykonawczy sprawdza typy, jeśli test jednostkowy obejmuje twoją metodę, złapie je.
jbtule,
4

Są to różne narzędzia, ale nie zależy to od wydajności. Chodzi o złożoność .

Języki dynamiczne zwykle dążą do maksymalnej elastyczności, co niesie ze sobą brak walidacji i rodzaj gwarancji. Następnie jest bardzo wydajny w programach na małą skalę, ale utrzymanie programów na dużą skalę (złożoność) staje się prawie niemożliwe.

Języki statyczne zwykle mają na celu maksymalną walidację. Ich pierwszym celem jest zwykle wykrywanie błędów (lub błędów) jak najwcześniej. Na walidację składa się wiele gwarancji. Wówczas trudniej jest się nauczyć i zacząć, ale w miarę powiększania się programów zapewnia lepszą weryfikację programu przy znacznie niższych kosztach (wysiłki związane z kodowaniem).

W rezultacie języki dynamiczne zwykle pasują do małych (mam na myśli bardzo małe) programów, takich jak dynamiczne strony internetowe, DSL przeglądarki internetowej (nie dla aplikacji przeglądarki!) Lub skrypty powłoki. Języki statyczne lepiej pasują do programowania systemu lub innych rzeczy.

Powyższe opisy dotyczą bardzo czysto dynamicznych lub statycznych języków. Większość prawdziwych języków znajduje się pomiędzy nimi i wykazuje różne cechy.

Zobacz tutaj po więcej szczegółów: https://softwareengineering.stackexchange.com/a/105417/17428

Eonil
źródło
1
„języki dynamiczne zwykle pasują do małych (mam na myśli bardzo małe) programów”: Z mojego doświadczenia wynika, że ​​można używać języków dynamicznych także do średnich aplikacji (i oczywiście są ludzie, którzy z powodzeniem je wykorzystują do dużych aplikacji). Zgadzam się, że im większa baza kodu, tym więcej możesz zyskać na sprawdzeniach statycznych zapewnianych przez języki statyczne.
Giorgio
2
@Giorgio Cóż, może dlatego, że jestem uzależniony od statycznego sprawdzania poprawności. To dla mnie takie słodkie i dosłownie nie mogę bez nich żyć nawet na małą skalę: p
Eonil
Widzę zalety języków statycznych (i poparłem twoją odpowiedź). Ostatnio używam Pythona i Common Lisp i przyznaję, że w praktyce osiągasz dobre wyniki, jeśli używasz czystego projektu, a zwłaszcza w Pythonie, jeśli piszesz wystarczającą liczbę testów. Te języki mogą być bardzo skuteczne w tworzeniu prototypu, który z łatwością można przekształcić w kod produkcyjny. Ale tak, w przypadku bardziej złożonych projektów chciałbym uzyskać jak najwięcej pomocy, więc wolę język statyczny.
Giorgio
1

Obecnie programuję w językach statycznych (C # i F #), ale lubię programować w językach dynamicznych (Smalltalk, Ruby). Istnieje wiele zalet i wad, które ludzie kojarzą z jednym typem w porównaniu do drugiego, które są bardziej związane z językiem niż w przypadku egzekwowania typów. Na przykład języki dynamiczne mają zwykle czystszą, bardziej zwięzłą składnię, jednak F # i OCaml z systemem wnioskowania o typie mają tak samo czystą składnię jak każdy język dynamiczny. A przy pisaniu statycznym masz prawdziwe automatyczne refaktoryzacje i autouzupełnianie, ale Smalltalk, z całym kodem źródłowym w bazie danych i każdą metodą skompilowaną osobno, był pierwszym językiem, który naprawdę miał poważne automatyczne refaktoryzacje i działał świetnie. Ostatecznie współczesne języki dynamiczne i statyczne są dziś bezpieczne dla typów, co jest najważniejszym aspektem twojego systemu typów,

jbtule
źródło
Czasami podejrzewałem, że pisanie statyczne jest tylko niewielką częścią równania tego, co czyni język mniej lub bardziej elastycznym. Myślę też, że zaczynam zdawać sobie sprawę, że wielu programistów woli prowadzić od nich wygodny zestaw szyn, niż mieć swobodę robienia absurdalnie niebezpiecznych rzeczy, takich jak przeciążanie operatorów. VS sprawia, że ​​czasami chcę kopać szczenięta, ale zdecydowanie jestem ciekawy F #, a to, co powiedziałeś o tym, jeszcze bardziej mnie ciekawi. Zakładam, że jest to coś więcej niż tylko C #, w którym można pośrednio rzutować na bardziej inkluzywny typ.
Erik Reppen,
@erik, Oh tak więcej niż sugerowanie pisania i var: F # Wnioskowanie typu
jbtule
-1

Jest rok 2015, który dodaje kilka interesujących fragmentów do rozmowy:

  1. Znacząca część korporacyjnego świata zaplecza rozważa lub zaczyna używać Pythona (dynamiczny) zamiast Java (ścisła statyczność)
  2. Przedsiębiorstwo frontend świat widzi rzeczy jak angularjs v2, na podstawie TypeScipt: a wpisywanych przedłużenie JavaScript.

Więc faceci backendowi są zmęczeni niepotrzebną prostą kurtką ścisłego pisania, podczas gdy faceci frontendu są zmęczeni chaosem dynamicznego pisania.

Całkiem ironiczne: zastanawiam się, czy spotkają się w środku, czy też przebiegną obok siebie z dźwiękowym hukiem upływającego terminu ...? ;)

Cornel Masson
źródło
O ile nie dostarczysz żadnego dowodu, twierdzę, że w najgorszym przypadku świat backendu przechodzi do Go, ale niech Bóg zabrania jakichkolwiek dynamicznych, skąpych rzeczy. Mit, że statyczny język programowania zawsze ma wiele ceremonii dawna debunked z bardziej zaawansowanych systemów wnioskowania i stałych wdrożeń rEPL
Den
W dużych skalach jest mnóstwo dynamicznie wpisywanych tylnych końcówek. W szczególności Django jest bardzo popularny w dziennikarstwie i prowadzi zaplecze dla NYT, Guardian i Washington Post. Walmart działa na Węzle. Jedynym mitem jest pomysł, że nie można pisać dla skali bez typów statycznych. I po tym, jak spędziłem trochę czasu na myśleniu o katastrofach bazowych kodu Java, na które wpadłem, myślę, że ludziom, którzy czują się tak dobrze, lepiej będzie, jeśli pracują ze statycznym lub dynamicznym.
Erik Reppen
Rzeczywiście wolałbym mieć wykwalifikowany zespół Pythona przy moim dużym przedsięwzięciu, zamiast kiepskiego Javy. Muszę tylko wyjaśnić swoje stanowisko: zamieściłem powyższą odpowiedź jako ocenę
Cornel Masson,
Rzeczywiście wolałbym mieć wykwalifikowany zespół Pythona przy moim dużym projekcie korporacyjnym, niż kiepski Java. Żeby wyjaśnić: zamieściłem powyższą odpowiedź jako spostrzeżenie na temat trendów, które widzę w mojej bazie klientów, sieci branżowej i ogólnych badaniach. Tradycyjnie ścisły backend obejmuje mniej restrykcyjności, tradycyjnie luźniejszy frontend, więcej. To nawet nie jest opinia, która jest „właściwa” (jeśli w ogóle) - nie jestem pewien, dlaczego zostałem przegłosowany. Być może ironia przepadła ...
Cornel Masson,