dynamicznie typowane - czy ma jakieś plusy?

3

Tak na luzie chciałem zadać pytanie, czy znacie jakieś plusy dynamicznie typowanych języków nad statycznie typowanymi językami? Tzn ja coś tam wiem, pewnie jak każdy, ale też chciałbym po prostu poznać Waszą techniczną opinię, bo dość często tutaj widzę jak dynamiczne języki dostają lanie zwłaszcza od osób, które ich w ogóle nie używają albo od osób, które raz użyli w pracy i się sparzyli na całe życie.

Analogicznie ktoś mógłby mówić, że Haskell jest zbyt dziwny i zbyt akademicki, niepraktyczny, i w ogólne za trudny jak na początek, ale zmienia myślenie (i przez to warto go poznać), sprawia, żę warto zmienić myślenie i przez to ten kto zignoruje powierzchowną opinię może odkryć w tym języku coś pięknego,pouczającego, prawda? I to samo podejście byłoby super wykorzystać tutaj, aby w tej dyskusji padały hasła dotyczące rzeczy, które są mniej dostrzegalne, a jednocześnie stanowią pewną wartość języków dynamicznych. Byłbym wdzięczny za powstrzymanie się od pisania frazesów, że język dynamiczny to zabawka, narzędzie niegodne inżyniera i ogólnie, że to środek, do wprowadzania bałaganu za cenę szybkiego prototypowania. Jeśli ktoś nie wie co zaproponować (bo np. żal go do tego typu rozwązań zalewa), niech się wstrzyma od głosu, dzięki!

O statycznie typowanych językach ludzie pewno powiedzą:

  • często idzie w parze z kompilacją do pliku binarnego
  • a jak plik binarny to często wykonanie jest szybsze, też jest większa oszczędność pamięci, lepiej to współgra z wykorzystaniem procesora
  • programy są bezpieczniejsze, bo są weryfikowane pod kątem zgodności z typami co również ułatwia refaktoryzację i ułatwia zaprojektownie kodu, by uniknąć niepożądanych użyć
  • obsługa błędów również na tym korzysta gdy błędy są zwracane jako wartość funkcji, ponadto łatwiej jest się ustrzec przed nullami
  • IDE taki kod lepiej obsługuje, daje znacznie więcej podpowiedzi i autouzupełnianie
  • kod jest bliższy kontekstowi użycia, stąd łatwo określić co przyjmujemy, łatwo określić co funkcja produkuje
  • poprzez typy łatwiej opisać zmiany jakie następują w trakcie przetwarzania
  • poprzez typy (z pomocą monad) można kontrolować efekty uboczne
  • typy też są dobre w modelowaniu gdzie dane mają dużą regularność, a także pozwalają modelować przetwarzanie tak by podkreślić zmiany jakie następują
  • dodatkowo moc tych punktów rośnie wraz z kodem, który integrujemy, a którego nigdy wcześniej nie pisaliśmy, łatwiej wykryć niezgodności

pewnie jeszcze dałoby radę coś wymyślić trochę punktów :-)

Fajnie byłoby zobaczyć podobne listy uwagi odnośnie atuty jakie mają dynamicznie typowane języki? Co one odblokowują? Ogólnie fajnie byłoby gdyby padło coś ciekawszego niż tylko wrażenia, ze na początku ich nauka jest prostsza, mniej wymagająca i , ż małe programy pisze się szybciej / taniej docelowo kosztem jakości. Mi bardziej chodzi o wskazanie tych cech, ktore robią różnicę na płaszczyźnie projektu, a które na ogół w typowych wojenkach nie są nawet dostrzegalne.

8

Ja piszę w językach zarówno statycznie typowanych (Scala do kodu biznesowego) jak i dynamicznie typowanych (Python i bash do skryptów). Nie widzę zalet typowania dynamicznego oprócz w zasadzie jednej - dynamicznie typowane języki skryptowe nadają się do tworzenia https://en.wikipedia.org/wiki/Glue_code , a konkretnie do oskryptowania projektu i powiązania w całość różnych narzędzi (w jeden proces). Języki statycznie typowane zwykle wymagają fazy kompilacji całego projektu (lub przynajmniej modułu) naraz, a więc utrudnione jest sklejanie kodu z kawałków porozsiewanych po różnych repozytoriach.

