Zobrazují se příspěvky se štítkemprogramování. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemprogramování. Zobrazit všechny příspěvky

sobota, ledna 12, 2008

Wow!

Vida. Myslel jsem si, jak si pěkně budu hovět v laskavé náruči .NET, a místo toho jsem spadl přímo do Win32. Však víte: to je ten svět, kde ty důležité věci jsou psány velkými písmeny, každá funkce má alespoň jednu Ex (a možná i ExEx) verzi a základem je pamatovat si, že když něco chcete, musíte pěkně poprosit funkcí SendMessage.

Popravdě musím říct, že až teď jsem si uvědomil, jak jsou Windows obrovské, co všechno v nich je a jak je zatraceně těžké v nich programovat.

Win32 API je vlastně úžasný artefakt závratné historické hodnoty, který umožňuje sledovat jak se osobní počítače vyvíjely posledních dvacet let. V dobách, kdy výkonné počítače měly 2MB paměti a jejich procesor běžel s taktem 20MHz, jistě bylo rozumné snažit se nacpat co nejvíce informací do co nejméně bytů paměti, a co nejvíce věcí řešit co nejmenším množstvím kódu. V té samé době, když ještě neexistovalo C++ (současná podoba byla standardizována až v roce 1998), bylo zcela určitě novátorským přístupem implementovat ten jediný prvek uživatelského rozhraní kterým Windows disponují (ano, správně, je to okno, hned ten název -- Windows -- dává takový pěkný dvojsmysl, že?) tak, že umožňuje tzv. subclassing, tedy možnost podstrčit systému ke správě takového okna správně napsanou funkci, ve které můžete z pitomého obdélníku udělat cokoliv, od tlačítka, přes textové pole až po... no, třeba ribbon, kdybyste o to stáli. A ačkoliv si to nebudete myslet, i ty registry, nad kterými každý ohrnuje nos, jsou poměrně slušně navržené (horší je to samozřejmě s implementací -- skoro bych se vsadil, že registry vymyslel ten tým, co dělal Windows NT, a pro Windows 95, blahé paměti, vyšla jejich nedomrlá verze, která brala ohled na to, že uživatelé nechtějí věnovat 70% výkonu svého počítače robustnímu úložišti konfigurace).

Bizarní na tom je, že tenhle místy prazvláštní slepenec funkcí (z nichž některé spojují podobné vstupní parametry a podobné výstupní hodnoty) pohání všechny Windows (tedy od verze 3.1, nebo kolik), včetně těch úplně posledních.

Znamená to dvě věci. Za prvé: skoro všechno co napíšete ve Win32 pro jedny Windows, poběží i na všech ostatních. A za druhé: Microsoft ve Windows nemůže nic změnit.

Myslím to takhle: Když píšete program, a rozhodnete se, že mezi dvěma verzemi něco změníte nebo opravíte, čímž se chování vašeho programu v 1% případů mírně změní, je to pro vaše uživatele jistě nepříjemné, ale, zatraceně, je to jedno mizerné procento a opravili jste chybu, kdo by si s tím lámal hlavu? Ovšem pokud jste Microsoft, a jedno procento uživatelů je, řekněme, 10 miliónů lidí, pak už takhle uvažovat nemůžete. Říkáte si: K čertu, náklady na opravu všeho softwaru, který je na téhle chybě závislý se zhruba vyrovnají nákladům na stavbu jedné či dvou letadlových lodí, nebo na stavbu základny na Měsíci, nebo tak něco. A nikdo nezaručí, že software, na kterém je třeba to jedno procento lidí existenčně závislých, někdo opraví. Co pak budete dělat s těmi 10 miliony telefonátů na servisní linku?

Podívejte se na Visty: Microsoft se v nich pokusil opravit hodně chyb, které mu byly dlouho vyčítány. Od přístupu co není zakázáno, je povoleno (tedy: uživatelé přeci nejsou banda tupých hovad), přešel k co není povoleno je zakázáno (tedy: dobře, když se chováte jako banda tupých hovad, ztížíme vám provádění těch největších pitomostí), protože léta uživatelé fňukali nad mizernou bezpečností Windows a tak dále. Odměnou mu za to je nepřetržitý proud neinformovaného plácání o tom, jak Visty jsou jen nové UI (jistě, navíc zkopírované z počítačů Apple), jak najednou nefunguje spousta software a hardware, kolik Visty čeho žerou a čím vším pořád točí a že Windows XP jsou stejně lepší, a kdo ví co ještě.

Dobrá, při uvedení Windows XP také všichni blekotali o tom, že v nich není nic nového než kulatá okna a tak dále a tak podobně, a stejně jako při přechodu z Windows 2000 na Windows XP tahle nesnesitelná litanie nejpozději koncem tohoto roku ustane.

Je tu ale přeci rozdíl: změna mezi Vistami a XP je opravdu podstatná, a ovlivní poměrně mnoho uživatelů (třeba celá ta věc s UAC -- v okamžiku, kdy na XP máte hotovou aplikaci, musíte ve Vistách začít řešit všechny tyhle manifesty, a Windows Defendery, a blokovače Bůh ví čeho). Spousta programů, které spoléhaly na to, že to či ono, je tam či onde, najednou nefunguje, protože tady a támhle, byly zalepeny ty či ony bezpečností díry, nebo se věči, o kterých Microsoft nikdy neřekl, že budou tam kde jsou i v budoucnu, přesunuly jinam, a najednou informace, která se ve Windows 2000 nebo XP dala vyčíst jedním dobře mířeným přístupem do registrů musí dohledávat přes API (což se ostatně měla už i ve Win2000, jen to nikdo nedělal, protože to bylo moc práce, a registry jsou přeci naše, že ano!).

