Karl-Ludwig Poggemann (cc by 2.0)

Jsou pointery a rekurze latinou softwa­rového inženýr­ství? Zde je článek The Perils of JavaSchools, který napsal Joel Spolsky (mimo jiné spolu­autor stackoverflow.com). S jeho laskavým svolením na serveru, kde už je více jeho českých překladů, jsem text přeložil do češtiny (překlad uvolňuji pod licencí Creative Commons by-nc-sa).

29. prosince, 2005

Líná děcka.

Kam se poděla tvrdá dřina?

Jistou známkou mé senility je naříkání nad „dnešními dětmi“ a nad tím, jak už nechtějí či nezvlád­nout dělat cokoliv obtížného.

Jako dítě jsem se učil progra­movat na děrných štítcích. Pokud jste udělali chybu, neměli jste žádnou z těch moder­ních vymože­ností jako tlačítko zpět, abyste chybu napra­vili. Museli jste štítek vyhodit a začít od začátku.

Když jsem v roce 1991 začal dělat vstupní pohovory s programátory, nechal jsem je vybrat si libovolný jazyk k řešení problémů, které jsem jim dal. V 99 % případů si vybrali C.

Dnes dávají přednost Javě.

Nechápejte mě špatně, s Javou jako imple­men­tačním jazykem není nic špatně.

Počkat, chci změnit své prohlášení. V tomto konkrétním článku nepíšu nic o tom, že je Java špatný jazyk. Je mnoho věcí, co je na ní špatně, ale to je na samos­tatný článek.

Místo toho bych rád zdůraz­nil, že Java není dosta­tečně složitý progra­mo­vací jazyk, aby dokázal oddělit skvělého programátora od průměr­ného. Může to být dobrý jazyk na práci, ale to není dnešním tématem. Dokonce bych zašel tak daleko a řekl, že fakt, že Java není tak složitá, není bug, ale featura.

Můžu-li být tak drzý, z mé skromné zkuše­nosti soudím, že jsou na univer­zitách jako součást osnov Computer Science (dále jen CS) tradičně učeny dvě věci, které mnoho lidí nikdy skutečně plně nepocho­pilo: pointery (ukaza­tele) a rekurze.

Na škole jste začínali s kurzem datových struktur (spojové seznamy, hasho­vací tabulky atd.) s rozsáhlým použitím pointerů. Tyto kurzy byly často používány jako síto. Byly tak obtížné, že kdo by býval nezvládl mentální výzvu oboru CS, by to vzdal. Což bylo dobře, protože pokud si myslíte, že pointery jsou obtížné, počkejte až se pokusíte dokázat věci ohledně fixed-point teorému.

Všechna ta děcka, která válela na střední, protože si v BASICu napsali hru pong pro svůj Apple II, se dostala na vysokou. Zapsali si CompSci, kurz datových struk­tur, a když se dostali k pointerům, jejich mozek prostě explo­do­val. Další věc, kterou o nich víte je, že získali titul z polito­lo­gie, protože právničina se jim zdála jako lepší nápad. Viděl jsem různá čísla kolik lidí odpadne z CS, obvykle je to mezi 40 % a 70 %. Školy mají sklon si myslet, že je to plýtvání. Já si myslím, že je to prostě nezbytné třídění lidí, kteří se nestanou šťastní a úspěšní v kariéře programátora.

Další obtížný kurz pro mnoho mladých studentů CS byl kurz, kde jste se učili funkcionální progra­mování včetně rekurze. MIT nasta­vilo pro tyto kurzy laťku velmi vysoko. Vytvořili povinný kurz(6.001) a učebnici (Abelson & Sussman - Struc­ture and Inter­pre­ta­tion of Computer Programs), která byla použita na stovkách nejlepších škol jako de facto úvod do CS. (Můžete a měli byste se podívat na starší verzi přednášky online.)