Kiedyś był taki argument, że dynamiczne typowanie pozwala zmniejszyć mocno rozmiar kodu, ale języki statycznie typowane rozwijają systematycznie inferencję (wnioskowanie) typów i można mieć zarówno zwięzłość kodu jak i statyczne typowanie, jak np. w Scali czy wspomnianym Haskellu.

8

Ludzie nie potrzebuja dynamicznego typowania tylko inferencji typow.

W takim OCamlu prawie w ogole nie uzywasz jawnego typowania (nawet w sygnaturze funkcji nie piszesz typu) a kompilator - twoj dobry przyjaciel - i tak Ci wskaze w ktorym miejscu w kodzie typy sie nie zgadzaja. Poprawiasz. Jak sie kompiluje to prawie na pewno dziala dobrze (bo to FP jezyk).

W dodatku widzialem juz kilka osob, ktore zachwalaly sobie type hinting w Pythonie. Ze to niby wprowadzilo nowa jakosc do ich pracy. A ja sie pytam: to nie prosciej wziac powazny jezyk z prawdziwymi typami?

Ludzie przez lata argumentowali ze ta "zwiezlosc" kodu to jest jakis duzy plus zeby na koncu i tak musiec robic protezy typowania.

1

Jak już się zdecydowałeś, z jakiegoś powodu, żeby mieć skrypt wykonywalny, którego nie zamierzasz kompilować, to zasadniczo większość zalet statycznego typowania zanika. A skoro tak, to czemu by nie mieć od razu dynamicznego typowania, które pozwala szybciej klepać byle jaki kod — co podkreśla jeszcze jedną z podstawowych zalet języków skryptowych (szybkość iteracji).

Więc to jest bardziej rozmowa o zaletach prekompilacji nad podejściem czysto skryptowym, niż o samym typowaniu — bo się, nie bez powodów, nie przyjęły ani języki prekompilowane z dynamicznym typowaniem (tzn. typami rozwiązywanymi nie przez kompilator, ale podczas działania), jak i języki skryptowe wymagające mocnej zgodności typów (bo i po co, skoro i tak nie ma kompilatora, który by tego dopilnował).

9

