Typový system versus unittesty

Kiwi

Re:Typový system versus unittesty
« Odpověď #465 kdy: 26. 06. 2018, 16:16:56 »
trochu offtopic, ale nemáte někdo nějakou teorii tohohle vehementního odmítání moderních technologií?
Co se týče mě, tak neodmítám, jen jsem si z toho nesedl na zadek, protože to žádná zázračná stříbrná kulka není. Nejspíš na to časem taky přijdeš, obvykle se tak děje když se člověk dostane od učebnicových příkladů k většímu projektu.


Kit

Re:Typový system versus unittesty
« Odpověď #466 kdy: 26. 06. 2018, 16:19:10 »
Ale tohle je diskuze nikoliv OOP vs FP, ale typy vs. unit testy (případně bez typů). Jinak moje praktická zkušnost myslím s "gson"em je ta, že mi to poctivě dávalo "null" do chybějících atributů (při generickém parsingu) a nebylo ochotné se to nechat přesvědčit jinak. Že by to samovolně zareagovalo na @NonNull, tak to už vůbec...

Jenže FP vs. OOP je ve své podstatě totéž jako typy vs. unit testy. OOP se obejde bez typů, FP se obejde bez testů. OOP bez testů je jak FP bez typů. Pro jednoduché úkoly to stačí, ale u složitějších je cítit jejich absence.

v

Re:Typový system versus unittesty
« Odpověď #467 kdy: 26. 06. 2018, 16:25:13 »
trochu offtopic, ale nemáte někdo nějakou teorii tohohle vehementního odmítání moderních technologií?
Co se týče mě, tak neodmítám, jen jsem si z toho nesedl na zadek, protože to žádná zázračná stříbrná kulka není. Nejspíš na to časem taky přijdeš, obvykle se tak děje když se člověk dostane od učebnicových příkladů k většímu projektu.
můžete uvést nějaký příklad menšího většího projektu? třeba ten typově bezpečný AST jsem úspěšně aplikoval na reálný programovací jazyk (IEC61131 STL), je to učebnicový příklad?

Re:Typový system versus unittesty
« Odpověď #468 kdy: 26. 06. 2018, 16:41:21 »
Citace: Filip Jirsák
Kdybych to psal v dynamickém jazyku, tak asi proto, abych typy nemusel řešit a poradilo si to s co největší škálou různých (i ne zcela správných) vstupů.
...
To by mě zajímalo, proč bys zrovna z těchto důvodů tohle psal v dynamickém jazyku....
Že je to dynamický jazyk přece bylo vaše zadání.
Nějak nerozumím vašemu logickému uvažování. Giving up.

Začalo to takhle:


Máš pravdu, když to píšu, tak to píšu bez přemýšlení... až na to, že tohle je kód, který je dost důsledně kontroluje, jestli ve zdrojových datech nechybí atributy, jestli to pole "delta" je fakt neprázdné, jestli tam někde nejsou nully.... a teď mi řekni, jak bys to psal v dynamickém jazyku a jak by vypadaly unit testy....

SB

Re:Typový system versus unittesty
« Odpověď #469 kdy: 26. 06. 2018, 16:43:39 »
Kód: [Vybrat]
data Obj {
    a :: Int
  , b :: Text
  , c :: [Int]
  , d :: NonEmpty Int -- neprazdne pole
  , e :: Maybe Double
  , f :: UTCTime
}
instance FromJSON Obj where
  parseJSON = withObject $ \o ->
     Obj <$> o .: "alpha" <*> o .: "beta" <*> o .: "cyril" <*> o .: "delta" <*> o .: "edward" <*> f .: "ftime"
...až na to, že tohle je kód, který je dost důsledně kontroluje, jestli ve zdrojových datech nechybí atributy, jestli to pole "delta" je fakt neprázdné, jestli tam někde nejsou nully.... a teď mi řekni, jak bys to psal v dynamickém jazyku a jak by vypadaly unit testy....

Tak především v OOP je (z podstaty) starostí objektu, aby si okontroloval, čím se plní, a naplnění i sám provedl (přestože to tak mnozí nedělají a omrdávají to jakýmisi dírami v implementaci, nebo anemickým modelem). Na to stačí metoda fromJson(json), fromDict(dict) atp. obsahující kontroly (klidně včetně rozsahů hodnot!) a jejich uložení. Jednotkovému testu stačí vyzkoušet, zda objekt pro daná data je možno vytvořit.
Ale tohle je diskuze nikoliv OOP vs FP, ale typy vs. unit testy (případně bez typů). Jinak moje praktická zkušnost myslím s "gson"em je ta, že mi to poctivě dávalo "null" do chybějících atributů (při generickém parsingu) a nebylo ochotné se to nechat přesvědčit jinak. Že by to samovolně zareagovalo na @NonNull, tak to už vůbec...

