===============================================================
Guido van Rossum:  Python in New York
                   Part I -- The Origins of Python
===============================================================
Google New York's Technical Speaker Series.
Guido van Rossum giving his Python presentation
at the New York Google office on Wednesday, February 22nd 2006.
http://video.google.com/videoplay?docid=-7758421725489622662
===============================================================

Část I -- Kořeny (původ) jazyka Python

Guido van Rossum přednáší v prostorách firmy Google ve středu 22. února 2006.

Zrození jazyka Python

  • Prosinec 1989,
  • během dvou volných týdnů volného času.
  • Nejdříve bylo vše v hlavě.
  • Fat Mac, překladač Ligthspeed C, 20 MB hard disk. (Můj současný mobil je výkonnější, než počítač, na kterém vše vznikalo. Mimochodem, na mém mobilu rovněž jede Python.)
  • První kód: generátor parseru. (Při prvních pokusech s parserem docházelo k tříbení syntaxe, protože ze začátku nebylo úplně jasné, jak by měla vypadat.)
  • Brzy vznikl první běžící program.

První fáze vývoje trvala asi rok (ve volném čase). Únor 1992 -- první zveřejněná verze (usenet) pod licencí podobnou MIT.

Některé cíle návrhu

  • Chování podobné shellu (interaktivní režim i skripty). Interaktivní režim není dotažen do té míry, ale některé projekty jako IPython tímto směrem jdou. Jsem dinosaurus, který je docela spokojený s používáním klasického Bourne Shell.
  • Architektura umožňující rozšiřování (vytváření nových typů). Měl jsem bolestné zkušenosti s předchozím jazykem, který se nedal rozšiřovat [ABC].
  • Být jedním z mnoha nástrojů, dobře s nimi spolupracovat (work well with others). Měl by to tohoto prostředí dobře zapadnout. Původně byl vyvíjen na unixové platformě, takže odpovídal unixové filosofii (vědomě i podvědomě).
  • Dodatečná funkcionalita musí být implementovatelná odděleně.
  • Vyhnout se syndromu "Not Invented Here" (volné půjčování myšlenek odjinud).
  • Musí to jít udělat jako "projekt pro jednoho člověka" (zkratky, "řezání zatáček"). V takové situaci se musíte rozhodnout, které části jsou natolik důležité, že je chcete psát sami. Ostatní věci se pak řeší používáním již hotových knihoven a tím, že umožníte psát některé věci jiným lidem.

Proč je objektově orientovaným? [05:50]

Koncem 80. a začátkem 90. let jsem nebyl velkým příznivcem OO jazyků. Věděl jsem o Smalltalku a C++ a opakovaně jsem si kladl otázku: "Co je vlastně tak zvláštního na objektově orientovaných jazycích?"

  • Jedním slovem: rozšiřitelnost. Nutnost objektově orientovaného návrhu přirozeně vyplynula z požadovaných vlastností jazyka z hlediska implementace.

  • Původní návrh byl objektově orientovaný uvnitř a počítal s používáním OO notace pro volání metod. Na druhou stranu nepodporoval uživatelsky definované třídy.

    Během návrhových prací se přirozeným způsobem prosadila dynamická typová kontrola (dynamic typing) a způsob implementace jazyka, který klade velmi silný důraz na dobu běhu (runtime orientation). [07:50]

  • Přístup k metodě byl zobecněn do podoby prostorů jmen (namespaces). [08:11] ... mít jeden prostor jmen, který by sjednocoval vše, co je viditelné na globální úrovni v modulu -- konstanty, proměnné, typy, třídy, funkce nebo dokonce další modul. Vše by bylo v jednom prostoru. Neměl by existovat syntaktický rozdíl mezi těmito prvky. Rozlišit se dají až podle použití.

  • Každý objekt představuje sám o sobě prostor jmen.

  • Modul je jen další objekt.

  • Vyhledávání jmen je přizpůsobitelné po prostorech jmen. [09:11] Nebyl definován standardní způsob zpřístupňování podle jmen. Prostě jste se objektu zeptali, zda může dát k dispozici objekt jménem XYZ. Tázaný mohl vrátit výjímku nebo vrátil objekt a následně jste mohli jste prohledávat zase jeho prostor jmen.

  • Uživatelsky definované třídy byly zavedeny během prvního roku vývoje, ale po dlouhou dobu zůstávaly "obyvateli druhé třídy" (až do zavedení nového stylu tříd v Pythonu 2.2).

    [09:17] Zajímavou historickou skutečností je to, že třídy v tom smyslu, že byste prostřednictvím syntaxe jazyka (příkazem class) zapsali definici nové třídy, původně v návrhu jazyka neexistovaly. Nepřišlo mi na mysl, že celá ta objektově orientovaná architektura je rovněž logickým základem toho, aby bylo i uživateli umožněno definovat své vlastní třídy. Přidání příkazu class navrhl kolega, který měl možná větší zkušenosti s C++ a dalšími jazyky. Původní myšlenka byla taková: pokud potřebujete nový typ, napíšete si kousek kódu v jazyce C a přilinkujete to k interpretu Pythonu. Ale lidi nechtějí psát kousky kódu v céčku, dokonce ani kvůli tomu, aby definovali nový typ.