Obtížnost těchto kurzů je udivující. V první lekci jste se naučili téměř vše ze Scheme a byli jste již seznámeni s funkcí, která bere další funkci jako svůj vstup. Když jsem zápasil s takovým kurzem (CSE121 na Penn), viděl jsem, jak ho mnoho studentů, ne-li téměř všichni, nezvládli. Materiál byl příliš obtížný. Napsal jsem profe­so­rovi dlouhý lkavý dopis, že to nebylo fér. Někdo na Penn mě (nebo někoho jiného) musel vyslyšet, protože teď je kurz vyučován v Javě.

Kéž by bývali neposlouchali.

Léta skuhrání líných bakalářů jako já v kombi­naci se stížnostmi z průmyslu na to, jak málo inženýrů promuje na americ­kých univer­zitách, si vybralo svou daň. Velké množství jinak perfektně dobrých škol v posled­ních deseti letech přešlo 100 % na Javu. Je to trend. Perso­na­lis­tům, kteří používají „grep“ na vyhod­no­cení životo­pisů, se to, zdá se, líbí. Nejlepší na tom je, že na Javě není nic tak obtížného, abyste na tom mohli vyhazovat programátory, kterým chybí ta část mozku, která zvládá pointery a rekurzi. Takže odpadne málo lidí, fakulty mají více studentů, větší rozpočet a vše je dobré.

Štastná děcka z Java škol nikdy nedostanou divný segfault při imple­men­taci na pointe­rech založené hash tabulky. Nikdy neztuhnou hrůzou ani nebudou blouznit při převodu věcí do bitů. Nebudou si lámat hlavu nad tím, že se v čistě funkcionálním programu nikdy nemění hodnota proměnné a přesto se stále mění. Paradox!

To jste měli štěstí! My jsme tři měsíce bydleli ve zmuchlaných novinách v septiku! Museli jsme každé ráno vstát v šest ráno a vyčistit noviny, běžet do fabriky, tam pracovat čtrnáct hodin denně, týden za týdnem, šest pencí týdně a když jsme se vrátili domů, otec nás uspával ranami opaskem!

Monty Pythonův létající cirkus - Four Yorkshiremen

Jsem jen jeden z těch starých bručounů, jako Four Yourk­shir­men, chvás­tajících se, jak drsné bylo přežít všechny ty obtíže?

V roce 1900 byla na vysokých školách latina a řečtina povinný předmět ne proto, že by sloužila k nějakému účelu, ale protože byla svým způsobem považo­vaná za všeobecný rozhled vzdělaných lidí. V jistém smyslu se můj argument neliší od lidí, kteří prosa­zo­vali latinu. “[Latina] trénuje vaši mysl. Trénuje paměť. Rozluštit latin­skou větu je úžasné myšlen­kové cvičení,” napsal Scott Barker. Ale nemůžu najít jedinou univer­zitu, která by ještě latinu vyžado­vala. Jsou pointery a rekurze latinou CS?

Připouštím, že progra­mování s pointery není v 90 % přípa­dech potřeba, ve skuteč­nosti jsou v produkčním kódu naprosto nebez­pečné. Dobrá. A funkcionální progra­mování není tak moc využíváno v praxi. Souhlasím.

Ale je to stále důležité pro některé z nejvzrušujících programátor­ských prací. Bez pointerů bychom například nikdy nebyli schopní pracovat na linuxovém jádru. Nemůžete porozumět řádku kódu Linuxu, ani jiného operač­ního systému, bez skuteč­ného porozumění pointerům.

Bez porozumění funkcionál­nímu progra­mování bychom nevyna­lezli MapReduce, algoritmus který dělá Google tak masivně škálo­va­telný. Termín Map a Reduce přišly z Lispu a funkcionál­ního progra­mování. Zpětně viděno, MapRe­duce je zřejmé každému, kdo si pamatuje něco z 6.001 - čistě funkcionální program nemá žádné vedlejší efekty a proto je snadno parale­li­zo­va­telný. Fakt, že Google, nikoliv Micro­soft, vynalezl MapRe­duce, říká něco o tom, proč Micro­soft stále nemůže dohnat základy vyhledávání, zatímco Google se posunul k dalšímu problému: budování Skynet^H^H^H^H^H^H světově největší hromadně paralelní superpočítač. Nemyslím si, že by si Micro­soft plně uvědo­mo­val, jak daleko jsou za konkurencí.