Čímž se oklikou dostávám k tomu, co jsem asi tak zhruba chtěl říct: ve Win32 se neprogramuje moc dobře. Ne proto, že by API bylo nějak extrémně špatně navržené. Ve skutečnosti je docela slušné a v rámci jednotlivých domén i poměrně konzistentní, když uvážíme, že se z počítačů s výkonem, který dnes má každá lepší kalkulačka dokázalo úspěšně přesunout na stroje s kdo ví kolika jádry a gigantickým (z pohledu počátku 90. let) množstvím paměti všeho druhu. (Vsuvka: Zrovna tento týden jsem poslouchal nějaký podcast, kde se řešilo, proč Windows nemohou pracovat na více než 64 procesorech. Je to proto, že maska, která určuje, na kterých procesorech -- nebo jádrech procesoru -- může program běžet, má jen 64 bitů. Dovedu si představit, jak někdo v roce 1992 uvažuje, zda takovou masku implementovat obecně, jako nějaký druh seznamu, nebo malinko špinavým trikem, jako jednu dlouho proměnnou. A je mi jasné proč, při tehdejší úrovni počítačů, zvolil malinko špinavý trik.) Problém programování ve Windows je v tom, že ve Windows je toho tolik.

Na tomto místě je obvyklé říct (a ano, i já to s oblibou říkám), že tyhle obří operační systémy jsou nesmysl, a že z nich stejně většina lidí využije jen malou část. Ovšem otázka je, kterou malou část většina lidí využije, když je jich třeba miliarda? Čeho vlastně má mít takový správný malý operační systém vestavěnou podporu? Sítě? Grafická akcelerace? Asi tak sto tisíc různých druhů nejexotičtějších periferií, bez kterých právě těch bezvýznamných 10 miliónů lidí nemůže být? Co byste z Windows vyhodili, aby to nikomu nechybělo? Nebo aby to chybělo méně než milionu lidí? Co když někdo rozhodne, a z další verze vypadne zrovna to, co potřebujete vy?

Na druhou stranu: Windows API má dneska kolem 14000 funkcí. I když dokumentace, kterou Microsoft k API poskytuje je (ve srovnání s jinými API) na dobré úrovni, je to, zatraceně, 14000 funkcí. Kdo se tohle může naučit? Kdo může mít alespoň základní přehled o tom, jak co správně udělat v kterékoliv oblasti, kterou to API pokrývá? Dobrá, dneska zadáte dotaz do Googlu, klik-klik, a o hodinu hledání dál máte zhruba dvě až tři diskusní fóra, ze kterých poskládáte jak udělat to co potřebujete udělat. Ale kdo z programátorů, po kterých šlape jejich šéf, že už to, sakra, mělo být dávno hotové, si vybere hodinu hledat, dvě hodiny studovat, a další hodinu programovat (správně), když může zmáčknout Win+R, napsat regedit, Ctrl+F, klepy-klepy-klep, hmmm, takže HKEY_LOCAL_MACHINE lomeno System lomeno... no vida, a už je to tady!? Samozřejmě kromě vás?

Proto není divu, že pro Windows vznikají -- ehm, jak to říct -- zprasené aplikace. I já sám jsem jistě spoustu věcí udělal nesprávně. A to ne proto, že bych je nechtěl udělat správně. Prostě nevím, jak to správně vypadá. Původně jsem si myslel, že by mi třeba pomohlo nějaké školení nebo knížka. Ale jak chcete udělat školení nebo knížku na 14000 funkcí? Mám Petzolda, který je jistě dobrý jako úplný základ, ale problém s aplikacemi je v tom, že mají řešit nějaký problém, a řešení takového problému se většinou skládá ze spousty ne zcela souvisejících pod-problémů. Jak se na tohle připravit? Jak máte vědět, co budete dělat příště (pokud tedy pracujete na více malých a krátkých projektech a ne na jednom velkém a dlouhém)? Myslím si, že jediné opravdu smysluplné řešení je průzkum bojem, kdy vám někdo zkušenější ukáže, co a jak. Ovšem kde pořád brát ty zkušenější lidi, to netuším.

Tenhle problém, myslím tu objemnost a horizontální rozplizlost, měl asi vyřešit .NET, a částečně se mu to i podařilo. Ovšem s každou další verzí .NET, přibývá jmenných prostorů a tříd a metod a jazykových konstrukcí .NET jazyků takovým tempem, že po pěti letech jsme se dostali skoro do stejné situace, v jaké jsme byli předtím: Vím jistě, že na tohle bude v .NET nějaká třída. Ale kde, proboha? A tak si programátoři znovu a znovu píší jednoduchá řešení složitých problémů, které už dávno někdo robustně vyřešil, jen o tom nikdo neví.

V každém případě: Windows je jeden z nejúžasnějších inženýrských projektů na světě. Ať už je to s jejich použitelností v jednotlivých verzích jak chce, tohle se jim upřít nedá. Při rozsahu, který mají, je vůbec div, že je ještě Microsoft dokáže udržovat, a občas dokonce i dál vyvíjet.

Představuji si, jak za milión let archeologové vyhrabou někde v místech, kde je dneska Seattle, server se zdrojovými kódy Windows, a vystaví je v muzeu, a děti se na to budou muset chodit dívat, a paní učitelky budou říkat Tady děti vidíte, kolik úsilí lidé dokázali vyvinout, když šlo o předměty sloužící nějakým tajemným divošským rituálům, a děti budou znuděně lepit na vitrínu žvýkačky a těšit se, až se na ty lidi půjdou podívat do zoo, a budou po nich házet kamínky a dělat na ně obličeje.

Děti už jsou prostě takové.

pátek, prosince 07, 2007

Not so Test Driven...

Tuhle jsem tu psal o tom, jak mě BVer uvrtal do unit testování, a věcí okolo. Dokonce jsem na sobě zkoušel praktikovat i Test Driven Development, a nějak bych rád shrnul, co jsem zjistil.

