kvalitní statická analýza - nástroj versus typy rubrika: Programování: Jiné

17 Taco
položil/-a 14.4. 12:40
 
upravil/-a 16.4. 12:00

V sousední otázce řekl @Tomáš Tintěra "kvalitní statická analýza. (Ne typová kontrola, ale samostatný nástroj)".

Zajímalo by mě, dokážete si představit některé oblasti statické analýzy, které by typový systém nedokázal ošetřit? Pusťte si prosím fantazii na špacír. Třeba ošetřit meze polí lze pomocí Dependenci Types.

Nebavíme se o tom, že to ten který jazyk neumí. Ale spíš tak nějak z principu.

Děkuji.

[Edit] Chytil jsem se toho opakovaně omílaného tvrzení, že: "Toto sebelepší typová kontrola neodhalí a je potřeba analyzator". Samozřejmě typy jsou na něco jiného, ale stejně mi to zní jako blbost.

Komentáře

  • harrison314 : Ja mam dve doplnujuce otazky: Ktory jazyk ma podla teba dostatocny typovy system? Ratas do typoveho systemu aj napriklad Haskelovske vynutenie velkosti zaciatocnych pismen (funkcie malym, typy velkym)? 14.4. 18:22
  • Taco : @harrison314: Žádný nebude dostatečný. Ale velice slušný má Scala, Haskell, Rust. To bych považoval za takové minimum, o čem se dá bavit. ••• Spíše asi ne, protože ta velikost písmen je IMHO spíše otázka syntaxe. 14.4. 21:01
  • harrison314 : Vsteky funkcionalne - je ti jasne, ze FP kladie ine poziadavky na typy ako OOP? 14.4. 21:57
  • Taco : @harrison314: to si nemyslím a to si nemyslím. 15.4. 11:40
  • Kit : @Taco: Uvědom si, že OOP typy (tím méně statické) prakticky nepotřebuje. 15.4. 14:04
  • Taco : @Kit: To si nemyslím. 15.4. 18:52
odkaz
13 rmaslo
odpověděl/-a 14.4. 16:45

Takže úkolem je najít něco co typy (ani ve své nejobecnější definici) nedovedou a statická kontrola by mohla.
To by podle mne mohla být třeba nějaká služba, která vrací do aplikace nějaké objekty, které jsou různého typu, dle vstupních parametrů té služby. Protože to, jaké konkrétní objekty (třeba pro nějakou množinu vstupních hodnot) budou vráceny si v statické analýze mohu zjistit, kdežto na typy je to fakt složité.

Konkrétně zkusme třeba toto: Dejme tomu, že mám nějakou tabulku překladů. V této tabulce mám nějaký code (což je to co se má přeložit) a nějaké lang_cz, lang_en, atd... a nakonec mám sloupec escaped (boolean), který mí říká zda tento záznam v té tabulce je "HTMl" nebo "TXT". Tato služba bude schována někde za funkci Trans(), která podle toho vrací různý typ.

V této tabulce mějme třeba takovéto záznamy:

code         lang_cz             escaped
den_pracovni <B>Pracovní</B> den 1
den_volny    <B>Volný</B> den    1
den_0        Neděle              0
den_1        Pondělí             0
....

Dále mějme nějaké funkce
Out - něco jako echo akorát, že si to kontroluje, že vstupem je (objekt typu) html_string
HtmlEscape - něco jako htmlspecialchars akorát, že si to kontroluje, že vstupem je (objekt typu) txt_string a výstupem je vždy (objekt typu) html_string
Date - stejné jako v PHP
& - oprátor string concat

A nyní napišme kód, něco jako

Out(HtmlEscape(Trans('den_' & date('w')))); //Spravne
Out(HtmlEscape(Trans('den_pracovni'))); //Chybne
Out(Trans('den_' & date('w'))); //Chybne
...

a chceme, aby nás něco upozornilo na chyby na řádku 2 a 3.

Dynamicky to není problém, na řádku 2. se udělá Trans('den_pracovni'), ten vrátí html_string a HtmlEscape zařve, že toto již html je. Na řádku 3. se udělá Trans, ten vrátí txt_string a Out zařve, že tohle vypisovat nebude.

Statická analýza - na řádku 2. zjistí, že vstupem Trans je 'den_pracovni' ze služby si zjistí, že to už je html_string a protože ví že vstupem HtmlEscape má být txt_string tak zařve.
Statická analýza - na řádku 3. by musela zjistit, že výstupem date('w') je 0-6 a zkontrolovat, že mezi den_0 až den_6 je aspoň jeden txt_string a pak zařvat, že to nejde. To by musel být fakt velmi propracovaný nástroj, aby něco takového zjistil.

Přes typy si moc nedovedu ani odhalit chybu na řádku 2. natož na řádku 3.

PS: Služba ve funkci Trans funguje tak jak funguje, můžeš namítat, že je naprosto blbě navržená (je), ale představ si, že to není překlad, ale třeba nějaká služba poskytovaná státem jako ARES atd... a že se bez ní neobejdeš.

Komentáře

  • Kit : Řešením by mohla být přetížená funkce HtmlEscape() nebo přímo Out(), která by sežrala cokoli a vyplivla správně escapovaný string. Statická analýza v takovém případě nebude potřebná a vždy to bude správně. 14.4. 17:04
  • rmaslo : @Kit: Jj, pro tento konkrétní problém dobré řešení. Teď, abych pro @Taco hledal nějaký jiný příklad, kde to takto obejít nejde :-). 14.4. 18:05
  • Taco : @rmaslo: Obvykle se takové scénáře řeší (pokud jsem tě dobře pochopil) buď tím, že to nevrací HtmlString či TxtString, ale typ AnyString, jenž má ... prostě něco jako rozhraní. A ty seš přinucen tam dát switch, kterým rozhodneš, co se zpracuje. Podobně funguje typ Maybe. Pointa je v tom, že tě to upozorní na to, že si nezpracoval nějaký scénář. (Toto se použije v nederministických případech jako je ten ARES etc.) ••• Případě se na to dají použít už zmiňované závislostní typy, které fungují tak, že návratová hodnota funkce je svázána s hodnotou vstupu. Takže typový systém si je schopen odvodit, že tato kompozice funkcí je v pořádku (či není). 14.4. 21:11
  • rmaslo : @Taco: K tomu AnyString - to že nějaký scénář není (není položka switch) to ale zjistí až dynamicky, ne? 14.4. 21:30
  • Kit : @Taco: K čemu switch, když máš stráže? 14.4. 22:00
  • Kit : @rmaslo: Ne, to se zjistí už při kompilaci. 14.4. 22:01
  • Taco : @rmaslo: při kompilaci to zjisti, je tam třeba ten Switch, a přinutí tě ho tam dat. Kterou cestou pak ty data potečou pak záleží na těch datech a to už je runtime. Což ale nevadi, páč chyba díky předchozímu nastat nemůže. 15.4. 10:36
  • Taco : @rmaslo: pro demonstraci se můžeme podívat do jazyka D. Tam když děláš switch nad položkami enum,, tak tam musíš vyjmenovat všechny hodnoty, jinak to prostě nepreloží. (Jinak ten jazyk žádný zázrak. Ale tohle mě potěšilo. ) 15.4. 10:41

Pro zobrazení všech 8 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.