Kromě prima facie důleži­tosti pointerů a rekurze je jejich skutečná hodnota v tom, že velké systémy vyžadují tento druh mentální flexi­bi­lity, které se vám dostane během učení se o pointe­rech a rekurzi. A tuto mentální schop­nost potře­bu­jete, aby vás nevyho­dili z kurzů, kde se učí. Pointery a rekurze vyžadují určitou schop­nost úsudku, abstrakt­ního myšlení, a hlavně vidět problém v několika úrovních abstrakce zároveň. A proto schop­nost porozumět pointerům a rekurzi je přímo úměrná schop­nosti být skvělým programátorem.

Z osnov posta­vených kompletně na Javě skutečně nic nevytřídí studenty, kteří postrádají mentální hbitost vypořádat se s těmito koncepty. Jako zaměst­na­vatel jsem viděl, že Java školy začaly stloukat máslo ze studentů, kteří nejsou prostě dost dobří na to, aby praco­vali na složitější aplikaci než další Java účetnictví. Přesto je byli schopní protlačit novými, nesku­tečně zjedno­dušenými předměty. Tito studenti by nikdy nepřežili 6.001 na MIT nebo CS 323 na Yale. A upřímně, to je jeden z důvodů, proč si jako zaměst­na­vatel cením titulu z MIT nebo Yale víc než z Duke, kde nedávno kompletně přešli na Javu. Nebo U. Penn, kde nahra­dili Scheme a ML Javou a snaží se učit předmět CSE121, který téměř zabil mě i moje kamarády. Ne že bych nechtěl najmout chytrá děcka z Duke nebo Penn, najímám je, jen je pro mě o dost těžší zjistit, co jsou zač. Býval jsem schopný poznat chytrá děcka, protože bývali schopní ve vteřině porozumět rekur­ziv­nímu algoritmu nebo imple­men­tovat funkce na manipu­laci se spojovým seznamem pomocí pointerů tak rychle, jak rychle uměli psát na tabuli. Ale u Java absol­ventů nedokážu říct, zda se s tím problémem trápí proto, že nejsou dosta­tečně vzdělaní, nebo proto, že jim chybí ta speciální část mozku, kterou budou potře­bovat pro skvělou programátor­skou práci. Paul Graham takovým říká Blub Programmers.

Je velmi zlé, že Java školy nevytřídí taková děcka, která se nikdy nestanou skvělými programátory. Školy se můžou vymlu­vit, že to není jejich problém. Průmysl, nebo alespoň perso­na­lis­té-používající-grep jistě volají po tom, aby se učila Java.

Ale Java školy rovněž selhávají v trénování mozků dětí k tomu, aby byli znalé, hbité a dosta­tečně flexi­bilní pro to dělat dobrý softwa­rový design (a nemyslím objek­tově orien­to­vaný „design“, kde trávíte nespočet hodit přepi­sováním svého kódu do hierar­chie objektů nebo dřina s falešnými „prob­lémy“ jako has-a versus is-a). Potře­bu­jete trénovat myšlení o věcech na více úrovních abstrakce zároveň a tento druh myšlení je přesně to, co potře­buje návrh skvělé softwa­rové architektury.

Může výuka objek­tově orien­to­vaného progra­mování (OOP) nahradit síto pointerů a rekurze? Rychlá odpověď: ne. Bez debaty o podstatě OOP to není dosta­tečně obtížné k vytřídění průměr­ných programátorů. OOP se na školách skládá většinou z memorování slovníkových hesel jako „zapouz­dření“ a „dědič­nost“ a absol­vování testů ohledně rozdílů mezi polymorfismem a přetěžováním. O nic složitější než se naučit pár slavných dat a jmen v hodinách dějepisu. OOP tak nepřed­s­ta­vuje dosta­tečnou hrozbu, která by odradila prváky. Pokud máte problémy s OOP, váš program bude stále pracovat, jen ho bude složité udržo­vat. Ovšem máte-li problémy s pointery, tak dosta­nete Segmen­ta­tion Fault a nebudete mít tušení, co se děje, dokud se nezas­tavíte, zhluboka nadech­nete a skutečně přinutíte svou mysl pracovat ve dvou různých úrovní abstrakce najednou.