Dobré věci z jazyka ABC [10:32]

ABC je předchůdcem Pythonu. S návrhem jazyka ABC nemám nic společného. Ovlivnil jsem jej možná z jedné desetiny procenta. Vznikal totiž na konci 70. a na začátku 80. let v hlavách vynikajících vědců na CWI v Holandsku. Poté co dokončili návrh jazyka a vytvořili velmi hrubý prototyp, rozhodli se najmout skupinu programátorů, kteří měli vytvořit korektní implementaci jazyka. Já jsem byl jedním z nich. Takže jsem asi 4 roky strávil prací s těmito lidmi. I když jsem neměl vliv na návrh jazyka, zkoušel jsem to. Kdykoliv mě napadla dobrá myšlenka, jak by se jazyk měl upravit nebo přidat nový rys, vždy mi laskavě a jasně vysvětlili, proč to není nutné a že uživatelé ABC by těmito rysy byli spíš více zatíženi, než aby jim v něčem pomohly.

[11:52] Svým způsobem jsem tento odpor k změnám v jazyce zdědil. Myslím si, že to je dobrý přístup, protože jazyk by se měl měnit mnohem pomaleji, než s ním spojené knihovny, runtime atd.

Mimochodem, cílová skupina uživatelů ABC měla být jiná, než je tomu u Pythonu. ABC bylo určeno pro inteligentní a bystré profesionály, kteří se ovšem nezabývají vývojem software. Měl to být jazyk pro vědce, knihovníky, chemiky a další, kteří používali počítače. Sem tam si chtěli napsat malý program, který by jim zjednodušil práci. Nebyl určen pro vývojáře, kteří by psali software používaný někým jiným.

[12:50] Otázka z publika: Byl Python vytvořen pro nějakou cílovou skupinu? Odpověď: Jazyk měl splňovat především mé vlastní požadavky. Chtěl jsem mít k dispozici implementaci jazyka, který by byl produktivnější než C a mocnější (více se podobající opravdovému programovacímu jazyku) než Bourne Shell. Cílová platforma se navíc příliš nepodobala Unixu. Takže Perl 3, který byl v té době k dispozici, nemohl být použit. A na základě své předchozí dlouhé zkušenosti s lidmi kolem ABC se mi nelíbila syntaxe Perl 3.

[13:35] (obsah slajdu, o jazyce ABC)

  • Interaktivní příkazový řádek >>> Ve skutečnosti bylo obtížné používat ABC v neinteraktivním režimu.
  • Pět mocných datových typů: seznam, tabulka, n-tice, číslo, text.
  • Ortogonalita jako důležitý princip. Schopnost vzít jakýkoliv objekt a použít pro něj známé operace.
  • Žádná omezení: hodnoty mohou být velké podle toho, jak velkou paměť máme k dispozici. (Skryj tyto implementační detaily před uživatelem. Tato omezení by neměl zavádět již programovací jazyk.)
  • Čísla vyjadřují matematické hodnoty, ne bitové vzorky.
  • Zabudován mocný aparát pro zpracování řetězců.
  • Nepoužívají se deklarace typů; proměnné se vytvářejí v okamžiku přiřazení. [16:00] Zajímavým přínosem ABC je také odvozování typů (inference). Nemusíte deklarovat typy proměnných, ale přesto se používá se statická typová kontrola, tj. v době překladu. Python má podobné vlastnosti, ale kontrola typů se neprovádí v době překladu, ale až za běhu.
  • Jednoduché řídicí konstrukce: IF, SELECT, WHILE, FOR

Nedobré věci na jazyce ABC [16:38]