Především chci říct, že když jsem báječný svět unit-testů objevil, říkal jsem si, jak jsem asi tak tisíc let za opicemi, a že tohle přeci musí používat každý člověk s trochou sebeúcty. Myšlenka testovat kód po malých částech ještě před tím, než zapomenete co má přesně dělat, nebo dokonce zjistit co a jak má dělat tím, že napíšete testy je tak skvělá a samozřejmá, že jsem byl zklamán, že mě nenapadla samotného.

Jaké bylo moje rozčarování, když jsem zjistil, že testování na úrovní nějakých malých komponent není vůbec samozřejmé, a že dokonce velká část lidí, kteří se živí programováním se k němu staví negativně, nebo dokonce odmítavě, a celkově v něm nevidí žádný užitek. Zkoušel jsem několika lidem několikrát opatrně vysvětlit, že čím dřív na chybu přijdou, tím dřív a rychleji ji odstraní, a i když unit testování není samospasitelné, že je to skvělá věc, a že by se jí měli věnovat.

Dokonce jsem i byl skoro úspěšný, když jsem jednoho (teď už bývalého kolegu) přesvědčil, aby si pár testů napsal. Čekal jsem, jak za mnou přiběhne s velkou krabicí belgických bonbónů, bude mi děkovně třást rukama a radostně poskakovat a povykovat, o kolik rychleji teď programuje a jak se kvalita jeho práce zvýšila a tak dále a tak podobně. Místo toho asi po třiceti minutách přišel s velmi správnou otázkou: "No a co mám jako dělat s tou databází?" I neváhal jsem, a začal ho zasvěcovat do tajů mock objektů, které okopírují rozhraní takové databáze, ale nebudou ve skutečnosti dělat nic jiného, než že na předem připravené otázky dají předem připravené odpovědi, načež zkontrolují, zda se jeho kód chová správně, a jeho kód zjistí jestli umí správně reagovat na divné stavy, do kterých se taková databáze může dostat. Čím déle jsem hovořil, tím víc zíval, až nakonec odešel, a o testování jsem od té doby spolu nemluvili.

Nerozuměl jsem tomu, protože napsat si mock-objekt na sériový port (ten z .NET) pro mě bylo opravdu zábavné, i když mi to, pravda, nějakou tu hodinku trvalo, a fakt, že jsem pak mohl pěkně ozkoušet co udělá celé komunikační rozhraní, které jsem tehdy psal, když místo očekávané zprávy přijde nějaká úplně jiná, mi pomohlo zkrátit ladění na pár desítek minut. Ještě méně jsem rozuměl odporu některých lidí, kteří se zabývají vývojem embedded aplikací, zvlášť když neměli k dispozici pořádný debugger.

Samozřejmě, že testování není zadarmo. Psát testy je někdy vážně nuda (třeba set/get metody s trochou logiky), někdy je to vyloženě masochismus (jednou jsem zkoušel, kolik úsilí by mě stálo dosáhnout 100% pokrytí kódu testy a vážně to nestálo za to, protože některé obzvláště vypečené chybové stavy je těžké vyvolat bez toho, abyste neomockovali půl operačního systému), nicméně celkově se rozumná míra testování vyplatí.

Projekt na kterém teď pracuji je poměrně agresivně naplánován, a popravdě, když jsem padesát minut psal mock na třídu zapisující do registrů, říkal jsem si, jestli to stojí za to. Nakonec se ukázalo že ano, protože jsem pak asi za deset minut odladil kód, který ten zapisovač používal, přičemž jsem odhalil asi pět velmi vypečených chyb, které by mě jinak stály spoustu ladění (určitě nejméně padesát minut, protože než bych na ně přišel, dávno bych zapomněl co jsem vlastně původně chtěl, aby kód dělal).

Rovněž jsem nabyl nezvratného přesvědčení, že i když TDD není pro mě (prostě nedokážu psát testy nasucho dopředu -- potřebuji alespoň nějaký kód, který pak třeba celý přepíšu, ale který mi dá vizuální představu jak bude celá věc fungovat a interagovat s okolím), jeho alespoň podvědomé používání vede k psaní lepších programů, které jsou lépe rozparcelovány, méně navzájem provázány, snáze udržovatelné, jednodušeji rozšiřitelné a tak dále. Myslím tím takové ty věci jako předávání objektů konstruktory, vyhazovaní výjimek, rozumné použití dědičnosti, využívání interfaců (interface nebo čistě abstraktní třída je grunt -- bez interfaců nikdy nemůžete vyměnit jeden objekt za druhý, resp. skutečný za mock) a podobné věci.

Chtěl jsem říct asi toto: jsem daleko od nejlepšího žáka Martina Fowlera, ale i když mám někdy pocit, že bych se měl na testování vykašlat, a raději smolit produkční kód, za který si zákazníci platí, vždycky se nakonec ukáže, že kdo testuje, ten vyhraje. A proto (spolu s klasikem) volám: Lidé, testujte!

pátek, srpna 31, 2007

Plus C++

Nedávno jsem teď četl tenhle text Bjarne Stroustrupa: Evolving a language in and for the real world: C++ 1991-2006. Ach, pro neznalé: Stroustrup je ten člověk, který rozšířil jazyk C o třídy a všechny ty další objektově orientované vymyšlenosti a další doplňky jako jsou šablony a tak dále. Tím způsobil malou revoluci v programování, protože z objektově orientovaných jazyků, které do té doby byly převážně záležitostí akademického světa (Smalltalk, Eiffel a další, které to nikam nedotáhly), udělal něco, co mohly vzít ty hordy zkormoucených programátorů v C a zanést díky tomu do svých programů o dva řády více složitosti (samozřejmě, že časem se i programátoři v C naučili co to vlastně znamená ten objektově orientovaný přístup, ale i tak: znám některé lidi, kteří nikdy v C++ nenapsali jinou než statickou metodu a atribut.)