Mimochodem perso­na­lis­té-používající-grep jsou zde vysmíváni z dobrého důvodu. Nikdy jsem nepotkal nikoho, kdo umí Scheme, Haskel a pointery v C, kdo by se nedokázal naučit Javu za dva dny a psát lepší kód než lidé s pětiletou praxí v Javě, ale zkuste to vysvětlit průměr­nému HR trubci.

A co s poslání CS fakult? Nejsou to učňáky! Nemělo by být jejich úkolem trénovat lidi pro práci v průmyslu. To by vám měli říct kolegové nebo v rekva­li­fi­kačním kurzu. Univer­zity by měly dávat studentům základní nástroje na žití jejich života, nikoliv je připra­vovat na první týdny v práci. Není to tak?

Přesto CS jsou důkazy (rekur­ze), algoritmy (rekur­ze), jazyky (lambda kalku­lus), operační systémy (poin­te­ry), kompilátory (lambda kalku­lus). Z toho plyne že Java školy, které nebudou učit C ani Scheme, ve skuteč­nosti vůbec neučí CS. Jakkoliv neuži­tečný může být koncept function currying pro skutečný svět, je to základní požadavek pro CS školy. Nedokážu pocho­pit, proč profe­soři při schva­lování osnov dovolili, aby jejich program zprimi­tivněl na úroveň, kdy nejen že už nezvlád­nout produ­kovat pracující programátory, ale nedokáží ani produ­kovat studenty, kteří by mohli získat doktorát a ucházet se o jejich práci. Počkat. Nevadí, možná že rozumím.

Když se vlastně vrátíte zpět a prozkoumáte diskusi, která se odehrála na akade­mické půdě během Velké Java změny, všimnete si, že největší obavou bylo zda je Java, jako výukový jazyk, dosta­tečně jednoduchá.

Můj bože, pomyslel jsem si, chtějí osekat osnovy ještě víc! Proč rovnou nekrmit studenty lžičkou? Nechme asistenty, ať za ně píší testy, tak alespoň nikdo neuteče na humanitní studia. Jak se má kdokoliv cokoliv naučit, když byly osnovy pečlivě sesta­veny tak, aby bylo všechno zjedno­dušeno ještě více, než už to je? Zdá se, že je tu síla (PDF), která se snaží najít jedno­du­chou podmnožinu Javy, kterou by šlo učit studenty. Připra­vují zjedno­dušenou dokumen­taci, která pečlivě schovává všechen ten EJB/J2EE balast před jejich něžnou myslí.

Nejsym­pa­tič­tější inter­pre­tace toho, proč CS fakulty tak nadšeně zjedno­dušují předměty, je to, že jim to nechává víc času na vysvět­lení skuteč­ných CS konceptů. Pokud by nepotře­bo­vali celé dvě lekce na vysvět­lení rozdílu, řekněme, Java int a Integer. No, pokud je to ten případ, tak 6.001 pro to má perfektní odpověď: Scheme, je to tak jedno­duchý jazyk že může být bystrým studentům vysvětlen celý za deset minut. Pak můžete věnovat zbytek semestru fixed-point teorému.

Pche.

Vracím se k jedničkám a nulám.

(Cože, vy máte jedničky? Klikaři! My měli jen nuly.)

Osobní poznámka překladatele

Nebyl jsem ze studia FEL ČVUT nijak nadšený, naopak jsem dost držkoval. Ovšem nutno přiznat, že ačkoliv nás učili Javu, prošel jsem si i pointery a rekurzi (pravda, to už jsme měli na střední). Bohužel se pro samý hardware a elekt­ro­niku nedostalo na Haskel, Lisp…

Zpětně viděno, má úloha z přijímacího pohovoru do Google velký smysl.

Související