IHMO dynamiczne typowanie nie ma zalet, to statyczne typowanie ma wady. Są to:

  • Brak generyków - Najstarsze statycznie typowane języki programowania nie mają generyków. Rozwiązywano to przez dynamiczne rzutowanie a więc pozbycie się typów. W C używa się do tego wskaźników. W Javie 4 wszystko było obiektem :(
  • Ułomne generyki - Teraz jest niby lepiej. Do niedawna za wzór dobrze zrobionych generyków uważałem Haskella, ale teraz w Haskellu nie umiem zaklepać odpowiedniej TypeClassy od dwóch parametrów. Może jestem niedouczony, może powinienem użyć czegoś innego niż TypeClassy, ale w Dynamicznym języku nie byłoby w ogóle tego problemu
  • Często ułomny polimorfizm - polimorfizm oparty o obiektowość jest często ułomny. Przez to w Javie mamy niekończące się fabryki. TypeClassy są lepsze, no ale mam te swoje problemy. Ale IHMO to multimetody z Lispa są najbardziej potężne i pozwalają wyrazić wszystko. Szkoda że nie wszystkie języki dynamiczne mają multimetody
  • Rozwlekły kod - Trzeba powtarzać typy. Np w Javie do znudzenia. Niby teraz w Javie w niektórych miejscach jest już var i typ jest wnioskowany podczas kompilacji, ale programiści do tego stopnia przywykli do powtarzania typów że dostałem zakaz używania var

A i tak przy wszystkich swoich wadach statyczne typowanie jest zaletą

1
Althorion napisał(a):

Jak już się zdecydowałeś, z jakiegoś powodu, żeby mieć skrypt wykonywalny, którego nie zamierzasz kompilować, to zasadniczo większość zalet statycznego typowania zanika.

Nie zgodzę się, bo kod wykonywalny edytuję w IDE, które nie musi nic kompilować, by przeanalizować składnię. Przy statycznym typowaniu mam pełne wsparcie od IDE (nawigacja, podpowiadanie składni i błędów, refaktor, itp itd), a przy dynamicznym wsparcie jest okrojone, w zależności od tego ile typów IDE jest w stanie wywnioskować, a ile nie. Type hinting w Pythonie nie wpływa na kompilację czy wykonywanie programu, ale pomaga IDE we wnioskowaniu typów i dlatego jest używane.

Jeśli chodzi o przyjmowanie się na rynku to:

  • Dart nie zastąpił JavaScriptu prawdopodobnie dlatego, że inne przeglądarki nie miały zamiaru go implementować, a Chrome nie był wtedy jeszcze takim hegemonem jak teraz
  • pisanie skryptów w Javie czy Scali wiąże się ze sporym narzutem na startowanie kompilatora, który jest sporym kawałkiem bajtkodu do zJITowania, oraz z koniecznością posiadania JDK na docelowej maszynie (JDK jest większy i rzadziej spotykany niż Python). Są jednak pewne wysiłki, by ten narzut zredukować: https://github.com/oracle/graal/issues/565 a konkretnie https://www.graalvm.org/reference-manual/java-on-truffle/ gdzie można z jednej strony skompilować kompilator do kodu natywnego, a drugiej strony dalej umożliwiać dynamiczne ładowanie i JITowanie bajtkodu. Może niedługo coś interesującego z tego wyjdzie, np JShell z bardzo szybkim czasem startu.
5

Jeśli robisz projekt tak na jeden dzień (jedna osoba - jeden dzień pracy) to:

  • nie potrzebujesz dokumentacji,
  • nie potrzebujesz testów,
  • nie potrzebujesz specjalnej walidacji wejścia,
  • nie potrzebujesz typów

W przypadku większego projektu brak typów kompensuje się robiąć dodatkowe (durnawe) testy, pisząc zabawną dokumentację z opisem typów, wpierniczając tony asercji co do oczekiwanej postaci argumentów.
Albo płacząc.

IMO nie opłaca się i to nawet bardzo, ale ludzie są dziwni.

Jest ciekawy wywiad z twórcą Ruby on Rails, gdzie jest minimalnie poruszona kwestia dynamic typing. Mnie do dynamic types nie przekonał (to nie był zresztą cel wywiadu), ale daje jakieś spojrzenie na ludzi z drugiej strony. To nie jest jakiś dziwny typ spod ciemnej gwiazdy - w bardzo wielu rzeczach się z nim zgadzam.
(Wrzucam, bo bardzo podobał mi się ten wywiad (audio) i dał mi do myślenia - między innymi to, że wśród tych dziwnych są ludzie, którzy IMO są bardzo łebscy)

https://corecursive.com/045-david-heinemeier-hansson-software-contrarian/

2

Gdy kod to nie jest nic ponad skrypt ponad kilka do kilkadziesiąt linii to zaletą jest brak "rozwlekłego rozpisywania się o typach jakie będą użyte".
Gdy kod to front-end to jakieś dopisanie, doklejenie czegoś w takim JS jest proste dlatego że nawet poważna zmiana nie wymaga przebudowania tego co już zostało napisane.

Zastosowanie decyduje o mocnych i słabych stronach. Słabe w jednym zastosowaniu będą dużą zaletą w innym.

2

Już padło: glue code, bo ad hoc można sobie wziąc output skądkolwiek i przekazać gdziekolwiek, jak nagle typ się zmieni to oszczędza to robotę. W małych projektach/skryptach to się sprawdza.
Przy czym piszę teraz w Pythonie kod - powiedzmy - okołosieciowy, dość niskopoziomowy; nie dlatego że chcę, dlatego że mnie "zmusili", tzn. firma ma taki standard że taka a taka klasa tooli ma być w wężu. Takiej liczby bzdurnych unit testów na konwersje typów pomiędzy int a intem z zadeklarowaną długością nie napisałem jeszcze nigdy, końca nie widać. I szczerze: rozumiem, że C czy C++ byłoby tu trudne "bo UB i wskaźniki", ale mam dziką ochotę napisać to Go albo Rust, bo kod będzie 30x bardziej zwięzły.

1

Największa jaką widzę (oprócz tego co już zostało powiedziane) to łatwe klepanie happy pathów np. w prostych skryptach. Jak piszesz w języku statycznie typowanym, to system typów cię ogranicza , bo musisz sprawdzać błędy, których nie ma (ewentualnie czają się). Przykładowo, jeżeli twój skrypt ma przerobić jsona na inny json, to w takim pythonie możesz przerobić taki dokument na normalną strukturę danych, przez co możesz użyć wszystkich znanych mechanizmów języka w swoim programie. Nie interesuje cię, czy pod /raz/dwa/0 jest liczba, czy lista, bo pythonowi to wszystko jedno, jak się nie będzie zgadzać to poleci wyjątek. W statycznym języku też byłoby to możlwe, ale musiałbyś użyć osobnej biblioteki, która wprowadzałaby taką dynamiczność, co prowadzi to konkluzji odwrotnej co do typowania w pythonie: "po co używać dynamicznego typowania w języku statycznym, skoro można użyć dynamicznego języka"

1

bo musisz sprawdzać błędy, których nie ma

No bo kazdy jezyk statycznie typowany ma checked exceptions :v
(sarkazm, wcale tak nie jest)

W statycznym języku też byłoby to możlwe, ale musiałbyś użyć osobnej biblioteki, która wprowadzałaby taką dynamiczność

Co?

2

Jak dla mnie nie jest kwestia w dynamicznym typowaniu, tylko w tym, żeby się wygodnie pisało programy i żeby to było czytelne.
Można to osiągnąć za pomocą dynamicznego typowania, można to osiągnąć za pomocą statycznego z inferencją typów (tak, żeby nie zmuszać programisty do pisania zbyt dużej ilości boilerplate'u związanego z typowaniem)

Przy czym ostatnie 2 dekady królowało dynamiczne typowanie (PHP, JS, Python, Ruby itp.), mam wrażenie, że od paru lat jest ofensywa języków statycznie typowanych i w ogóle wrzucania statycznego typowania do języków dynamicznie typowanych (no bo duże projekty w językach dynamicznych to nie musi być dobry pomysł), i pewnie ten trend się utrzyma jeszcze z dekadę, dwie, aż znowu się koło zakręci i wrócą do łask języki dynamicznie typowane (tylko wtedy ktoś by musiał do nich zrobić dobry tooling).

Z drugiej strony statyczne języki też się rozwijają i zaczynają przypominać coraz bardziej języki skryptowe, a języki skryptowe zaczynają wcielać statyczne typowanie (np. TypeScript), więc w przyszłości pewnie się to wymiesza wszystko.

Aha, jest jeszcze kwestia prototypowania czy pisania czegoś na szybko. Dla mnie możliwość dodawania właściwości do obiektów w locie w JS to super ficzer, który pozwala na szybkie napisanie czegoś, bo po prostu dodajesz coś do obiektu (tak, nie będzie to utrzymywalny kod, ale nie o to tu chodzi). Języki statycznie typowane raczej nie pozwoliłyby mi na takie dodawanie właściwości (chyba, że trzymałbym wszystko w hashmapach). No i ogólnie luźne podejście do obiektów(np. duck typing) pozwala na pisanie czegoś szybciej niż przy mozolnym deklarowaniu interfejsów w językach statycznie typowanych. Mimo, że to drugie byłoby bardziej eleganckie.

Więc prototypowanie/pisanie czegoś na szybko/pisanie w pojedynkę vs. pisanie dużej apki przez wiele miesięcy rozwijanej przez wiele osób.
To trzeba brać pod uwagę, jak się patrzy na to, co lepsze.

1

Domyślam się, że obecnie opisujecie plusy dynamicznego typowania z najbardziej znanej wam perspektywy czyli przepływu:
projektuj -> pisz -> buduj -> uruchamiaj i faktycznie tutaj statycznie typowanie wygrywa, bo najpierw piszemy, ubezpieczamy się na wiele sposobów, by uruchomienie było w możliwie dużym stopniu poprawne. Ja stawiam, że w takim obiegu będzie technicznie bardziej poprawny, ale czy biznesowo jest poprawny to tutaj nie ma gwarancji, i z tym bywa różnie, chyba, że wprowadzamy jakieś drobne oczywiste poprawki.

A czy widzicie jakieś korzyści, gdyby ten kierunek wyglądał odwrotnie, tzn:

uruchamiaj -> buduj -> pisz -> projektuj?

Ja myślę, że ten przepływ akurat jest wręcz nieopłacalny do odtworzenia z perspektywy statycznych języków. Co myślicie o tym?

1

Aplikacja rozwijana kilka miesięcy ma już zestaw testów jednostkowych i infrastrukturę do nich (a przynajmniej powinna i zakładam tutaj, że ma dobre pokrycie kodu). Przetestowanie nowymi testami (na wzór tych starych i używających obecnej infrastruktury) nowej funkcjonalności jest w całościowym rozrachunku szybsze niż stawianie aplikacji co chwilę, pchanie do niej danych testowych i ręcznie sprawdzanie czy daje dobre wyniki. Wyjątkiem są skrypty w bashu i Pythonie, bo te (w praktyce) nawet jeśli są pisane miesiącami czy latami, to i tak nie mają testów jednostkowych.

0

W statycznym języku też byłoby to możlwe, ale musiałbyś użyć osobnej biblioteki, która wprowadzałaby taką dynamiczność,

Przykład: posortuj mi listę w jsonie dostępną pod scieżką /a/b/c. W jakim języku statycznym jestem w stanie użyć gotowej funkcji sort/sorted, żeby rozwiązać ten problem?

@slsy

w Go udało mi się zrobić coś takiego:

func get(obj interface{}, key string) interface{} {
	return obj.(map[string]interface{})[key]
}

func main() {
	var data interface{}
	json.Unmarshal([]byte("{\"a\":  { \"b\":  { \"c\":  [2, 5,3,1,4]}  }   }"), &data)
	var list = get(get(get(data, "a"), "b"), "c").([]interface{})
	list2 := make([]float64, len(list))
	for i, value := range list {
		list2[i] = value.(float64)
	}
	sort.Float64s(list2)
	fmt.Println("lista", list2)
}

Możliwe, że da się prościej i ktoś bardziej obeznany z Go zrobiłby to lepiej (no i nie ma tu obsługi błędów, więc program spanikuje, jeśli ścieżki nie będą się zgadzać. Czyli... happy path ;) ), tym niemniej jest to jakiś proof of concept, że się da napisać to, co proponujesz, w języku statycznie typowanym.

1

@LukeJL: w twoim przypadku napisałeś wlasy kod wprowadzający tą dynamiczność (funkcja get). Do tego nie sprawdzasz błędów i nie serializujesz ponownie dokumentu, W porównaniu do pythonowego import sys, json; x = json.load(sys.stdin); x["a"]["b"]["c"].sort(); print(json.dumps(x)) jest dużo więcej boilerplatu. Do tego, żeby być złośliwym: posortuj mi slice Int64

3

Dzięki za odpowiedź. Myślę, że wszystkie 4 punkty jakie wymieniłeś możliwe, że są problematyczne w Javie, ale gdyby tak szerzeć popatrzeć to nie jest to ograniczenie jakie wynika wprost ze statycznego typowania.

Odpowiem w poście bo dużo tego:

  • Brak generyków - C dalej nie ma generyków, Go do niedawna nie miał. Trudno o prosty język z generykami.
  • Ułomne generyki(i skomplikowane generyki) - jak powiedziałem w Haskellu nie umiem zrobić. W Javie bym to zaklepał bez problemu
  • Ułomny polimorfizm - tu nie krytykuje Javy tylko wszystkie języki obiektowe
  • Rozwlekły kod - C++ i C# mają auto/var też względnie od niedawna. Chociaż badania nad wnioskowaniem typów trwają od czasu pojawienia się języka ML, a później było to z powodzeniem wdrożone w SML, OCamlu i Haskellu

Historia informatyki dowodzi że trudno zrobić język programowania który będzie statycznie typowany oraz będzie posiadać dobre i proste generyki oraz dobry i prosty polimorfizm. Z drugiej strony napisanie własnego interpretera Scheme to zadanie które mogą dostać studenci 2 roku jako projekt semestralny i było to realizowane w ramach podręcznika SICP.

1

Największym, imo, problemem języków dynamicznych jest wydajność - ze względu na dynamikę trudno się je optymalizuje. A zalety, szybkie prototypowanie na pewno, czytelność kodu.

3

@LukeJL:
To moze troche ladniej

import kotlinx.serialization.*
import kotlinx.serialization.json.*

@Serializable
data class Cc(var someList: List<Int>)

@Serializable
data class Bb(val c: Cc)

@Serializable
data class Aa(val b: Bb)

fun main() {
    val rawJson = """ {"b":{"c":{"someList":[2,5,3,1,4]}}} """

    val a = Json.decodeFromString<Aa>(rawJson)

    a.b.c.someList = a.b.c.someList.sorted()

    val serialized = Json.encodeToString(a)

    println(serialized)

    // {"b":{"c":{"someList":[1,2,3,4,5]}}}
}
2

IMO w porównaniu do w miarę współczesnych języków statycznie typowanych (które mają sensowne generyki, inferencję typów itd) zalety języków dynamicznie typowanych się drastycznie zmniejszają - z grubsza da się pisać równie zwięzły i ekspresywny kod w obu, czasami nawet bardziej zwięzły przy silnym typowaniu - fakt faktem jak chce się mieć type checki w Pythonie to nie dość, że będą w runtime, to wymagają napisania boilerplate.

Z drugiej strony, przy upierdliwych językach statycznie typowanych dynamiczne typowanie pozwala oszczędzić sporo czasu i nerwów - chyba, że nie dostrzegam przewagi Object czy void**.

No i przydaje się faktycznie jako glue code, szczególnie w połączeniu z duck typing - jak mam kilka podobnych obiektów z różnych źródeł (biblioteki itd) to nie do końca chce mi się rzeźbić jakieś dodatkowe mappery, wrappery itd, szczególnie gdy prototypuję i robienie enterprajsowego kodu nie za bardzo przyniesie jakąkolwiek wartość :)