Nuže, v tom textu Stroustrup shrnuje jak se vyvíjel jazyk C++, co byly jeho hlavní cíle při jeho návrhu, jak se zformovala standardizační skupina ISO, kdo přišel z nechutným bastardem Embedded C++, jak je těžké se na něčem dohodnout, že STL neznamená Standard Template Library, protože Stepanov na STL pracoval dávno před tím, než v C++ existovala věc, které se říká template (neboli šablona; v tomto směru doporučuji rozhovor s Alexem Stepanovem Al Stevens Interviews Alex Stepanov) a tak dále a tak podobně.

Je to vážně moc zajímavé čtení a pokud programujete (jedno v jakém jazyce), rozhodně si ten text přečtěte, abyste příště, až budete mít chuť pomlouvat C++ nevypadali jako... no, jako někdo, kdo o něm nic neví.

Takže: chtěl jsem říct, že jsem pod dojmem tohoto textu tak trochu přemýšlel o C++. Jako ostatně každý soudný člověk, mám z C++ strach. C++ je krutý a syrový jazyk, který neodpouští chyby, a kdo není obdařen železnou disciplínou, která mu zabrání dělat cokoliv v rozporu s pravidly, toho rozdrtí, zašlape do země, poplive a nakonec se na jeho ostatky -- no, nechal jsem se unést, ale asi chápete co chci říct. Stroustrup přiznává, že jeho snahou nebylo znemožnit programátorů stát se svými vlastními oběťmi. (Oproti tomu designeři C# se vyznávají z opačného přístupu: C++ and the Pit Of Despair.) Stroustrup chtěl jazyk tak mocný, že umožní až bizarní úrověň abstrakce, ale přitom programy v něm napsané poběží stejně rychle, ne-li rychleji než ty v C.

Věru, to se mu povedlo. Nicméně cenou za to je, že spousta z nás, nedomrlých programátorských wannabes, si, jsme-li vyzbrojeni C++, dříve či později ustřelí nohu, nebo nějakou jinou, možná ještě důležitější, část těla.

Proto jsem si myslel, že čas C++ pomalu končí, že až vymře těch pár dědků s táákovýmihle fousy, kteří udržují v chodu existující aplikace, celý svět se prozáří, a všichni budeme rázem programovat jen a pouze pro garbage collected jazyky, které generují nějaký ten byte code pro virtuální stroje jako je Java Virtual Machine, nebo Common Language Runtime.

Samozřejmě, že to byla hloupá představa.

Problém je v tom, že nějaký ten mikroprocesor je součástí skoro každého zařízení, které koupíte ve vašem oblíbeném (internetovém) obchodě s elektronikou. A jelikož to zhusta jsou málo výkonné procesory, je potřeba psát pro ně v jazyce, který je hardwarovému modelu takového procesoru co nejblíže. A takovým jazykem je právě C++. C++ přistupuje k paměti se stejnou nenuceností jako C, ale přitom se v něm dá vyvíjet na rozumné úrovni abstrakce, takže výsledný program může být hotov rychle a dá se udržovat.

Samostatnou kapitolou pak jsou různé tyhle PDA, nebo chytré telefony. Čert vem PDA -- těm už vážně odzvonilo (jejich prodej opět poklesl o 40%), ale za pár let budou všechny telefony chytré, protože to bude lacinější, mít jen jednu základní desku (resp. její zapojení) pro celou modelovou řadu, a na každém telefonu poběží nějaký ten operační systém (ať už Symbian, nějaký ten klon Linuxu, nebo Windows Mobile, či jak se to vlastně bude za tři roky jmenovat), a pro ten bude potřeba vyvíjet aplikace v jazyce, který bude co nejblíže hardwaru.

Říkáte si: blbost, za pár let bude v každém telefonu Java, a po C++ nikdo ani nevzdechne. Myslím, že ne. Svůj odpor ke snobské společnosti Apple jsem tu vyjádřil tolikrát, že to už ani není zajímavé, ale přesto nemohu Apple upřít, že iPhone to bere v zásadě za správný konec. Mám na mysli tohle: co jsem tak četl, iPhone disponuje dlouhou výdrží baterie, což je jistě vlastnost, kterou každý rozumný člověk od podobného zařízení očekává, nicméně málokdy jsou jeho oprávněná očekávání naplněna.

Aby baterie vydržela dlouho, a přitom telefon mohl dělat všechny ty cool věci, které od něj očekáváme, má jeho výrobce v zásadě jedinou možnost: snížit spotřebu procesoru a pamětí (nebo displeje, ale displej je to, co dnes odlišuje jednotlivé třídy telefonů, takže pro high-end modely s ním nejde moc dělat). V tomto směru jsou tu dvě možnosti: zaprvé do telefonu strčit pro některé, na procesorový čas náročné operace, speciální obvod (jako je v iPhone hardwarový dekodér videa). To je ovšem drahé a pro low-end se to nehodí (na méně movité zákazníky s telefonem za 500USD dojem neuděláte), navíc speciální čip bude vysávat baterii. Nebo můžete do přístroje strčit pomalejší a úspornější procesor, který bude mít k dispozici méně paměti, a operační systém a aplikace napíšete tak, aby z takového hardware vyždímaly co se dá. A tady se zase vracíme k C++.

Čili, ať děláte co děláte, programování na úrovni (resp. rozsahu úrovní), kterou poskytuje C++ se nevyhneme ani v nejbližších několika letech.

Řikáte si: ale já kašlu na nějaký chytrý mobil. Mám své PC (od libovolného výrobce) a tam je výkonu taková přehršel, že se o nějakých pár usmolených wattů starat nemusím. Ohó, říkám já, to se tedy pletete.

Pomalu začíná docházet k tomu, po čem toužím už několik let: aby PC žraly (nedá se to říct jinak) méně. Počítače se zvolna začínají učit šetřit energií, a jak její cena poroste, a jak se na trhu budou stále více prosazovat mobilní PC (notebooky a to, v co se časem přemění TabletPC nebo UMPC), bude zase potřeba být s to využít výkon který je k dispozici co nejúčelněji.

.NET sice umí předkompilovat strojový kód svého virtuálního stroje do nativního kódu procesoru na kterém běží, a asi v tom je i docela dobrý, ale poctivá kompilace C++ programu nastavená na rychlost (nebo na velikost) je něco, s čím se dá asi při Just In Time kompilaci jen těžko bojovat.

Jsem první, kdo řekne: čert vem 15% výkonu, hlavně že tu aplikaci napíšu rychle, půjde udržovat, a využije konzistentního frameworku, ale firmy, které vyrábějí výpočetně a paměťově intenzivní software (třeba ty navigační programy, o kterých jsem tu tuhle mluvil), ví své. Každých pár kilobytů paměti se počítá, každé procento na rychlosti běhu se u zákazníků počítá.

Závěrem: Tak se stalo, že jsem se z odmítače C++ stal ostražitým sledovačem, který bude vývoj tohoto jazyka, který jsem už považoval za mrtvý (v smyslu, v jakém je mrtvá Latina), bude pečlivě sledovat. Protože jak tuhle řekl BVer: správný programátor udržuje svou bedničku s nářadím vybavenou a připravenou.

pátek, července 13, 2007

Bábel

Jak jsem tu už zmiňoval, drželi jsme s BVerem řeč na letošním Festivalu Fantazie (matně si vybavuji nějaké rčení o tom, že čím méně něčemu rozumíte, tím spíše o tom budete druhé poučovat...). V rámci přípravy jsem si napsal tyhle guidelines, kterých jsem se nakonec ani moc nedržel, protože tak už to na takových neformálních přednáškách chodí. Nicméně myslím, že publikum jsme pobavili (zejména jazyk WhiteSpace sklidil velký úspěch), nadhodili několik vcelku podmětných poznámek o DSL (ty zmatené obličeje, když jsem ukázal na pár odstavců anglicky psaného textu a řekl, že tohle je kód Inform7 stály za to) a tak dále a tak podobně.

Občas bylo potřeba trochu tlačit na pilu, aby mezi mnou a BVerem při přednášce vznikly nějaké třecí plochy, které pobaví posluchače, takže pokud se vám některé pasáže budou zdát příliš... erm... no prostě na několika místech jsem schválně přeháněl, protože to zkrátka bylo potřeba. Text asi obsahuje nějaké překlepy a tak podobně, ale vzhledem k jeho délce nemám sílu to znova celé číst a korigovat.

Jak já to vidím, přístup k programovacím jazykům se v posledních, řekněme destíti letech, tedy s nástupem Internetu, podstatně změnil.

Dříve se člověk seznámil s více programovacími jazyky maximálně tak na univerzitě, kde z didaktických důvodů přičichl ke Smalltalku, a tak trochu k Lispu, a samozřejmě k Pascalu, který, ze mně ne zcela zřejmých důvodů, bývá považován za vhodný jazyk k výuce programování. Když programátoři dospěli, skončili jaksi samozřejmě u C++, nebo ti progresivnější u Javy. (Nemluvíme tu o BASICu a assembleru, protože to jsou záležitosti pro nás staré dědky.)

Dnes je situace naprosto jiná. Mladí programátoři se začínají učit programovat v Javě nebo PHP (to je snad ještě děsivější než začínat s Pascalem), pak do sebe nacucnou celou škálu skriptovacích jazyků jako je Perl, Python nebo Ruby, pak se třeba podívají na Lisp a vrkají si spolu o tom, jak skvělý je typový systém v Haskellu, a že kdo to myslí s paralelizací vážně, nemůže než použít Erlang, k tomu nějaký ten C# pro nás Microsoftí poskoky, nebo, pokud máte silná zápěstí, třeba VisualBasic (s i bez Option strict, což je nastavení, které udělá z VisualBasicu úplně jiný jazyk se stejnými klíčovými slovy), a základem je určitě i SQL, a tak dále a tak podobně.

Prostě: tam, kde dříve programátoři konvergovali k jedinému jazyku (kterým bylo C nebo C++) a s tím vystačili na větší část své kariéry, se dnes mladí vlčáci naučí pět až šest diametrálně odlišných jazyků ještě než jim naskáčou na čele uhry.

Čím to je? Domnívám se, že rozdíl je v té šíři aplikací, pro které se dnes počítače používají. Jak již řekl můj fundovanější kolega, programovací jazyk vybíráme podle aplikační domény, tedy podle toho co se chystáme dělat. Jistě nemá smysl programovat webové aplikace v C++, a na druhou stranu, je zřejmé, že i když napsat kompilátor PHP do nativního kódu by asi nebyl takový problém, nikdo to neudělá jen proto, aby mohl pro své PDA vyvíjet ve stejném jazyce jaký používá 90% programátorů s klamnými představami o svých schopnostech.

Tedy: jak se rozšiřuje množství aplikací, rozšiřuje se i počet jazyků, kterými tyto aplikace píšeme. Na programování klademe v různých oblastech různé nároky (třeba: náročnost na zdroje, ověřitelnost správnosti, rychlost, přehlednost, rychlost implementace atd.), a tomu se uzpůsobují i jazyky, které používáme.

Problém s programovacími jazyky je tento: programovací jazyky, stejně jako Olomoucké tvarůžky, potřebují čas, aby dozrály. Už nějaký čas sleduji vývoj jednoho programovacího jazyka, na kterém pracuje řekněme deset dvacet lidí tak čtyři roky. Je to skvělý jazyk? Ó, to nepochybně. Boo je jeden z nejvíce sexy jazyků na které jsem narazil (jakožto milovník staticky typovaných jazyků se příliš nevzhlížím v Ruby nebo Pythonu). Použil bych ho pro psaní nějaké aplikace, u níž předpokládám vývoj delší než řekněme dva měsíce? To nikdy.

Programovací jazyky jsou založeny na kompilátorech a interpreterech. A kompilátory a interpretery jsou software jako každý jiný. A software obsahuje chyby. A dovedete si představit něco více frustrujícího než používat programovací jazyk, jehož kompilátor (nebo interpreter) je plný chyb?

Můj volnomyšlenkářský kolega tu prezentoval svou antipatii k jazykům vlastněným firmám. Vážený příteli, velké firmy jsou jediné instituce, které dokáží uřídit vývoj něčeho tak delikátního jako je programovací jazyk s dostatečnou kvalitou. Skutečnost, že stovky tisíc open-source dobrovolníků dokázaly vyvinout za více než dvacet let existence open-source hnutí tři použitelné skriptovací jazyky (Perl, Python a Ruby), mluví samo za sebe. Všechny ostatní jazyky "vlastní" buď nějaká soukromá společnost, nebo univerzita, nebo se brzy po svém vzniku rozštěpily do tolika větví a jsou tak nespolehlivé, že je nikdo seriózně nepoužívá (viz třeba Lisp, který má asi tři sta dvacet sedm vzájemně nekompatibilních dialektů a nepoužitelné knihovny). To, že vlastníci těchto jazyků maskují za licenci GPL vůbec nic neznamená.

Tím jsem se dostal k další záležitosti, kterou tady pan doktor nakousl: knihovny. Knihovny jsou dneska stejně důležité, ne-li důležitejší, než samotný jazyk. Bez knihoven, na úrovni abstrakce, na které se musíte dneska pohybovat, abyste v konečném čase stvořili něco smysluplného, bez pořádného balíku knihoven, nejlépe celého frameworku, nesvedete nic. Potřebujete knihovny na práci s unicode řetězci (což je oblast, jejíž složitost si většina jedinců ani nedokáže představit), s implementací TCP/IP socketů, nějaké to šifrování, zobrazování, XML, formátování výstupu a zpracování vstupů v závislosti na národním nastavení, prostředky pro komunikaci a synchronizaci u vícevláknových aplikací, přístup na disky se všemi těmi zabezpečovacími serepetičkami, izolovaná úložiště dat, a tak dále a tak podobně. A to jsme ještě nezabrousili do oblastí řízení bezpečnosti aplikací a přidělování oprávnění k přístupu k různým částem operačního systému.

Chci říct: napsat programovací jazyk je jedna věc, ale učinit ho užitečným je věc úplně jiná. A sílu učinit jazyk užitečným mají podle mého jen společnosti, které jsou dost bohaté a schopné na to, aby vývoj tohole všeho zvládly v čase kratším než geologickém.

Aha, vidím nespokojenost na tváři tady mého veleváženého kolegy. Inu, má pravdu. Existuje způsob jak vyvinout dobrý jazyk a dobrými knihovnami a nestrávit tím celý život: použijete existující framework s virtuálním strojem, a pro ten svůj skvělý jazyk napíšete. Dnes máme na výběr ze dvou variant: jednak je tu Java Virtual Machine od Sun Microsystems, na kterém běží Java, dvak Common Language Runtime od Microsoftu, který využívá široká paleta .NET jazyků. Samozřejmě, že přítomné zrdojanarchisty nemůže uklidnit to, že je jejich jazyk plně open-source, když běží na virtuálním stroji soukromé společnosti, ale výhody pro nás ostatní jsou zřejmé: zaprvé od úplného začátku existuje celý balík velmi dobrých knihoven, které lze použít, a zadruhé: všechny tyhle optimalizační a portační kejkle za vás udělá někdo jiný. Vy si jen poklidně kompilujete do nějakého toho bytekódu, který pak virtuální stroj překládá do instrukcí procesoru který právě používáte.

Proto: pokud dneska opravdu chcete napsat programovací jazyk, piště jej pro některý z těchto virtuálních strojů. Jinak se sice naučíte spoustu zajímavých věcí o kompilátorech a procesorech a všech ostatních cool věcech, kterými neuděláte dojem na slečny dole u baru, ale bude to práce, kterou nikdo neocení.

Existuje ještě jedna skupina jazyků, o kterých jsme se tu ani já, ani můj vzdělanější kolega nezmínili. Jde o tzv. DSL, neboli domain specific languages, tedy jazyků určených pro jednu konkrétní aplikační doménu. Tento druh jazyků se dneska většinou píše v programovacích jazycích které vládnou syntaktickými makry, tedy takovou vypečenou věcičkou, která vám umožní do jakési meta-funkce předat jako parametr kus kódu, který se pak při kompilaci (nebo interpretaci) přeloží do skutečného kódu toho kterého jazyka. Příhodnou ukázkou může být třeba generování XML (nebo HTML), kdy místo používání ordinérních prostředků pro zapisování tagů použijete virtuálně vytvořená klíčová slova vašeho DSL, čímž celou věc krásně zpřehledníte a zjednodušíte.

DSL je dneska progresivní oblast programovacích jazyků (asi jako začátkem devadesátých let OOP), která pomocí dostatečně mocných obecných jazyků umožňuje napsat speciální jazyk pro každou aplikaci tak, že z kódu je hned zřejmé nejen jak věci děláte, ale také co děláte a leckdy i proč.

Nejzářnějším příkladem DSL je Inform7, tedy programovací jazyk určený k vývoji interaktivních fikcí (tedy textových adventur), který se snaží předstírat, že programujete v angličtině. V I7 napíšete něco jako "Miska s vodou stojí na stole v kuchyni," a překladač z toho sám odvodí, že miska je kontejner, stůl je objekt, na kterém mohou ležet jiné objekty a že kuchyň je místnost ve hře. Problém je v tom, že a) to funguje jen v angličtině, b) když se dostanete za hranice takto jednoduchých vztahů, musíte tvořit další pravidla pomocí syntaxe, která není ani zdaleka tak přehledná. Nehledě na to, že v takovémto jazyce se prakticky nedá ladit.

