Rozhovor s Guido van Rossumem, část 5.

Autor jazyka Python Guido van Rossum odpovídá na otázky Billa Vennera o historii Pythonu, o vlivu jazyka ABC na vývoj Pythonu a o hlavních cílech při vývoji Pythonu.

Originál rozhovoru je dostupný na http://www.artima.com/intv/guido.html .

Author:Jan Švec
Date:2005-10-05
Copyright:Copyright (C) 2004-2005 Jan Švec

Silně typové vs. slabě typové jazyky

Bill Venners: Jednou jsem se s Jamesem Goslingem bavil o produktivitě programátorů. Jeho odpověď, kterou považuji za názor zastánce silně typových jazyků, byla: "Existuje pověst říkající, že ve volně typových systémech se dají velice jednoduše vytvářet prototypy programů. To může být pravda, ale cesta od hotového prototypu ke skutečnému průmyslovému využití systému je ještě pěkně dlouhá."

Guido van Rossum: Ta "cesta" je také pověst, jak mohu ze své zkušenosti potvrdit. Cesta od prototypu k systému je popsána stejně málo, jako ona jednoduchost prototypování.

Bill Venners: Gosling také řekl: "Cokoli, co vám řekne o problému dříve, nedělá věci jen více spolehlivými díky zachycení mnoha chyb, ale čas, který ušetříte následným hledáním chyb, můžete využít zcela jiným způsobem."

Když jsem se zeptal Joshe Blocha na silně- a volně- typové jazyky, řekl: "Je vždy užitečné detekovat chyby programátora co nejdříve je to možné."

Guido van Rossum: Mimo jiné, s tímto nesouhlasím.

Bill Venners: Josh Bloch pokračoval: "Nezáleží na tom, že v prostředí, které s překladem udělalo krátký proces, můžete prototypovat rychleji ale myslím si, že výsledný program je méně robusní. Pokud chcete dostat robusnější program, mělo by se dělat co nejvíce statických typových kontrol."

To všechno mi připadá logické. Čím dříve v programu najdu chybu, tím lépe. Silné typování mi pomáhá hledat chyby již v okamžiku překladu. Volně typové jazyky mě nechávají čekat, dokud se neobjeví výjimka. Potíž je v tom, že používám Mailman a qmail. Oba jsou napsáni kompletně v Pythonu a pracují výborně. Nejsou to prototypy, jsou to aplikace a obě mi připadají docela robusní. Kde je tedy v mé úvaze chyba?

Guido van Rossum: Tento postoj je klasickou ukázkou zastánců silně typových jazyků. Jedna věc, která mě velmi trápí, je soustředění programátora na (silné) typy tak, aby jeho program byl správně a šel přeložit. Silné typování zachytí mnoho chyb, ale zároveň nutí programátora dávat pozor na to, aby všechny typy byly v pořádku, a ne na to, aby byl v pořádku program samotný.

Silné typování je jeden z důvodů, proč jazyky jako C++ nebo Java vyžadují mnohem více kódu. Všechny vaše proměnné musíte deklarovat a kolem toho se ještě mnoho nadřete jen aby byl překladač spokojen. Staré pořekadlo od Unixových vývojářů zní nějak takto: "Váš program bude v pořádku jen tehdy, až ho napíšete třikrát." Pak byste můžete být rádi, protože když program napíšete třikrát, bude to stačit ke správné funkci. Tak to ale není.

Veškerá pozornost věnovaná správnosti typů ještě nutně neznamená, že váš program je správně. Typ je malý kousek informace o vašich datech. Jestliže se podíváte na velké programy napsané v silně typovém jazyce, všimněte si, že mnoho času je stráveno právě obcházením typového systému.