7

Rust pilnuje typów jak diabeł, więc trzeba pracowicie je przerabiać, a każda konwersja zwraca optionale, wymuszając sprawdzanie błędów w jakiejś formie.

use serde_json::Value;

fn main() {
    let data = r#"{"a":{"b":{"c":[2,5,3,1,4]}}}"#;
    let json: Value = serde_json::from_str(data).unwrap();
    let mut vec = json["a"]["b"]["c"].as_array().unwrap().iter().map(|i| i.as_i64().unwrap()).collect::<Vec<i64>>();
    vec.sort();
    println!("{:?}", vec)
}

Dla odmiany C++ jest czytelny aż miło :D

#include <iostream>
#include <algorithm>

#include <nlohmann/json.hpp>

using json = nlohmann::json;

auto main() -> int32_t {
    auto j = "{\"a\":{\"b\":{\"c\":[2,5,3,1,4]}}}"_json;
    auto vec =  j["a"]["b"]["c"];
    std::sort(vec.begin(), vec.end());

    std::cout << vec << std::endl;
}
6

Każdy język ma jakieś przeznaczenie i wymuszanie typów ma sens w jednych językach a nie ma w innych. W JS czy Pythonie mogę iterować po właściwościach klasy i obiektu, więc typ można sobie odczytać w trakcie działania programu. Z resztą weźmy przykład z C++:

