Obsah
1. Clojure aneb jazyk umožňující tvorbu bezpečných vícevláknových aplikací pro JVM
2. Moderní programovací jazyk, jehož kořeny sahají až do roku 1958?
3. Funkcionální programovací jazyky v době vícejádrových procesorů
4. Technologie, na nichž je postaven programovací jazyk Clojure
5. Malá odbočka: historie vzniku programovacího jazyka LISP a smyčky REPL
6. Způsoby spuštění REPL jazyka Clojure i další varianty jeho použití v JVM
7. Základní prvky programovacího jazyka Clojure
1. Clojure aneb jazyk umožňující tvorbu bezpečných vícevláknových aplikací pro JVM
V předchozích částech seriálu o programovacím jazyku Java i o virtuálním stroji tohoto jazyka (JVM) jsme si popsali strukturu bajtkódu i vlastní instrukční soubor JVM. Minule jsme se navíc seznámili s novou instrukcí nazvanou příhodně invokedynamic, která byla do instrukčního souboru JVM přidána v rámci různých změn a vylepšení v JDK 7 především z důvodu lepší podpory překladačů dynamicky typovaných programovacích jazyků (samotný překladač Javy tuto instrukci nepoužívá a ani ji nepotřebuje používat). Taktéž jsme si řekli, že ani virtuální stroj Javy ani jeho instrukční soubor vlastně nikde striktně nepředpokládají, že JVM bude spouštět pouze bajtkód získaný překladem javovských programů – ve specifikaci JVM je na několika místech explicitně zmíněn předpoklad, že nad virtuálním strojem Javy budou provozovány i další programovací jazyky umožňující přímý či nepřímý překlad do bajtkódu.
Pravděpodobně nejznámějším příkladem takového programovacího jazyka je Scala, která nabízí prakticky bezproblémovou spolupráci mezi částmi kódu psanými ve Scale a zbytkem aplikace psaným v Javě (popř. jsou některé projekty psané pouze ve Scale, ovšem provozovány jsou například na ryze javovských serverech – Tomcat, Jetty atd.). Díky tomu, že zdrojové kódy psané ve Scale jsou přímo překládány do bajtkódu, získali tvůrci tohoto programovacího jazyka prakticky zadarmo veškeré vymoženosti, které virtuální stroj Javy (či přesněji řečeno celé JRE) poskytuje – od poměrně pečlivé kontroly bajtkódu při jeho načítání do virtuálního stroje přes použití správců paměti a JIT překladačů (Just in Time Compiler) až po možnost využití rozsáhlých standardních knihoven J2SE a samozřejmě taktéž mnoha dalších knihoven a frameworků, které jsou pro JVM dostupné. Ovšem Scala samozřejmě není jediným programovacím jazykem, který díky překladu do bajtkódu umožňuje využít prakticky veškerého potenciálu JVM/JRE.
Odkazy na další informační zdroje (týkající se většinou jazyka Scala):
- Scala Programming Language
http://www.scala-lang.org/ - Run Scala in Apache Tomcat in 10 minutes
http://www.softwaresecretweapons.com/jspwiki/run-scala-in-apache-tomcat-in-10-minutes - Fast Web Development With Scala
http://chasethedevil.blogspot.cz/2007/09/fast-web-development-with-scala.html - Top five scripting languages on the JVM
http://www.infoworld.com/d/developer-world/top-five-scripting-languages-the-jvm-855
2. Moderní programovací jazyk, jehož kořeny sahají až do roku 1958?
Z dalších překladačů programovacích jazyků, které pro virtuální stroj Javy vznikly, je podle mého názoru nejzajímavějším jazykem a současně i jazykem s velkým potenciálem pro budoucnost programovací jazyk s názvem Clojure, jehož autorem a dodnes nejaktivnějším vývojářem je Rich Hickey. Samotný název tohoto jazyka vznikl vložením písmene „j“ (Java/JVM) do slova closure (toto slovo se používá ve smyslu „lexikální uzávěr“ – důležitá abstrakce používaná ve funkcionálních programovacích jazycích). V následujících kapitolách se alespoň ve stručnosti seznámíme s nejzajímavějšími prvky tohoto programovacího jazyka. Hned na úvod je nutné si na rovinu říct, že velká část předností a pro mnohé vývojáře taktéž záporů programovacího jazyka Clojure vychází z toho, že se jedná o programovací jazyk, jehož syntaxe a sémantika do značné míry vychází z LISPu a Scheme, tedy jazyků známých především tím, že se v programech v nich psaných používá nadměrné množství kulatých závorek.
Obrázek 1: Hra Abuse je z velké části napsána v LISPu – nízkoúrovňové části používají nativní knihovny (na Linuxu například SDL), ovšem veškerá herní logika je skutečně v LISPu a s troškou vůle a volného času lze z Abuse vytvořit zcela odlišnou hru. Zdánlivá malá výkonnost LISPu se zde neprojevuje, protože Abuse lze bez problémů hrát i na stařičkém počítači s mikroprocesorem 80486DX2.
Mnoho čtenářů si nyní s velkou pravděpodobností klade otázku, jestli vůbec má smysl si něco začínat s programovacím jazykem odvozeným od LISPu, jehož první verze vznikla už před neuvěřitelnými 54 lety, konkrétně v roce 1958 (jedná se tedy po Fortranu o druhý nejstarší stále používaný vysokoúrovňový programovací jazyk). Může vůbec jazyk postavený na tak „starých“ myšlenkách něco nabídnout současné IT? Kupodivu to smysl má (a dokonce čím dál tím větší), protože kromě již zmíněné přemíry kulatých závorek nabízí různé dialekty LISPu programátorům i poměrně velké množství předností. Clojure k těmto přednostem přidává zejména možnost snadného vytváření vícevláknových aplikací, a to bez nutnosti explicitního používání zámků (locks) či dalších synchronizačních prostředků. Clojure se tak řadí k takovým jazykům jako je spíše akademicky orientovaný Haskell či naopak na praxi orientovaný programovací jazyk Erlang.
Obrázek 2: Ukázka části zdrojového kódu hry Abuse.
3. Funkcionální programovací jazyky v době vícejádrových procesorů
Pravděpodobně nebude velkým překvapením zjištění, že jak Clojure, tak i již zmíněné jazyky LISP, Scheme, Haskell a Erlang patří mezi skupinu funkcionálních jazyků, tj. programovacích jazyků vycházejících z teorie takzvaného λ-kalkulu, jehož autorem je Alonzo Church (na první návrhy LISPu se dokonce můžeme dívat jako na způsob zápisu λ-kalkulu, pro nějž jen tak mimochodem existuje mechanismus vyhodnocování jednotlivých λ výrazů; taktéž se tím vysvětluje přítomnost znaku lambda v logu jazyka Clojure). V době, kdy byl publikován návrh programovacího jazyka LISP, se v akademické sféře předpokládalo, že další vývoj programovacích jazyků a s nimi souvisejících technologií (typový systém, interpretry, překladače, správci paměti) se bude ubírat právě cestou LISPU, přesněji řečeno cestou funkcionálních jazyků. Toto očekávání do jisté míry souviselo s vírou v prudký rozvoj umělé inteligence a spolu s pozdějším větším či menším neúspěchem mnoha projektů zaměřených na vývoj umělé inteligence poněkud poklesl i zájem o LISP a jeho dialekty.
Obrázek 3: Logo jazyka Clojure s jasně viditelným písmenem lambda.
Potom se po dlouhou dobu zdálo, že úspěch budou slavit dnes vlastně již „klasické“ jazyky takzvané algolské větve, které do značné míry kopírují technologii počítače, na nichž jsou překladače těchto jazyků provozovány. Poměrně zásadní změna v názorech na další vývoj programovacích jazyků přichází vlastně až v posledních letech, kdy se výpočetní výkon počítačů zvyšuje mj. i zvětšováním počtu mikroprocesorů, popř. mikroprocesorových jader. Mikroprocesory se dvěma jádry jsou dnes již naprostým standardem a u výkonnějších počítačů není neobvyklé se setkat s osmi, šestnácti atd. jádry. Aby bylo možné psát výkonné aplikace i pro počítače s velkým množstvím procesorových jader, je nutné, aby tyto aplikace vytvářely množství vzájemně komunikujících procesů nebo vláken. Kritickým prvkem se pak stává vzájemná komunikace a synchronizace mezi procesy/jádry, která je však v mnoha programovacích jazycích dosti problematická a potenciálně i nebezpečná (nehledě na složitosti vyplývající z obtížnějšího ladění těchto aplikací).
Zajímavé je, že dokonce ani Java tuto problematiku nedokáže uspokojivě vyřešit, protože explicitní synchronizace s využitím synchronizovaných metod či bloků je pro skutečně „paralelní“ aplikace složitá a výjimkou nejsou ani deadlocky objevené pozdě, tj. až na počítačích/serverech zákazníka. A právě v oblasti paralelních aplikací začínají programátoři znovu objevovat kouzlo funkcionálních jazyků, dnes především Erlangu (který má za sebou množství komerčně úspěšných projektů) a taktéž Clojure.
Odkazy na další informační zdroje:
- Lambda kalkul
http://cs.wikipedia.org/wiki/Lambda_kalkul - McCarthy
„Recursive functions of symbolic expressions and their computation by machine, part I“
1960 - Guy L. Steele
„History of Scheme“
2006, Sun Microsystems Laboratories - Kolář J., Muller K.:
„Speciální programovací jazyky“
Praha 1981 - „AutoLISP Release 9, Programmer's reference“
Autodesk Ltd., October 1987 - „AutoLISP Release 10, Programmer's reference“
Autodesk Ltd., September 1988 - McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I.
„LISP 1.5 Programmer's Manual“
MIT Press. ISBN 0 262 130 1 1 4 - Carl Hewitt; Peter Bishop and Richard Steiger
„A Universal Modular Actor Formalism for Artificial Intelligence“
1973
4. Technologie, na nichž je postaven programovací jazyk Clojure
Základní vlastnosti jazyka Clojure vychází z technologií, které byly vytvořeny již před více než padesáti roky v rámci vývoje programovacího jazyka LISP. Ovšem tyto technologie a postupy byly upraveny tak, aby se dobře přizpůsobily současným technologiím – především just-in-time překladačům pracujícím s bajtkódem, správcům paměti dosti odlišným od poměrně naivních správců založených na počítání referencí atd. Z pohledu programátora je programovací jazyk Clojure, stejně jako LISP a mnoho dalších funkcionálních jazyků, vybaven takzvanou smyčkou REPL (Read-Evaluate-Print-Loop), tedy interaktivním prostředím, v němž je možné zapisovat jednotlivé výrazy, které jsou (alespoň zdánlivě) ihned vykonány a jejichž výsledek je vypsán na standardní výstup. Pomocí REPL lze vytvářet nové programy (i když zde je většinou vhodnější se spokojit s vhodným integrovaným vývojovým prostředím s možností spuštění REPL), ladit programy, popř. se dokonce – vzdáleně – připojit k běžící aplikaci a bez nutnosti jejího restartu v ní opravit chybu (a na některé zákazníky skutečně magické sousloví „zero downtime“ působí velmi dobře :-).
Smyčku REPL si většinou spojujeme především se skriptovacími jazyky, které jsou prováděny interpretrem (příkladem může být BASH a nepřímo též Basic), ovšem ústředním prvkem jazyka Clojure je ve skutečnosti jeho překladač. Může se to možná zdát překvapivé, ale programy psané v Clojure jsou skutečně překládány, ale nikoli přímo do nativního strojového kódu procesoru, na němž JVM běží, ale do regulárního bajtkódu, který je ihned po překladu dostupný i z Javy (to v případě, že by se například funkce napsaná v Clojure měla ihned volat z javovského programu). To s sebou přináší poměrně značné množství výhod, protože překladač Clojure do bajtkódu může být poměrně přímočarý a jednoduchý, podobně jako překladač Javy do bajtkódu – v obou případech se prakticky neprovádí žádné optimalizace, protože ty jsou již záležitostí just-in-time překladače. Výsledkem využití bajtkódu je překvapivě rychlý běh aplikací vytvořených v Clojure, dobrá a přímočará integrace se samotnou Javou, možnost použití prakticky jakýchkoli profilovacích, testovacích aj. nástrojů vytvořených pro Javu atd.
Použití sousloví „smyčka REPL“ není z hlediska gramatiky příliš správné, protože už písmeno „L“ ve zkratce „REPL“ znamená smyčku (viz též časté prohřešky typu LED dioda či LCD displej). Nicméně použití jiných opisů mi přišlo poměrně násilné, takže se za tuto vlastně záměrnou chybu omlouvám.
5. Malá odbočka: historie vzniku programovacího jazyka LISP a smyčky REPL
Syntaxe jazyka LISP je již po 50 let zdrojem inspirace pro autory vtipů
Možná nebude na škodu i do článku o zcela moderním programovacím jazyce vložit krátkou historickou vsuvku o LISPu. Historie programovacího jazyka LISP je velmi dlouhá, neboť se jedná o jeden z nejstarších vyšších programovacích jazyků vůbec. Autorem teoretického návrhu tohoto jazyka je John McCarthy, který se již v roce 1956 připojil k týmu, jehož úkolem bylo navrhnout algebraický programovací jazyk umožňující zpracování seznamů, jenž by byl vhodný pro vývoj systémů umělé inteligence – AI (zatímco dnes jsou „v kurzu“ enterprise systémy, popř. WEB 2.0 či „cloud“, v padesátých a šedesátých letech minulého století se jednalo o umělou inteligenci a expertní systémy). McCarthy navrhl, aby se fakta o okolním světě (která může AI při své činnosti použít) reprezentovala formou vět ve vhodně strukturovaném formálním jazyce. Posléze se ukázalo, že je výhodné reprezentovat jednotlivé věty formou seznamů. McCarthy myšlenku jazyka vhodného pro AI rozpracoval dále – odklonil se například od infixové notace zápisu algebraických výrazů, protože naprogramování některých manipulací s těmito výrazy (derivace, integrace, zjednodušení výrazů, logická dedukce) bylo zbytečně složité.
Obrázek 4: Na tomto grafu evoluce programovacích jazyků můžeme najít prarodiče mnoha dodnes používaných programovacích jazyků, včetně LISPu.
Následně McCarthy ve svých teoretických pracích (vznikajících v průběhu let 1957 a 1958) ukázal, že je možné pomocí několika poměrně jednoduchých operací (a notací pro zápis funkcí) vytvořit programovací jazyk, který je turingovsky kompletní (tj. jeho výpočetní mocnost je ekvivalentní Turingovu stroji), ale zápis algoritmů v tomto jazyce je mnohem jednodušší než zápis pravidel pro Turingův stroj. Tento jazyk, jenž byl z velké části založen na již zmíněném Lambda kalkulu, obsahoval možnost vytváření rekurzivních funkcí (což byl významný rozdíl například oproti tehdejší verzi FORTRANU), podporoval použití funkcí jako argumentů jiných funkcí, podmíněné výrazy (jedna z variant takzvané speciální formy), funkce pro manipulaci se seznamy a v neposlední řadě také funkci eval. Na McCarthovu teoretickou práci navázal S. R. Russell, který si uvědomil, že samotná funkce eval, pokud by byla implementována na nějakém počítači, může sloužit jako základ plnohodnotného interpretru jazyka LISP (interpretr LISPu se někdy též označuje taktéž již mnohokrát zmíněnou zkratkou REPL: Read-Evaluate-Print-Loop, tj. interpretr ve smyčce načítá jednotlivé výrazy, vyhodnocuje je a následně tiskne jejich výslednou hodnotu). Russell skutečně celou smyčku REPL implementoval – tímto způsobem se zrodila první reálná verze LISPu.
6. Způsoby spuštění REPL jazyka Clojure i další varianty jeho použití v JVM
V této kapitole se seznámíme se třemi základními postupy, jakými lze překladač jazyka Clojure využít. Nejjednodušší je využití smyčky REPL tohoto programovacího jazyka, která se spouští a následně používá velmi snadno. Postačuje si ze stránek Clojure stáhnout poslední stabilní verzi tohoto jazyka, což je jediný soubor nazvaný clojure-1.4.0.zip (současná verze). Po rozbalení tohoto archivu získáme mj. i Java archiv clojure-1.4.0.jar. V tomto souboru je uložen překladač, všechny podpůrné knihovny jazyka i samotný REPL. Již z koncovky názvu tohoto souboru je patrné, že se skutečně jedná o klasický Java archiv, který lze využít několika způsoby. Nejjednodušší způsob spočívá ve spuštění interaktivního prostředí představovaného smyčkou REPL. Na příkazovou řádku postačí zadat:
java -jar clojure-1.4.0.jar
Pro první seznamování s jazykem Clojure je využití smyčky REPL dostatečné, ovšem v praxi se spíše setkáme s potřebou spouštět aplikace, jejichž části jsou psané v Javě a částečně v Clojure a které tedy vyžadují i v runtime podporu tohoto jazyka (například pro dynamický překlad kódu). V tomto případě postačuje aplikaci spustit běžným postupem, ovšem s tím rozšířením, že na CLASSPATH musí být uvedena cesta k Java archivu obsahujícího Clojure:
java -cp .:clojure-1.4.0.jar MyApp.Main
Některé aplikace navíc přistupují ke „skriptům“ nikoli přes nějaké proprietární aplikační programové rozhraní vytvořené tvůrci daného skriptovacího jazyka, ale snaží se namísto toho použít univerzální rozhraní specifikované v JSR 223: Scripting for the Java Platform. S tímto standardním rozhraním dostupným přímo v JRE jsme se již v tomto seriálu setkali, viz též odkazy uvedené na konci této kapitoly. Pokud je nutné volat části kódu napsané v jazyku Clojure pomocí rozhraní definovaného v JSR 223, musí se kromě archivu clojure-1.4.0.jar stáhnout i archiv clojure-jsr223.jar ze stránky http://code.google.com/p/clojure-jsr223/ a i ten se musí umístit na CLASSPATH:
java -cp .:clojure-1.4.0.jar:clojure-jsr223.jar MyApp.Main
Odkazy na další informační zdroje o JSR 223:
- Podpora skriptovacích jazyků v JDK6 a OpenJDK6
http://www.root.cz/clanky/podpora-skriptovacich-jazyku-v-jdk6-a-openjdk6/ - Podpora skriptovacích jazyků v JDK6 a OpenJDK6 (2.část)
http://www.root.cz/clanky/podpora-skriptovacich-jazyku-v-jdk6-a-openjdk6–2-cast/ - Podpora skriptovacích jazyků v JDK6 a OpenJDK6 (3.část)
http://www.root.cz/clanky/podpora-skriptovacich-jazyku-v-jdk6-a-openjdk6–3-cast/
7. Základní prvky programovacího jazyka Clojure
Nyní se již (konečně!) můžeme seznámit se základními prvky programovacího jazyka Clojure. Všechny příklady, které zde budou ukázány, jsou spouštěny interaktivně ze smyčky REPL, což znamená, že každý výraz je nejprve načten (read), vyhodnocen (evaluate), posléze je jeho výsledek vypsán na standardní výstup (print) a následně je očekáváno zadání dalšího výrazu (loop). Všechny dále uvedené výrazy jsou jednořádkové, takže na prvním řádku je vypsán vlastní výraz (tak jak má být opsán do konzole) a na řádku druhém výsledek tohoto výrazu. V předchozích větách jsme sice pro jednoduchost používali slovo „výraz“ odpovídající spíše jazykům typu Céčka či Javy, ovšem v Clojure je, podobně jako v LISPu či Scheme, základním uceleným prvkem programu takzvaná forma (form). Právě formy se postupně zpracovávají ve smyčce REPL a REPL taktéž kontroluje, zda uživatel skutečně zadal validní formu. V programovacím jazyku Clojure existují čtyři základní typy forem:
- literály
- symboly
- složené formy (v podstatě se jedná o seznamy představující volání funkce)
- speciální formy (podobají se složeným formám, ale interně se vyhodnocují odlišným způsobem)
8. Literály
Nejjednodušším typem formy jsou literály, protože ty se v REPL vyhodnocují samy na sebe. Na literály se můžeme dívat jako na konstanty primitivního datového typu, mezi které v programovacím jazyce Clojure patří především čísla (k dispozici jsou různé formy reprezentace), znaky, řetězce a pravdivostní hodnoty. Nyní si ukážeme několik příkladů, které naznačí, jak s literály pracuje REPL a tudíž i samotný programovací jazyk Clojure:
Řetězec je prostě… řetězec:
user=> "Hello world!" "Hello world!"
Důležité je, že řetězce jsou – podobně jako v Javě – konstantní a tudíž i neměnné, což sice v některých případech může vést k tvorbě neefektivních operací, kterým se však lze v Clojure většinou zcela vyhnout. To, že jsou řetězce neměnné však zjednodušuje tvorbu bezpečných vícevláknových aplikací, řetězce lze využívat jako klíče do asociativních polí atd. atd., takže přednosti většinou převažují nad zápory.
Použití literálů představujících pravdivostní hodnoty asi nikoho nepřekvapí:
user=> true true user=> false false
Číselné literály jsou již mnohem zajímavější, protože čísla lze reprezentovat různým způsobem, například:
…jako celé číslo (odpovídající konvencím zápisu podle Céčka, C++ či Javy):
user=> 42 42
user=> 0x2a 42
user=> 052 42
… jako celé číslo se zadáním základu číselné soustavy (před r může být uvedeno číslo 2 až 36):
user=> 2r101010 42
user=> 10r42 42
user=> 16r2a 42
user=> 36r16 42
… jako číslo reálné odpovídající normě IEEE 754:
user=> 42.0 42.0
… jako zlomek (opět je zde vidět návaznost na LISP):
user=> 100/3 100/3
… a dokonce i jako instance třídy java.math.BigDecimal:
user=> 123456789123456789123456789M 123456789123456789123456789M
Popis dalších tří typů forem programovacího jazyka Clojure bude uveden až v navazující části tohoto seriálu. Tam se taktéž zmíníme o tom, jak je možné, že v tomto jazyku lze relativně snadno naprogramovat bezpečné vícevláknové aplikace – řeč bude o neměnných (imutable) datových typech, agentech a transakční paměti, což jsou poměrně zajímavé a ve většině dalších programovacích jazyků prakticky neznámé technologie.
9. Odkazy na Internetu
- Clojure home page
http://clojure.org/downloads - Clojure – Functional Programming for the JVM
http://java.ociweb.com/mark/clojure/article.html - Clojure quick reference
http://faustus.webatu.com/clj-quick-ref.html - 4Clojure
http://www.4clojure.com/ - ClojureDoc
http://clojuredocs.org/ - Clojure (Wikipedia EN)
http://en.wikipedia.org/wiki/Clojure - Clojure (Wikipedia CS)
http://cs.wikipedia.org/wiki/Clojure - Riastradh's Lisp Style Rules
http://mumble.net/~campbell/scheme/style.txt - Dynamic Languages Strike Back
http://steve-yegge.blogspot.cz/2008/05/dynamic-languages-strike-back.html - Scripting: Higher Level Programming for the 21st Century
http://www.tcl.tk/doc/scripting.html - Java Virtual Machine Support for Non-Java Languages
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/multiple-language-support.html - New JDK 7 Feature: Support for Dynamically Typed Languages in the Java Virtual Machine
http://java.sun.com/developer/technicalArticles/DynTypeLang/ - JSR 223: Scripting for the JavaTM Platform
http://jcp.org/en/jsr/detail?id=223 - JSR 292: Supporting Dynamically Typed Languages on the JavaTM Platform
http://jcp.org/en/jsr/detail?id=292 - Java 7: A complete invokedynamic example
http://niklasschlimm.blogspot.com/2012/02/java-7-complete-invokedynamic-example.html - InvokeDynamic: Actually Useful?
http://blog.headius.com/2007/01/invokedynamic-actually-useful.html - A First Taste of InvokeDynamic
http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html - Java 6 try/finally compilation without jsr/ret
http://cliffhacks.blogspot.com/2008/02/java-6-tryfinally-compilation-without.html - An empirical study of Java bytecode programs
http://www.mendeley.com/research/an-empirical-study-of-java-bytecode-programs/ - Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
http://www.mobilefish.com/tutorials/java/java_quickguide_jvm_instruction_set.html - The JVM Instruction Set
http://mpdeboer.home.xs4all.nl/scriptie/node14.html - Control Flow in the Java Virtual Machine
http://www.artima.com/underthehood/flowP.html - Root.cz: Využití komprimovaných ukazatelů na objekty v JVM
http://www.root.cz/clanky/vyuziti-komprimovanych-ukazatelu-na-objekty-v-nbsp-jvm/ - Root.cz: JamVM aneb alternativa k HotSpotu nejenom pro embedded zařízení a chytré telefony
http://www.root.cz/clanky/jamvm-aneb-alternativa-k-hotspotu-nejenom-pro-embedded-zarizeni-tablety-a-chytre-telefony/ - The JavaTM Virtual Machine Specification, Second Edition
http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html - The class File Format
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html - javap – The Java Class File Disassembler
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javap.html - javap-java-1.6.0-openjdk(1) – Linux man page
http://linux.die.net/man/1/javap-java-1.6.0-openjdk - Using javap
http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_javap.html - Examine class files with the javap command
http://www.techrepublic.com/article/examine-class-files-with-the-javap-command/5815354 - BCEL Home page
http://commons.apache.org/bcel/ - BCEL Manual
http://commons.apache.org/bcel/manual.html - Byte Code Engineering Library (Wikipedia)
http://en.wikipedia.org/wiki/BCEL - Java programming dynamics, Part 7: Bytecode engineering with BCEL
http://www.ibm.com/developerworks/java/library/j-dyn0414/ - Bytecode Engineering
http://book.chinaunix.net/special/ebook/Core_Java2_Volume2AF/0131118269/ch13lev1sec6.html - BCEL Tutorial
http://www.smfsupport.com/support/java/bcel-tutorial!/ - ASM Home page
http://asm.ow2.org/ - Seznam nástrojů využívajících projekt ASM
http://asm.ow2.org/users.html - ObjectWeb ASM (Wikipedia)
http://en.wikipedia.org/wiki/ObjectWeb_ASM - Java Bytecode BCEL vs ASM
http://james.onegoodcookie.com/2005/10/26/java-bytecode-bcel-vs-asm/ - Bytecode Outline plugin for Eclipse (screenshoty + info)
http://asm.ow2.org/eclipse/index.html - aspectj (Eclipse)
http://www.eclipse.org/aspectj/ - Aspect-oriented programming (Wikipedia)
http://en.wikipedia.org/wiki/Aspect_oriented_programming - AspectJ (Wikipedia)
http://en.wikipedia.org/wiki/AspectJ - EMMA: a free Java code coverage tool
http://emma.sourceforge.net/ - Cobertura
http://cobertura.sourceforge.net/ - FindBugs
http://findbugs.sourceforge.net/ - GNU Classpath
www.gnu.org/s/classpath/ - Java VMs Compared
http://bugblogger.com/java-vms-compared-160/ - JSRs: Java Specification Requests – JSR 223: Scripting for the Java Platform
http://www.jcp.org/en/jsr/detail?id=223 - Scripting for the Java Platform
http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/ - Scripting for the Java Platform (Wikipedia)
http://en.wikipedia.org/wiki/Scripting_for_the_Java_Platform - Java Community Process
http://en.wikipedia.org/wiki/Java_Specification_Request - Java HotSpot VM Options
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html - Great Computer Language Shootout
http://c2.com/cgi/wiki?GreatComputerLanguageShootout - Java performance
http://en.wikipedia.org/wiki/Java_performance - Trying the prototype
http://mail.openjdk.java.net/pipermail/lambda-dev/2010-August/002179.html - Better closures (for Java)
http://blogs.sun.com/jrose/entry/better_closures - Lambdas in Java: An In-Depth Analysis
http://www.infoq.com/articles/lambdas-java-analysis - Class ReflectiveOperationException
http://download.java.net/jdk7/docs/api/java/lang/ReflectiveOperationException.html - Proposal: Indexing access syntax for Lists and Maps
http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001108.html - Proposal: Elvis and Other Null-Safe Operators
http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000047.html - Java 7 : Oracle pushes a first version of closures
http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-of-closures/ - Groovy: An agile dynamic language for the Java Platform
http://groovy.codehaus.org/Operators - Better Strategies for Null Handling in Java
http://www.slideshare.net/Stephan.Schmidt/better-strategies-for-null-handling-in-java - Control Flow in the Java Virtual Machine
http://www.artima.com/underthehood/flowP.html - Java Virtual Machine
http://en.wikipedia.org/wiki/Java_virtual_machine - ==, .equals(), compareTo(), and compare()
http://leepoint.net/notes-java/data/expressions/22compareobjects.html - New JDK7 features
http://openjdk.java.net/projects/jdk7/features/ - Project Coin: Bringing it to a Close(able)
http://blogs.sun.com/darcy/entry/project_coin_bring_close - CloseableFinder source code
http://blogs.sun.com/darcy/resource/ProjectCoin/CloseableFinder.java - Joe Darcy blog about JDK
http://blogs.sun.com/darcy - Java 7 – more dynamics
http://www.baptiste-wicht.com/2010/04/java-7-more-dynamics/ - New JDK 7 Feature: Support for Dynamically Typed Languages in the Java Virtual Machine
http://java.sun.com/developer/technicalArticles/DynTypeLang/index.html