=============================================================== 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.
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.
- self.foo: odlišuje instanční proměnnou [tj. složku objektu] od lokální proměnné
- 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)