User user;

Jeśli chcę wiedzieć co jest w typie User to i tak muszę kliknąć na jego nazwę w IDE - User mówi coś o typie, ale nic o udostępnianym przez ten typ interfejsie. Czasem jednak jeśli piszę coś, to nie obchodzą mnie typy. Np. w Pythonie:

def addNumbers(a, b):
    return a+b

Nazwa funkcji sugeruje to, co funkcja robi. To też napisałbym w dokumentacji. Jeśli użytkownik poda argumenty, które obsługują dodawanie inaczej albo wcale, to jego problem - dostanie wyjątek podczas działania programu (z resztą throws w Javie to raczysko). W C++ odpowiedni komunikat byłby na etapie kompilacji (no chyba, że ktoś poda parametry z przeciążonym operatorem dodawania) - wcale nie byłby bardziej czytelny od wyjątku w Pythonie.
Często typy w niektórych językach są niepotrzebne. Nie wyobrażam sobie w bashu zapisu w stylu:

(string[]) grep psyduck pikachu.txt | (string) wc -l >> new File("out.txt")

No bo skoro typy byłyby wymuszone, to i konwersja mogłaby być jawna. Już pominę awk i wyrażenia regularne. Jak chcę napisać parę linijek to piszę.
Wniosek: typy są dobre tam, gdzie są przydatne/ niezbędne.