Problém kontejnerů je jeden z těchto příkladů. V jazyce bez obecných typů je velmi obtížné napsat implementaci obecného kontejneru (tj. kontejneru, který není omezen na jeden konkrétní typ). A všechno silné typování vyhodíte z okna v okamžiku, kdy si řeknete: "Dobře, napíšeme pouze kontejner Objektů, a budeme je přetypovávat zpět na typ, který měly, než jsme je do kontejneru vložili." Díky těmto přetypováním toho jednak napíšete ještě více a ke všemu při používání kontejneru ztrácíte podporu typového systému.

Python po vás přetypování nevyžaduje a jeho kontejnery jsou kompletně obecné, což je obrovská výhoda těchto kontejnerů, ke všemu bez jakékoli protislužby, vše plně automaticky. Nejde o "klady", kterými nás klamou v C++ s jejich šablonami a dalšími obecnostmi, v praxi se ukazuje, že tyto mechanismy jsou velice nepohodlné. Každý vývojář překladače zjistil, jak obtížné je napsat šablony tak, aby fungovaly správně a efektivně, a každý programátor narazil na mnoho problémů, zatímco se je učil správně používat. Celé šablony jsou další nový, vysoce komplexní jazyk.

Běhové, nikoli volné typy

Guido van Rossum: Python, což je jedna z věcí, které mám na něm rád, dělá vše za běhu. Jeho syntaxe není ani zdaleka tak komplikovaná v porovnání s jazyky jako C++ nebo i Java, která je mnohonásobně jednodušší, než C++. I když, neplánoval Sun přidat obecné typy do Javy?

Bill Venners: Ano.

Guido van Rossum: Přesně, protože jde o silně typový jazyk a některé věci nelze přidat jiným způsobem.

"Volně typový" není správný popis Pythonu. Jde spíše o jazyk typovaný za běhu, poněvadž každý objekt je označen svým typem.

Bill Venners: Každý objekt v Pythonu má typ?

Guido van Rossum: Máme mnoho typů, například řetězec, integer, reálné číslo, slovník nebo cokoli jiného.

Bill Venners: Ale parametry metod a návratové hodnoty typ nemají.

Guido van Rossum: Tyto proměnné typy nemají. Runtime-typování pracuje poněkud odlišně. Velice snadno můžete metodě předat chybný argument a zjistíte to až ve chvíli, kdy je tato metoda zavolána. Ale pokud již k chybě dojde, interpretovaný jazyk vám přesně řekne co se stalo: "Toto je jeden typ, toto jiný typ a přesně zde k chybě došlo." Pokud se v typech spletete v C nebo C++, projeví se tato chyba až běhu programu. Většinou dojde k výpisu obsahu paměti a to je vše. Proto nemůžete jednoduše říci, že silně typové jazyky jsou lepší než jazyky slabě typové, porovnáváte totiž neporovnatelné.

Bill Venners: Nechte mne zrekapitulovat, co jste řekl. Jako programátor v silně typových jazycích si myslím, že vždy je lepší zjistit chyby dříve, než později. Vy souhlasíte, ale zároveň říkáte, že musím zvážit cenu takovéhoto mechanismu. Dále mohu svůj program spustit až po třech nebo čtyřech pokusech o překlad, protože jsem otravován překladačem, který ovšem nikdy nezaručí správnou funkci programu. O silně typových jazycích říkáte, že nás ničí a berou náš čas.

Gosling řekl, "Cokoli, co vám řekne o problému dříve, nedělá věci jen více spolehlivými díky zachycení mnoha chyb, ale čas, který ušetříte následným hledáním chyb, můžete využít zcela jiným způsobem." Vy přidáváte: "... pokud zrovna neděláte překladač spokojeným s typy vašich proměnných."

Guido van Rossum: Opravdu máte čas dělat něco jiného. Jelikož program v Pythonu je kratší, můžete třeba důkladněji testovat, důkladněji, než pokud píšete velké programy v Javě nebo C.