Nicméně si myslím, že podobně formované DSL budou v nejbližší budoucnosti poměrně populární, a že otevřou programování mnohem šiřší skupině než lidí, než by starému von Neumanovi bylo milé (ten dokonce považoval i assembler za zatemňování smyslu programu; ale co byste čekali od člověka, který sčítal nekonečné řady z hlavy).

Takže: i když, jak tu můj esotericky zaměřený kolega prezentoval, lze napsat programovací jazyk o jediné instrukci a přesto bude Turing-kompletní, volba správného programovacího jazyka je a bude zatraceně důležitá. Správný programovací jazyk vás zbaví potřeby znát polovinu návrhových vzorů z té provařené knihy gangu 4 (z hlavy si vzpomenu třeba na iterator, strategii a visitor), ty správné (funkcionální) jazyky budou potřeba pro rozvoj opravdu paralelního programování, příhodné jazykové konstrukce vás dokáží zbavit potřeby šmudlit složité SQL dotazy, nebo opakovat jeden skoro stejný kód dvacetkrát.

Zkrátka: pokud jste se rozhodli následovat osud dinosaurů, držte se svého jazyka a o nic dalšího se nezajímejte. Vy ostatní: vítejte v Babylonu!

A abych nezapomněl: stav je zdrojem všeho zla!