2

Co do przykładu, to nie mogło zabraknąć scali:

import rapture.json._
import rapture.json.jsonBackends.jackson._
import rapture.data.dictionaries.dynamic.implicitDictionary

object Main extends App {
  val json = json"""{"b":{"c":{"someList":[2,5,3,1,4]}}} """
  println(json.b.c.someList.as[Seq[Int]].sorted.mkString(","))
}

Jak już znajdziemy pakiet, który działa w naszej wersji Scali , i ogarniemy które implicity i pakiety są potrzebne to jest fajnie.
(rapture dla scali 2.13 nie znalazłem, bo jakiemuś pięknemu programiście nie chciało się opublikować- ech...)

4

Przykład języka programowania który dobrze spisuje się bez typów to... Bash! Poza tym wszędzie tam gdzie mamy do czynienia z danymi nie-ustrukturyzowanymi które były by reprezentowane przez Map'y i List'y języki dynamiczne będą pasować jak ulał (obróbka danych pod data-science, ekstrakcja danych z tekstu).

W każdym innym wypadku, typowane są lepsze. Ostatnio widać to dobrze na migracji JS -> TS. Wzrost złożoności webappek sprawił że typy zaczeły być jednak przydatne!

2

@0xmarcin:

Przykład inny, to SQL, gdzie wszystko mogłoby być jednym typem tekstowym - CDATA - i też dałoby się z tym żyć (pomijam blob i podobne). I do XML doga niedaleka