V Pythonu také můžete snadno psát krátké úryvky kódu a okamžitě si ověřovat, jak pracují. Můžete provádět velmi důkladné testování jednotek. Lze použít i programování způsobem zdola vzhůru. Můžete začít s velmi vágním nápadem, začít ho implementovat, a ověřovat si jeho funkci. Mnoho věcí kolem přitom můžete stále měnit. V silně typových jazycích se však takové změny dělají podstatně hůře.

Pokud v silně typových jazycích přejdete k jiné datové struktuře, musíte změnit typy argumentů a návratových hodnot v mnoha metodách, které tuto strukturu používají. Nebo může chtít změnit počet argumentů, protože najednou předáváte vstupní informaci jako dvě nebo tři části narozdíl od jediné. Pokud v Pythonu změníte typ něčeho, nemusíte vůbec měnit ten kód (kterého je většina), který tuto strukturu přímo nepoužívá.

Význam testování modulů

Billa Venners: Jaká je vaše představa o testování jednotek? Jakou roli hraje testování při zachování robusnosti systému?

Guido van Rossum: Jsem za důkladné testování modulů, obzvláště, jste-li v raných fázích vývoje vaší aplikace a speciálně pokud píšete aplikaci postupem zdola vzhůru, jako knihovnu komponent, které následně použijí vyšší vrstvy vaší aplikace.

Pokud se chcete vyvarovat mnoha chybám, které jsou jinak velmi těžko laditelné, testujte každou funkci se všemi přípustnými argumenty. Pokud máte dlouhý program, který nepracuje díky nějaké chybě, trvá většinou hodně dlouho, než najdete chybující funkci. Tato funkce například vrací chybný výsledek, který je předán dále a použit v jiném mezivýpočtu, který se vyhodnotí s úplně jiným výsledkem a o 17 kroků dále má vaše proměnná najednou záporné znaménko, které jste nikdy nepředpokládali. Zpětné vystopování chyby může být opravdu těžké.

Testujete-li moduly správně, prověřujete každou funkci individuálně. A pokud to provádíte důkladně, za použití eXtrémního programování, píšete testy a implementaci vaší funkce zároveň.

Vždy doporučuji jak testování černé skříňky, tak i bílé skříňky. Test černé skříňky je napsán pouze pro rozhraní, zatímco test bílé skříňky již využívá znalosti o implementaci funkce. Pokud víte o nějakém triku při implementaci, vytvořte test pro všechny možné případy. Pokud provádíte jednu činnost pro krátké vstupy a jinou pro vstupy delší než 512 bytů, doporučuji napsat test několika malých hodnot a pak hodnot délky 510, 511, 512, 513 a 514 bytů. Ujistěte se, zda výsledky pro všechny tyto hodnoty odpovídají a zda vše pracuje jak má i v okamžiku přechodu z jednoho algoritmu na jiný.

Interaktivní testování Javy s Jythonem

Bill Venners: K čemu je dobrý Jython?

Guido van Rossum: Jython najde využití v interaktivním testování programů. I v čistém Java prostředí můžete použít Jython k interaktivnímu testování vašich Java tříd. Je dobré umět si napsat napsat testy k modulům, ale někdy budete chtít se ve vašem systému pouze zorientovat. Můžete pak třeba importovat třídu a podívat se, co se stane, pokud zavoláte určitou metodu s konkrétním parametrem. Možná ještě ani nejste ve fázi testování, pokoušíte se zjistit, které věci vám fungují a které ne.

S Jythonem pouze spustíte interaktivní intepretr Pythonu, přímo importujete Java třídu, vytvoříte její instanci a začnete testovat. Můžete vidět výsledky rovnou, aniž byste napsali jakýkoli program, zkompilovali ho, sestavili a spustili. Pokud se chcete přesvědčit, co se vytiskne pro 5 namísto 4, jednoduše to napíšete na dalším řádku interpretru. Pokud chcete vidět výsledky pro vstupní hodnoty 1 až 10, můžete vytvořit pouhou smyčku for kolem volání metody v Javě. Jak vidíte, přináší tento systém mnoho výhod.

