Obávám se, že takto statické typování nefunguje. Všechny příklady tebou naznačného spektra možností mohu řešit. A statické typování mi bude hodně pomáhat. (A nemusím to dělat ručně.)
Zkusme být konkrétní. Bylo tu uvedeno parsování JSONu. Řešil bych to určitě staticky. Rozhodování zpracování podle typu dat? Staticky. Rozhodnování podle dat - to si nejsem jist, co myslíš. Jak se mohu rozhodovat podle dat? Čeho se mohu chytnout? Můžeš uvést příklad?
Netvrdím, že to nejde. Kdyby to nešlo, tak by většina praktických problémů byla neřešitelná staticky typovanými jazyky. Jenže to, co vnímáš jako cosi, co ti bude hodně pomáhat, já často vnímám jako klacky motající se pod nohama.
Takže něco takového jako když já po milióntý prvý pouštím celou aplikaci, a píšu druhou miliardu testů, aby to pokrylo alespoň 5procent všech možnejch chyb? :-)
Toto asi už bude o pocitech, takže to nerozebírejme. Zajímají mě tedy asi spíše nějaké racionálnější argumenty.
Rozhodování podle dat, tím myslím IF size > 5 cm THEN ...
Rozhodování podle typu, tím myslím IF (x hasMagnitude) THEN ...
Rozhodování bez ohledu na typ, tím myslím IF x > 5 THEN ..., bez ohledu na to, co to "x" je, protože mě zajímá jen odpověď na otázku, zda "to" je větší než 5.
Rozumím. Tak první bude nějaká funkce. Druhé bude pattern matching na typ. A třetí se řeší třídou/interfacem. Viz odpověď dále.
Konkrétní příklad bych vzal mnohem prostší - chceš realizovat jakýsi print(x), který zajistí vypsání argumentu na terminál. Jaký datový typ x-u by ta funkce měla podle tebe optimálně očekávat a proč? V čem mi jakožto vývojáři pomůže, že ta funkce očekává ten konkrétní datový typ? Uvažuješ-li o stringu, tak pokračuj v úvaze dál - jak se teda pak vypořádat s ne-stringy. Nebo třeba seznam v Pascalu...
typ show (v případně Javy by to bylo něco jako Printable)
Takový typ zajistí, že každá hodnota je schopná se převést na string. Včetně toho seznamu. Včetně uživatelského typu.
V Haskellu je to otázka přidání deriving show k definici typu, a všechno si odvodí sám.
Viděl jsi často, že by hostinský točil pivo do papírové krabice, přestože mu v tom nic nebrání? Jistě by šlo zařídit, aby se pípa odjistila jen v případě, že pod sebou detekuje konkrétně určený značkový půllitr. Mě by popadl rapl a ta pípa by letěla na smetiště hned v okamžiku, kdy by mi odmítala pustit pivo do džbánku.
Smysl statických typů je zajistit, aby se něco takového nestalo. Když zůstaneme u přirovnání, tak ty budeš muset hostinského zaškolit, a ještě nainstalovat kameru, aby si ho sledoval, zda nečepuje pivo přímo do pusy. A stejně ho neuhlídáš. Zatímco já tam budu moct dát cedulku "samoobslužná pípa".
Každopádně ve statickém jazyce zajistím, že ta pípa se odjistí jen v případě, kdy je do čeho načepovat. Džbánek ano, papírová krabice ne.
V případě dynamických typů ten problém máš samozřejmě taky. Ale buď ho neřešíš, a doufáš, že všechno dobře dopadne. Nebo testuješ jak blbej, a pak doufáš, že všechno dobře dopadne.
Co je na tašce na rohlíky tak provokativního? Do datového typu rohlík dám jen rohlík a seznam rohlíků není nic jiného než taška na rohlíky. V době překladu vím, že mám datový typ, do kterého můžu naskládat jedině rohlíky. Jistě, mohu vytvořit i datový typ, do něhož jdou sázet rohlíky a housky. Ale i tuto situaci musím předvídat v době překladu.
Ano, musím to předvídat v době překladu. To je jediné, v čem máš pravdu. Jinak fakt neuvažuju, tak jak popisuješ.
Kontainer na rohlíky bych dělal v případě, kdy chci jen rohlíky. Takže to bude třeba recept na jednohubky. Protože ten dělám zásadně z rohlíků.
Ale když budu brát do krámu nějakou tašku, tak bych byl idiot se omezovat takhle, ne. Budu definovat jiná omezení. Ta, která budou užitečná.
Neznám moc jazyků, které by obsahovaly "rohlík" jako jeden ze základních typů.
Taky nás nic takového nezajímá. Doba typování ala jazyk C je naštěstí už dávno pryč.
Budu-li chtít modelovat nákupní tašku, tak jako nejjednodušší případ mě napadá nějaká kolekce, třeba seznam. Ale pořád mi tu BoneFlute nevysvětlil, seznam čeho by to optimálně měl být a jakou by to mělo výhodu oproti obecné dynamicky typované kolekci.
Toho, čeho potřebuješ. To přirovnání je debilní, ale tak můžeš mít nákupní tašku na pečivo. Takže obecný typ pro pečivo. Nebo typ TuháHmota, aby si tam nečepoval to pivo. Atd.
Pak samozřejmě můžeš dojít k závěru, že nevíš, a že tam chceš dát cokoliv. Tak dáš typ *, a budeš tam moct uložit opravdu cokoliv.
Protože staticky typovaný jazyk mi říká "hele, tu informaci, co konkrétně se chystáš nakupovat, bezpodmínečně potřebuju znát dopředu", zatímco dynamicky typovaný jazyk nikoli.
Není nutné, uvádět úplně konkréntí informaci, tam kde ji nepotřebuješ vědět. S tím si typy poraděj.
Trošku bych to přeformuloval:
Statickej jazyk: "hele, čím víc mi řekneš podrobností předem, tím líp ti pomůžu".
Dynamickej jazyk: "hele, mě to nezajímá, cpi si tam co chceš, stejně si to budeš hlídat ty, já ti nepomůžu, ani mě nenapadne".
Statické typování mě nutí, abych dopředu znal nějaké omezení, nebo abych si ho uměle vytvořil, ačkoli z řešeného problému vůbec neplyne.
Nenutí, nemusíš vytvářet, pokud skutečně neplyne. Ale častokrát plyne. Statické typování dělá úplně jinou věc.
Nejčastějším problémem, se kterým se vývojář ve své pracovní době potýká, není obvykle přímo problém, který má za úkol vyřešit, ale jak se vypořádat s problémy, které si nadělal sám sobě dříve nebo které mu vymysleli jeho předchůdci. Takže jakmile se zákazník zeptá, proč nejde koupit Boeing, co mu na to odpovíš? A jak se budeš tvářit, až po X mandays práce, spočívající v překopávání půlky programu kvůli Boeingu, ti zákazník nezaplatí ani halíř, protože v té původní smlouvě o dílo není nikde napsáno, že by ten program neměl umět nakupovat Boeingy?
To zdaleka není specifické pro Statické typování. Ve skutečnosti je to tak, že:
- Ve statickém typování řešíš, jak problém popsat, a překladač ti fluše do tváře tvoje chyby.
- V dynamickém typování ti aplikace furt padá (ideálně na produkci), protože jsi nevychytal všechny chyby (nic ti nepomáhá).
V obou případech klient čeká.