čtvrtek, července 20, 2006

Jazykotepci

Není nic smutnějšího, než zamlklý blogger. Chci říct: nějak se mi v létě ani nechce nic psát, ale protože přiznat, že se mi nechce psát, by v kontextu weblogu působilo dost podivně, řeknu, že jsem se věnoval studiu jazyků. A opravdu. Narazil jsem teď nedávno na dva docela zajímavé programovací jazyky, kterým jsem věnoval nějaký ten čas, který bych jinak třeba věnoval psaní duchaplností.

Takže první z nich je Boo. Boo je převodem syntaxe dynamicky typovaného Pythonu do prostředí staticky typované platformy .NET, bez pythonovských dogmat, ale s některými rysy, které připomínají tak trochu Ruby a malinko (opravdu malinko a jen někdy) Lisp. Zní to dost zmateně, ale Boo má všechno, co jsem kdy záviděl programátorům ve skripotvacích jazycích, jako jsou třeba closures (pěkně o closures píše třeba guru extremních programátorů Martin Fowler tady), generátory nebo Perlovská syntaxe regulárních výrazů, a přitom se zbavuje některých věcí, které jsou opravdu otravné v C# (verzi dva), jako je třeba nutnost psát sáhodlouhé názvy typů tam, kde si kompilátor může typ domyslet sám, a obecně potřeba chrlit desítky řádků kódu, abyste napsali nějakou v zásadě jednoduchou věc.