Testování rozsáhlých systémů

Frank Sommers: Jakým způsobem testujete rozsáhlé Pythonovské systémy?

Guido van Rossum: Jednou z věcí, kterou já a můj tým děláme velmi často, je psaní malých testovacích programů spolupracujících s daným systémem. V těchto testech využíváme specifikaci funkce, tj. specifikace vstupních a výstupních parametrů. Vy můžete zadat testovací případy k ověření, zda funkce opravdu pracuje správně. Ale pokud chcete otestovat velký systém, často se improvizuje.

To, jak testovat větší systémy je mnohem méně známo, protože jednoduše nemůžete otestovat všechny možné vstupy nebo stavy systému. V Pythonu můžete snadno napsat malé i větší programy, které vám pomohou připravit testovací vstupy nebo data ověřovat si výstup systému.

Testování programů v Pythonu je obzvláště jednoduché díky tzv. introspekci. Můžete jednoduše zkontrolovat výstup z metody, stejně jednoduše lze nahradit jednu třídu jinou, která bude např. zahrnovat testovací nástroje. V Pythonu můžete napsat i obecné třídy, které budou pracovat jako proxy pro jiné objekty, aniž by znaly jejich rozhraní. Proxy třída je velmi obecná a pokud změníte třídu na níž proxy ukazuje, většinou nemusíte proxy třídu dále upravovat. Proxy pouze předá dále cokoli, co dostane a přitom zaznamenává volání metod a někdy může provádět ještě jiné, důležitější věci.

Silné a slabé osobnosti

Bill Venners: Co rozhoduje o volbě silně nebo slabě typového jazyka pro implementaci daného systému? Potkal jsem mnoho lidi, kteří byli zastánci slabě typových jazyků. Znám mnoho lidí, kteří měli rádi například Smalltalk. Ti považují dny, kdy v něm pracovali, za nejlepší dny svého života. Tito lidé pociťují chybová hlášení překladače jako brzdu jejich práce. Oproti tomu jsem poznal i mnoho lidí, kteří byli rádi za tyto výpisy. Ti v překladači viděli přítele jenž jim pomáhá přijít na chyby dříve než ovlivní jejich program. Do jaké míry je výběr správného nástroje problémem uspokojení programátorových nálad a choutek jednotlivých vývojářů?

Guido van Rossum: To je opravdu záležitost každé osobnosti. Je zajímavé, že jste zmínil Smalltalk. Mnoho ex-Smalltalkistů považuje Python za východisko z problémů s Java kódem. Mnoho z nich považuje Python za dobrou alternativu, která má mnohem blíže k tomu, co mají rádi, ke Smalltalku. Mimoto volbu správného nástroje pro vývoj aplikací ovlivňuje i cílové určení programu. Napsání software pro raketoplán je něco úplně jiného než napsání software pro telefonní ústřednu. Ale vaše teorie osobnosti je určitě správná.

Létáme s Pythonem

Bill Venners: Mluvíme-li o raketoplánu, věřil byste řídícímu software v letadlech, kdyby byl napsán v Pythonu?

Guido van Rossum: To záleží spíše na zručnosti vývojářů, kteří by na tomto software pracovali, než na zručnosti týmu programátorů Pythonu. Jsou situaci, kdy Python obstojí lépe než klasické silně typové jazyky, zvláště pokud je potřeba spolehlivost raketoplánu nebo kontroly letového provozu.

Bill Venners: Proč?

Guido van Rossum: Nikdy nepřijdete na všechny chyby programu. Jednodušší čtení a psaní kódu a větší průhlednost pro čtenáře, může být mnohem hodnotnější než úzké zaměření na kontrolu typů, které nabízí mnohé překladače. Jsou známy anekdoty o kosmických lodích nebo letadlech, které spadly díky chybě při přetypování před kterými vás překladač nedokáže ochránit.

Obsah