Tak to se omlouvám, ale viděl jsem tam Obj, tak jsem si myslel, že se jedná o OOP. Každopádně jako příklad v dynamickém (netypovém) OO jazyku a s jednotkovými testy to mám správně.


Re:Typový system versus unittesty
« Odpověď #470 kdy: 26. 06. 2018, 16:45:31 »
můžete uvést nějaký příklad menšího většího projektu? třeba ten typově bezpečný AST jsem úspěšně aplikoval na reálný programovací jazyk (IEC61131 STL), je to učebnicový příklad?
Co třeba taková kalkulačka? Jenom simulace té nejobyčejnější kalkulačky – zadávání čísel v desítkové soustavě, sčítání, odčítání, násobení a dělení. Žádné priority, žádné paměti, žádné další funkce. Můžete napsat, jaké byste tam použil typy, jak by vypadal kód – a zda byste tam měl nějaké testy, případně jaké?

Kit

Re:Typový system versus unittesty
« Odpověď #471 kdy: 26. 06. 2018, 17:04:39 »
Tak to se omlouvám, ale viděl jsem tam Obj, tak jsem si myslel, že se jedná o OOP. Každopádně jako příklad v dynamickém (netypovém) OO jazyku a s jednotkovými testy to mám správně.

Obj v daném příkladu není objekt, ale typ.

Re:Typový system versus unittesty
« Odpověď #472 kdy: 26. 06. 2018, 17:35:22 »
...v případě Typového systému máme 100% pokrytí z principu vždy...

Nikoho tu tato věta nevydráždila...?
Tak povídej :-)
Pokryti ceho a cim?

Měl jsem na mysli trivialitu v tom, že:
Kód: [Vybrat]
fn foo(Byte: x):
je ekvivalentní:

Kód: [Vybrat]
fn foo(x):

fn test_foo():
    foreach x in [0, 1, 2, 3, 4, 5 , 6, ... 255]:
        foo(x)

fn test_foo_fail_string():
    foreach x in ["a", "b", "c", ... "aa", "bb", ...]:
        exceptedException
        foo(x)

fn test_foo_fail_float():
    foreach x in [1.1, 1.2, 1.3, ...]:
        exceptedException
        foo(x)

a vlastně ten rozvoj je nekonečný...


Pokryti testy asi vetsina lidi chape jako (mnozstvi kodu spusteneho behem testovani)/(celkove mnozstvi kodu) a ne jako (mnozstvi testovanych vstupu)/(mnozstvi vsech moznych vstupu).

Nicmene tvuj priklad krasne ukazuje, ze pri pouziti vhodnych typu ztraci smysl vsechny negativni testy. A nejen smysl, ale vlastne ani nejdou napsat/spustit, protoze ta typovane verze funkce proste nejde zavolat s jinym typem argumentu.

A ted se pokusim odpovedet na otazku zivota vesmiru a vubec (a jelikoz nedelam v haskellu tak by to mohlo trknout i Filipa a Kita)

Funkce se da vyjadrit:
  • analyticky - o to se vetsina programatoru snazi
  • graficky - o to se vetsina programatoru nesnazi, ale mohlo by to byt zajimave
  • vyctem hodnot - o to se vlastne snazi BoneFlute, akorat se mu nechce psat vsechny tak "zneuziva" typovy system

A potom je to uz jasne ne? Kdyz mam uz v definici vstupu a vystupu zakodovano chovani funkce (protoze jsem zapis funkce vlastne nahradil lookup tabulkou) tak prece nepotrebuju zadne unit testy ktere overi vysledek pro nejake mizive promile tech moznych vstupu. To je prece jasna duplicita.

A jako bonus dokonce ani nepotrebuju psat telo funkce, protoze vsechno je uz v podpisu.

v