1

@BraVolt: Gdyby w SQLu wszystko było typem tekstowym to mocno ograniczyłoby to możliwości indeksów (tych do wyszukiwania przedziałów). Indeksować możesz po datach czy liczbach. Teoretycznie możesz je zamienić na tekst i wtedy indeksować, ale:

  • leksykograficznie "5" jest większe od "15", więc musiałbyś zaimplementować porównywanie parsujące liczby - po co tak kombinować skoro można mieć liczby wprost?
  • sortowanie dat ze strefami czasowymi by w ogóle nie wypaliło (w sensie w standardowych formatach), a nawet te bez stref czasowych musiałyby być sformatowane w odpowiedni sposób, by sortowanie leksykograficzne dało oczekiwany efekt
0

@Wibowit:

Indeksowanie to już bardziej implementacja. A formaty daty, stref czasowych w xml latają w prostym formacie tekstowym.

0

Czy Ty porownujesz XMLa do bazy danych?

0

@stivens:

Jak do XML dodasz JSON to wyjdzie ładne "Not Only SQL"

1

Co do tej redukcji ilości kodu jaki piszemy w dynamicznych językach to się trochę nie zgodzę. Tzn teoretycznie jak nie mamy inferencji typów to tak, trzeba pisac te długie nazwy, ale w praktyce mamy ctrl + spacje w IDE, więc jak ktos nie kodzi w notatniku to ten argument jest trochę inwalidą ;) Ogólnie cieszy mnie to że inferencja typów stała się popularna, więc argument o boilerplate staje się inwalidą.

1 użytkowników online, w tym zalogowanych: 0, gości: 1