Další výhodou Boo je třeba že: a) generuje standardní .NET assemblies (pro verzi frameworku 1.1 i 2.0), což prý IronPython (port Pythonu na platformu .NET) neumožňuje, b) díky tomu, že je staticky typovaný, netrpí výkonovou ztrátou, která je pro dynamicky typované jazyky obvyklá, c) je podporován vývojovým prostředím SharpDevelop, d) i když ho vyvíjí prakticky jediný člověk, je otevřený, a tudíž není pod kontrolou jediné firmy, e) disponuje báječnou věcí, které se říká syntactic macros, která umožňuje doplnit jeho syntaxi o cokoliv, co vás jen napadne (nebo skoro cokoliv), f) komunita kolem něj není příliš velká a v zásadě je velmi rozumná, takže se zatím dokázal ubránit smršti fanatických debat o hloupostech.

Zkoušel jsem psát v Boo dva jednoduché programy (jeden pro příkazovou řádku, druhý s WinForms), a byla to moc příjemná práce. Samozřejmě, že Boo má své nevýhody. Asi největší je absence podrobnější dokumentace, druhou pak skutečnost, že zatím nepodporuje generika, což někdy může být docela nepříjemný problém. Tak jako tak, ze skupiny alternativních .NET jazyků jako je IronPython, F# nebo Nemerle, je mi Boo nejsympatičtější a uvažuji, že v něm zkusím napsat nějakou obsáhlejší aplikaci.

Druhým jazykem na který jsem narazil, který je z akademického pohledu mnohem zajímavější než Boo, je Inform 7. I7 je jazyk (nebo spíše prostředí) určený jen a pouze pro vývoj interaktivních fikcí (interaktivní fikce se má k textovým hrám asi tak, jako nejnovější Toyota k prvnímu autu Henryho Forda), a zajímavé na něm je, že se maskuje jako angličtina.