Re:Typový system versus unittesty
« Odpověď #473 kdy: 26. 06. 2018, 17:39:42 »
můžete uvést nějaký příklad menšího většího projektu? třeba ten typově bezpečný AST jsem úspěšně aplikoval na reálný programovací jazyk (IEC61131 STL), je to učebnicový příklad?
Co třeba taková kalkulačka? Jenom simulace té nejobyčejnější kalkulačky – zadávání čísel v desítkové soustavě, sčítání, odčítání, násobení a dělení. Žádné priority, žádné paměti, žádné další funkce. Můžete napsat, jaké byste tam použil typy, jak by vypadal kód – a zda byste tam měl nějaké testy, případně jaké?
nic neslibuju, ale můžu se o to pokusit, asi by bylo ideální abych se o to pokusil v tom jazyce, ve kterém jste si zkoušel dependent types, který že to byl?

Re:Typový system versus unittesty
« Odpověď #474 kdy: 26. 06. 2018, 18:47:15 »
nic neslibuju, ale můžu se o to pokusit, asi by bylo ideální abych se o to pokusil v tom jazyce, ve kterém jste si zkoušel dependent types, který že to byl?
Bavíme se tu přece teoreticky – nezaznamenal jsem, že by tu BoneFlute jásal, že konečně objevil ten správný jazyk. Takže jsem vám záměrně ponechal volnost, abyste použil jazyk, jaký chcete – předpokládal jsem, že pro to budete muset nadefinovat vlastní jazyk. Ale nemusíte ho definovat nijak podrobně, stačí popsat, jak budou vypadat ty typy a kód. Na konkrétní syntaxi přece nezáleží.

v

Re:Typový system versus unittesty
« Odpověď #475 kdy: 26. 06. 2018, 18:57:49 »
nic neslibuju, ale můžu se o to pokusit, asi by bylo ideální abych se o to pokusil v tom jazyce, ve kterém jste si zkoušel dependent types, který že to byl?
Bavíme se tu přece teoreticky – nezaznamenal jsem, že by tu BoneFlute jásal, že konečně objevil ten správný jazyk. Takže jsem vám záměrně ponechal volnost, abyste použil jazyk, jaký chcete – předpokládal jsem, že pro to budete muset nadefinovat vlastní jazyk. Ale nemusíte ho definovat nijak podrobně, stačí popsat, jak budou vypadat ty typy a kód. Na konkrétní syntaxi přece nezáleží.
http://augustss.blogspot.com/2009/06/more-llvm-recently-someone-asked-me-on.html

Re:Typový system versus unittesty
« Odpověď #476 kdy: 26. 06. 2018, 19:06:17 »
Nicmene tvuj priklad krasne ukazuje, ze pri pouziti vhodnych typu ztraci smysl vsechny negativni testy.
Což je ovšem dost slabé tvrzení oproti původnímu „nejsou potřeba žádné testy“.

A mimochodem ten BoneFluteův příklad je poněkud nekompletní, protože tam má jenom typ, ale žádnou funkci. Jednotkové testy se ale používají na právě na testování algoritmů. Kdyby se nezabýval jenom tím typem Byte, ale hlavně tou funkcí foo(), hned by měl co testovat.

Funkce se da vyjadrit:
  • analyticky - o to se vetsina programatoru snazi
  • graficky - o to se vetsina programatoru nesnazi, ale mohlo by to byt zajimave
  • vyctem hodnot - o to se vlastne snazi BoneFlute, akorat se mu nechce psat vsechny tak "zneuziva" typovy system

A potom je to uz jasne ne? Kdyz mam uz v definici vstupu a vystupu zakodovano chovani funkce (protoze jsem zapis funkce vlastne nahradil lookup tabulkou) tak prece nepotrebuju zadne unit testy ktere overi vysledek pro nejake mizive promile tech moznych vstupu. To je prece jasna duplicita.
Za prvé je z toho hned vidět, že definovat funkce výčtem hodnot je pro reálné programy v drtivé většině případů nepoužitelné. Až začnete psát o tom, že se to přece dá nějak redukovat a nevypisovat všechny hodnoty, ale nahradit to nějakým předpisem – pak právě přijdou na řadu ty testy, které porovnávají, jestli ten předpis pro některé zajímavé hodnoty dává opravdu tu hodnotu, která by měla být v tom výčtu.

Za druhé, pokud by vám nemožnost udělat úplný výčet připadala jako nějaké dočasné technické omezení, vzpomeňte si třeba na funkce rand() nebo na faktorizaci velkých čísel – kdybychom dokázali ty funkce definovat výčtem hodnot, přestaly by být zajímavé a nikdo by je nepoužíval.