Python v sobě odráží vše dobré, co se mi na ABC líbilo. Zvým způsobem odráží také vše, co se mi na ABC nelíbilo. Dá se říci, že v návrhu Pythonu jsem se snažil opravit vše, co se mi na ABC nelíbilo.

  • Monolitická implementace; těžko se přidávají nové věci.
  • Obtížná spolupráce se systémem souborů. Bylo například velmi obtížné otevřít soubor a něco z něho přečíst.
  • Používání odlišné programátorské terminologie (znovuobjevování). Používaly se pojmy jako "text", místo "řetězec", "howto" místo "procedura", "yield" místo "funkce" atd.
  • Používání aplostrofu (') v identifikátorech; klíčová slova se zapisují VELKÝMI PÍSMENY.
  • Seznam má podobu neuspořádané multimnožiny (bag); tabulky jsou seřazené. [slajd říká neuspořádaný seznam, GvR říká uspořádaný 17:57 ?]
  • Práce s malými řetězci je relativně pomalá. (Dobře implementované řetězce z hlediska asymptotické složitosti, ale velká konstanta.)
  • Přiřazení: PUT výraz IN proměnná.
  • Chybí uživatelské zpracování chyb: chyba vede k návratu na >>> vyzývací řádek.
  • Prostředí pro editaci je příliš těsně integrováno. (Jazyk ABC je stále dostupný, napsaný v C -- zkuste Google.)
  • Přitažlivý většinou pro lidi, kteří se k počítači moc nedostali. Nepodařilo se získat komunitu příznivců v tvrdém jádře unixového světa -- kvůli špatné integraci s OS.

Co jsem změnil [19:20]

  • Rozšiřitelnost se stala základním kamenem implementace.
  • Zabudovaná podpora práce se soubory; ostatní funkčnost operačního systému dostala podobu rozšíření. Zabudováno velmi dobré rozhraní pro různé funkce operačních systémů. [19:30] Jednou z částí byly například vstup/výstupní operace, jak je definuje norma jazyka C. Jde o operace dostupné všude, i když se implementace může lišit (přenositelnost). [19:42] Od začátku jsem myslel na to, že programátoři na různých platformách budou chtít psát svá rozšíření zpřístupňující vlastnosti specifického operačního systému. [20:00] To je přístup, který pythonovský přístup v základech odlišuje například od jazyka Java. Přístup Javy "zkompiluj jednou a spusť kdekoliv" vede k jakési sadě rysů představující největšího společného jmenovatele [tj. využívání jen těch rysů, které jsou dostupné na všech platformách].
  • Návrat k standardní programátorské terminologii.
  • Používání znaku podtržení v identifikátorech; klíčová slova se zapisují malými písmeny.
  • Seznam je uspořádaný, slovník je implementován jako vyhledávací tabulka (hash).
  • Optimalizace pro malé řetězce (memcpy je velmi rychlé).
  • Tradiční zápis přiřazení: proměnná = výraz
  • Přidány výjimky, try/except/finally (Modula 3)
  • Zahozeno integrované editační prostředí.
  • Přitažlivost pro unixový svět: imitace chování shellu, # pro komentáře, podpora #!, přístupk nízkoúrovňovým voláním unixového systému (ale také přenos na PC/Mac!)

Co dalšího jsem změnil [20:58]

Přidal jsem další dobré věci, které nepocházejí z jazyka ABC. A taky jsem přidal pár svých chyb.

  • Řada věci byla motivována snahou udržet projekt natolik jednoduchý, aby to zvládl jeden člověk.
  • Opuštěno odvozování typů (type inference). Místo toho zavedeno dynamické určování typů (dynamic typing).
  • Zahozeny "zjemňující" řídicí struktury.
  • Zahozena konstrukce SELECT ve prospěch if...elif...elif...else...
  • Rozlišeny číselné typy int, long a float.
  • Největší chyby:
    • 32bitový integer (předčasná optimalizace)
    • celočíselné dělení ořezává výsledek (bezmyšlenkovitá imitace chování z jazyka C)
    • o třídách a typech se uvažovalo odděleně (uživatelsky definované třídy byly zavedeny později)
    • výjimky v podobě řetězcových objektů (mechanismus výjimek je starší, než mechanismus uživatelsky definovaných tříd).

[23:20] Otázka: [k celočíselnému dělení, volná sumarizace velmi dlouhé otázky] ... dělení celých čísel matematicky sice vede k obecně racionálním výsledkům, ale na druhou stranu, při numerických výpočtech je řada algoritmů kvůli výkonnosti optimalizována právě na celočíselné dělení...

[24:50] Odpověď: Pokud skutečně chcete, aby bylo celočíselné dělení uzavřeno v oboru celých čísel, můžete [do budoucna] používat operátor "i // j" místo "i / J". Jde o speciální operátor, který ořízne výsledek. Pravděpodobně to není celá odpověď na danou otázku. Je to také otázka filosofického přístupu. Python se řídí filosofií, která dává přednost "praktickému" přístupu k řešení problémů před "teoretickým". Právě praktické problémy uživatelů vedly k rozhodnutí změnit výsledek celočíselného dělení na typ float (reálné číslo). Pokud to skutečně potřebujete, můžete si definovat vlastní číselný typ, který definuje (overload) vlastní chování operátoru dělení.

Další vlivy [25:58]

  • Lisp: first class funkce. Někteří si o Pythonu myslí, že jde o jakousi druhou reinkarnaci Lispu, což mi připadá zábavné, protože jsem Lisp nikdy pořádně neznal. Určitě jsem o něm neuvažoval při návrhu Pythonu...
  • Smalltalk: interpret bajtkódu. ... To už se spíše dá hovořit o ovlivnění Smalltalkem (interpret bajtkódu a různé implementační techniky).
  • Emacs: ukládání přeloženého bajtkódu do souboru. (Drobné ovlivnění lispem, který je vnitřním jazykem)
  • Algol-60, Algol-68, Pascal: applehood & mother pie. První jazyky, se kterými se GvR seznámil. Patří k nim i jazyk ABC, i když byl syntakticky velmi odlišný.
  • Modula-3: try/except, třída jako záznam, explicitní používání self. [27:04] Kompilátor zde neví o tom, že kompiluje třídu. Chová se, jako kdyby kompiloval funkce. Že jde o třídu se pozná jen z kontextu. První parametr, předávaný funkcím, má speciální význam odkazu na záznam objektu. Tento koncept je zcela převzat z Moduly-3.
  • UNIX: modularita; standardní interaktivní chování,#! (konstrukce z jazyka C). Převzata klíčová slova, řídicí struktury, zápis speciálních znaků v řetězcích [escape characters] a podobné věci, zápis literálů, identifikátorů, čísel, atd.
  • Icon: slices; mhohem později generátory [27:49] Osobně jej neznám, ale pracoval jsem s kolegy, kteří přenos některých vlastností tohoto jazyka zprostředkovali.
  • Perl: syntaxe regulárních výrazů
  • Tcl/Tk: Tkinter; více interpretů; sandboxing
  • Java: nové aplikační rozhraní pro vlákna, reformy v oblasti výjimek (nedávno). [28:10]

[28:15] Otázka: Odkud pochází odsazování. Odpověď: Odsazování je vypůjčeno z ABC, ale jde o starší myšlenku. Jde o přístup běžně používaný v polovině 70. let.

[28:50] Otázka: Proč nejsou regulární výrazy zabudovány přímo do jádra jazyka? Odpověď: Souvislost s ABC, který regulární výrazy nepoužíval (byl určen pro výuku začátečníků). Python původně regulární výrazy také nepodporoval z podobných důvodů. Dalším důvodem je to, že přidávání nových věcí do Pythonu formou modulů je v 9 z 10 případů jednodušší, než úpravy jádra jazyka. A protože přidání regulárních výrazů formou modulu bylo možné, neprováděly se změny přímo do jádra. Jediným kompromisem bylo zavedení nové formy zápisu řetězce [r'raw string'], u které interpret není tak agresivní při interpretaci backslash.

Další poznámky [slajd zobrazen v čase 28:23]

[30:45]

  • Proč používat explicitně self? Pochází z Modula-3.
    • self.foo: odlišuje instanční proměnnou [tj. složku objektu] od lokální proměnné
      • důležité pro překladač (potřebuje vědět, kde se má ukládat)
      • důležité pro čtenáře-člověka
    • def bar(self, arg):
      • dovoluje dívat se na funkci jako na metodu nebo naopak.
  • Odkud přišla introspekce?
    • '__dict__' tady bylo od začátku jako mechanismus pro zveřejnění implementace
  • Je Python multi-paradigmatický jazyk?
    • Stěží. Podporuje procedurální a OO programování, ale je slabý co se týká funkcionálního programování a jiných přístupů.

(Konec první části. Pokračování -- PrednaskaGvRPythonInNewYorkII)