Čili pokud chcete definovat nějakou herní lokaci (třeba kuchyni, ve které je stůl a na něm hrnek), napíšete něco jako Kitchen is a room. Description of kitchen is "Nice little kitchen". Table is supporter. Table is in the kitchen. Cup is container. It is on the table., čímž jste popsali kuchyni jako místnost, stůl jako objekt, na který se dají pokládat objekty a hrnek jako objekt, který může obsahovat objekty a který se nachází v kuchyni na stole (ve skutečnostidokonde stačí napsat jen něco jako Description of kitchen is "Nice little kitchen". Table is in the kitchen. Cup is on the table. Tea is in the cup., z čehož už si I7 domyslí co je co). Kouzelné je, že celý I7 je rule-based, a umožňuje definici různých operátorů jako je "většina", "několik", "skoro žádný", a tak podobně, které pak lze kombinovat s definovanými pravidly (takže můžete říct, že stůl unese 10kg, a ze když je přetížen rozpadne se -- to všechno v angličtině, samozřejmě). Dále I7 obsahuje implementaci path-findigu, který lze ovšem aplikovat nejen na hledání nejlepší cesty z místnosti do místnosti pro NPC (non-player characters), ale třeba také na stromy dialogů, které umožňují NPC bavit se s vámi poměrně sofistikovaným způsobem.

Zkrátka je to moc pěkný experiment, který se může (ale také nemusí) ukázat úžasným zjednodušením práce autorů interaktivních fikcí. Hlavní výhodou i nevýhodou I7 je používání angličtiny jakožto programovacího jazyka. Výhodou je, že když se podíváte na nějaké ukázkové programy, hned máte pocit, že programovat v I7 je jednoduché, z čehož jste ovšem záhy vyléčeni, protože I7 nerozumí angličtině, ale jen a pouze angličtině I7. Ta se, s tím, jak se snažíte dělat složitější a složitější věci, stále více vzdaluje angličtině, a více se přibližuje běžnému programovacímu jazyku, takže postupně zjišťujete, že se stejně musíte naučit programovací jazyk, jen o dost užvaněnější než jiné jazyky (snad s vyjímkou Visual Basicu).

V každém případě mě myšlenka alespoň takto omezeného použití "přirozeného" jazyka k programování nadchla a skoro si začínám myslet, že tudy se bude ubírat vývoj jednoduchých skritovacích jazyků: Každý si nadefinuje svou vlastní verzi angličtiny, které se vzájemně nebudou příliš lišit, a které otevřou programování i lidem, kterým teď připomíná kabalu. Hlavním proti je skutečnost, že různí lidé mluví různými jazyky a že lokalizace takového programovacího prostředku není triviální (pokusy naučit I7 česky alespoň na úrovni parseru příkazů jsem po pár hodinách vzdal, protože jsem měl nepříjemný pocit, že marním svůj čas).

Tak jako tak, bude zajímavé z povzdálí sledovat, co se z Inform 7 vyvine...

čtvrtek, března 09, 2006

Visual Driven

Takže BVer mě svou soustavnou věrozvěsteckou činností nakonec přeci jen uvrtal do Test Driven Development. (Byly časy, kdy jsem si myslel, že je to tím, že je o nějaký ten rok starší, že vždycky přivede k něčemu zajímavému on mě, a ne já jeho. Pak jsem ale sám trochu zestárl, a zjistil jsem krutou pravdu: opravdu jsou někteří lidé chytřejší než já. Někteří o dost chytřejší [sigh].) Zatím jsem ve fázi bezbřehého nadšení, které samozřejmě časem vyprchá, až budu kvůli banální změně v interfacu třídy přepisovat dvacet testů, ale právě teď mě fakt, že se v nUnit mnění kolečka z červených na zelená, naplňuje takovým štestím, že se to snad ani nedá popsat.

S tím souvisí další téma, které jsem chtěl už delší dobu zmínit: Visual Studio 2005. Tak tedy: na první pohled skvělé. Sice mi příjde, že se vizuálním vzhledem až nebezpečně blíží Microsoft Office 2003, což je samozřejmě nepříjemné, protože, jak známo, vývojové prostředí má být tak spartánské jak to jen jde... No dobrá, podobné žvásty mě iritují u vyznavačů čistých textových editorů jakožto primárního vývojového prostředku, takže si je odpustím. (Pravda je taková, že bych těch pár pixelů, které zkonzumují barevné toolbary klidně obětoval dalším dvěma řádkům kódu, ale nešť.)

Nové (teď už ne tak moc) Visual Studio z mého pohledu (tedy z pohledu v zásadě stand-alone vývojáře, sám se řídím, sám si peru, a tak dále) nepřineslo nic až tak obrovsky úžasného. Ano, C# konečně podporuje templaty (v microsoftím newspeaku generika), ano, Class designer je moc pěkná věc, která konečně umožňuje snadné XML komentování kódu, a občas i návrh tříd (a je opravdu fajn, že se prázdná třída vygeneruje automaticky), a pak jsou tu tyhle vymoženosti v Data-bindings, a spousta nových funkcí a tříd v .NET frameworku 2, ale popravdě: je to krok spíše evoluční, než revoluční, skoro nic, co by mi dneska nemohl poskytnout produkt jako je #develop, nebo v případě C++ nějaký ten front-end nad gcc.

Jelikož pořád ještě nemáme (a dlouho mít nebudeme) WinFX, nějakému tomu importování Win32 funkcí se člověk nevyhne, nové Visual Studio padá (a to tak že často -- s VS2003 jsem žádný pád nikdy nezažil, zato hned první pokus s VS2005 skončil moc pěknou chybou, kdy neinicializovaný objekt -- po importu projektu z VS2003, kde to nevadilo -- způsobil pád form-designeru, který se, po znovuspuštění a znovunačtení projektu, automaticky načetl, takže nebylo lze chybu opravit, a nakonec jsem musel smazat .suo soubor, abych se neotevíraly žádné soubory projektu), i když je teď dialog Options trochu přehlednější, nemůžu se zbavit dojmu, že z něj zmizely některé položky, které v VS2003 bylo možné nastavit.

Celkově je VS2005 (podle mého zjevně nezasvěceného názoru) pořád nejlepším vývojovým prostředím (hlavně kvůli opravdu vypečenému IntelliSense), ale nějak jsem si od něj sliboval víc...