Za třetí, pořád předpokládáte, že výkonný kód i test vzniká stejným způsobem a píše to ten samý programátor. Ve skutečnosti kdyby vám někdo dal funkci (i se zdrojákem) definovanou výčtem hodnot a tvrdil by vám, že ta funkce dělá X, první co byste udělal, že byste si v tom zdrojáku vyhledal pár hodnot a ověřil byste, že alespoň pro tyhle hodnoty opravdu dělá X.

Re:Typový system versus unittesty
« Odpověď #477 kdy: 26. 06. 2018, 19:13:05 »
nic neslibuju, ale můžu se o to pokusit, asi by bylo ideální abych se o to pokusil v tom jazyce, ve kterém jste si zkoušel dependent types, který že to byl?
Bavíme se tu přece teoreticky – nezaznamenal jsem, že by tu BoneFlute jásal, že konečně objevil ten správný jazyk. Takže jsem vám záměrně ponechal volnost, abyste použil jazyk, jaký chcete – předpokládal jsem, že pro to budete muset nadefinovat vlastní jazyk. Ale nemusíte ho definovat nijak podrobně, stačí popsat, jak budou vypadat ty typy a kód. Na konkrétní syntaxi přece nezáleží.
http://augustss.blogspot.com/2009/06/more-llvm-recently-someone-asked-me-on.html
Hezký, akorát že to není ta požadovaná kalkulačka, že. Všimněte si, že jeden z implicitních požadavků na program je to, že když dostane nějaký vstup mimo zadání, oznámí chybu. Decimální kalkulačka, do které zadám krf % brf a ona vypíše peklo, asi není úplně bezchybná, nemyslíte?

v

Re:Typový system versus unittesty
« Odpověď #478 kdy: 26. 06. 2018, 19:16:17 »
nic neslibuju, ale můžu se o to pokusit, asi by bylo ideální abych se o to pokusil v tom jazyce, ve kterém jste si zkoušel dependent types, který že to byl?
Bavíme se tu přece teoreticky – nezaznamenal jsem, že by tu BoneFlute jásal, že konečně objevil ten správný jazyk. Takže jsem vám záměrně ponechal volnost, abyste použil jazyk, jaký chcete – předpokládal jsem, že pro to budete muset nadefinovat vlastní jazyk. Ale nemusíte ho definovat nijak podrobně, stačí popsat, jak budou vypadat ty typy a kód. Na konkrétní syntaxi přece nezáleží.
http://augustss.blogspot.com/2009/06/more-llvm-recently-someone-asked-me-on.html
Hezký, akorát že to není ta požadovaná kalkulačka, že. Všimněte si, že jeden z implicitních požadavků na program je to, že když dostane nějaký vstup mimo zadání, oznámí chybu. Decimální kalkulačka, do které zadám krf % brf a ona vypíše peklo, asi není úplně bezchybná, nemyslíte?
požadovaná?? tak tohle je asi moje mez, jestli neukážete aspoň trochu snahy porozumět tématu, tak na vás asi nebudu reagovat

andy

Re:Typový system versus unittesty
« Odpověď #479 kdy: 26. 06. 2018, 19:40:06 »
můžete uvést nějaký příklad menšího většího projektu? třeba ten typově bezpečný AST jsem úspěšně aplikoval na reálný programovací jazyk (IEC61131 STL), je to učebnicový příklad?
Co třeba taková kalkulačka? Jenom simulace té nejobyčejnější kalkulačky – zadávání čísel v desítkové soustavě, sčítání, odčítání, násobení a dělení. Žádné priority, žádné paměti, žádné další funkce. Můžete napsat, jaké byste tam použil typy, jak by vypadal kód – a zda byste tam měl nějaké testy, případně jaké?

https://gist.github.com/ondrap/69fa2162bc2516469642e5380b379f5c (v reálu by tam byl zvlášť typ na operátor a Show instance pro jednodušší debugování, která se bohužel u toho ExprF nenageneruje sama)

Testy obvykle dělám na parsing, a pak asi nějaký test, že to nepočítá úplnou haluz (i.e. 100% code coverage, tady že jsem se neuklep v těch operátorech). Ono tam teda moc co testovat není....  jinak parser na "normální" výrazy není o moc delší, jen jsem línej to hledat... tam by se asi pak řešilo v testech, jestli se korektně respektuje priorita operátorů.

No, ale v podstatě je to to, co jsem psal - parsing typově moc obsáhnout nejde, vlastní výpočet má v podstatě 3 řádky a  není moc co tam splést.... aritmetika na Double je poměrně "totální", takže tam taky není moc co řešit...