Hlavní navigace

Clojure aneb jazyk umožňující tvorbu bezpečných vícevláknových aplikací pro JVM

12. 6. 2012
Doba čtení: 20 minut

Sdílet

V dnešní části seriálu o programovacím jazyku Java i o virtuálním stroji tohoto jazyka se seznámíme s jazykem Clojure běžícím nad JVM. Jedním z nejzajímavějších rysů Clojure je jeho zaměření na tvorbu vícevláknových aplikací bez nutnosti použití explicitně zapisovaných zámků či použití jiných synchronizačních mechanismů. Na příkladu Clojure lze ukázat, že JVM je použitelný i pro provozování vysoce paralelních aplikací.

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

8. Literály

9. Odkazy na Internetu

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):

  1. Scala Programming Language
    http://www.scala-lang.org/
  2. Run Scala in Apache Tomcat in 10 minutes
    http://www.sof­twaresecretwe­apons.com/jspwi­ki/run-scala-in-apache-tomcat-in-10-minutes
  3. Fast Web Development With Scala
    http://chaset­hedevil.blogspot­.cz/2007/09/fast-web-development-with-scala.html
  4. Top five scripting languages on the JVM
    http://www.in­foworld.com/d/de­veloper-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ř. mikropro­cesorový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/ser­verech 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:

  1. Lambda kalkul
    http://cs.wiki­pedia.org/wiki/Lam­bda_kalkul
  2. McCarthy
    „Recursive functions of symbolic expressions and their computation by machine, part I“
    1960
  3. Guy L. Steele
    „History of Scheme“
    2006, Sun Microsystems Laboratories
  4. Kolář J., Muller K.:
    „Speciální programovací jazyky“
    Praha 1981
  5. „AutoLISP Release 9, Programmer's re­ference“
    Autodesk Ltd., October 1987
  6. „AutoLISP Release 10, Programmer's re­ference“
    Autodesk Ltd., September 1988
  7. McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I.
    „LISP 1.5 Programmer's Ma­nual“
    MIT Press. ISBN 0 262 130 1 1 4
  8. 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é.

lisp01

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.go­ogle.com/p/clo­jure-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:

  1. Podpora skriptovacích jazyků v JDK6 a OpenJDK6
    http://www.ro­ot.cz/clanky/pod­pora-skriptovacich-jazyku-v-jdk6-a-openjdk6/
  2. Podpora skriptovacích jazyků v JDK6 a OpenJDK6 (2.část)
    http://www.ro­ot.cz/clanky/pod­pora-skriptovacich-jazyku-v-jdk6-a-openjdk6–2-cast/
  3. Podpora skriptovacích jazyků v JDK6 a OpenJDK6 (3.část)
    http://www.ro­ot.cz/clanky/pod­pora-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:

  1. literály
  2. symboly
  3. složené formy (v podstatě se jedná o seznamy představující volání funkce)
  4. 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):

CS24_early

user=> 100/3
100/3

… a dokonce i jako instance třídy java.math.Big­Decimal:

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

  1. Clojure home page
    http://clojure­.org/downloads
  2. Clojure – Functional Programming for the JVM
    http://java.o­ciweb.com/mar­k/clojure/arti­cle.html
  3. Clojure quick reference
    http://faustus­.webatu.com/clj-quick-ref.html
  4. 4Clojure
    http://www.4clo­jure.com/
  5. ClojureDoc
    http://clojure­docs.org/
  6. Clojure (Wikipedia EN)
    http://en.wiki­pedia.org/wiki/Clo­jure
  7. Clojure (Wikipedia CS)
    http://cs.wiki­pedia.org/wiki/Clo­jure
  8. Riastradh's Lisp Style Rules
    http://mumble­.net/~campbell/sche­me/style.txt
  9. Dynamic Languages Strike Back
    http://steve-yegge.blogspot­.cz/2008/05/dy­namic-languages-strike-back.html
  10. Scripting: Higher Level Programming for the 21st Century
    http://www.tcl­.tk/doc/scrip­ting.html
  11. Java Virtual Machine Support for Non-Java Languages
    http://docs.o­racle.com/java­se/7/docs/techno­tes/guides/vm/mul­tiple-language-support.html
  12. New JDK 7 Feature: Support for Dynamically Typed Languages in the Java Virtual Machine
    http://java.sun­.com/developer/techni­calArticles/Dyn­TypeLang/
  13. JSR 223: Scripting for the JavaTM Platform
    http://jcp.or­g/en/jsr/deta­il?id=223
  14. JSR 292: Supporting Dynamically Typed Languages on the JavaTM Platform
    http://jcp.or­g/en/jsr/deta­il?id=292
  15. Java 7: A complete invokedynamic example
    http://niklas­schlimm.blogspot­.com/2012/02/ja­va-7-complete-invokedynamic-example.html
  16. InvokeDynamic: Actually Useful?
    http://blog.he­adius.com/2007/01­/invokedynamic-actually-useful.html
  17. A First Taste of InvokeDynamic
    http://blog.he­adius.com/2008/09­/first-taste-of-invokedynamic.html
  18. Java 6 try/finally compilation without jsr/ret
    http://cliffhac­ks.blogspot.com/2008/02­/java-6-tryfinally-compilation-without.html
  19. An empirical study of Java bytecode programs
    http://www.men­deley.com/rese­arch/an-empirical-study-of-java-bytecode-programs/
  20. Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
    http://www.mo­bilefish.com/tu­torials/java/ja­va_quickguide_jvm_in­struction_set­.html
  21. The JVM Instruction Set
    http://mpdebo­er.home.xs4all­.nl/scriptie/no­de14.html
  22. Control Flow in the Java Virtual Machine
    http://www.ar­tima.com/under­thehood/flowP­.html
  23. Root.cz: Využití komprimovaných ukazatelů na objekty v JVM
    http://www.ro­ot.cz/clanky/vy­uziti-komprimovanych-ukazatelu-na-objekty-v-nbsp-jvm/
  24. Root.cz: JamVM aneb alternativa k HotSpotu nejenom pro embedded zařízení a chytré telefony
    http://www.ro­ot.cz/clanky/jam­vm-aneb-alternativa-k-hotspotu-nejenom-pro-embedded-zarizeni-tablety-a-chytre-telefony/
  25. The JavaTM Virtual Machine Specification, Second Edition
    http://java.sun­.com/docs/book­s/jvms/second_e­dition/html/VMSp­ecTOC.doc.html
  26. The class File Format
    http://java.sun­.com/docs/book­s/jvms/second_e­dition/html/Clas­sFile.doc.html
  27. javap – The Java Class File Disassembler
    http://docs.o­racle.com/java­se/1.4.2/docs/to­oldocs/window­s/javap.html
  28. javap-java-1.6.0-openjdk(1) – Linux man page
    http://linux.di­e.net/man/1/j­avap-java-1.6.0-openjdk
  29. Using javap
    http://www.ide­velopment.info/da­ta/Programmin­g/java/miscella­neous_java/Usin­g_javap.html
  30. Examine class files with the javap command
    http://www.techre­public.com/ar­ticle/examine-class-files-with-the-javap-command/5815354
  31. BCEL Home page
    http://common­s.apache.org/bcel/
  32. BCEL Manual
    http://common­s.apache.org/bcel/ma­nual.html
  33. Byte Code Engineering Library (Wikipedia)
    http://en.wiki­pedia.org/wiki/BCEL
  34. Java programming dynamics, Part 7: Bytecode engineering with BCEL
    http://www.ib­m.com/developer­works/java/li­brary/j-dyn0414/
  35. Bytecode Engineering
    http://book.chi­naunix.net/spe­cial/ebook/Co­re_Java2_Volu­me2AF/0131118269/ch13lev­1sec6.html
  36. BCEL Tutorial
    http://www.smfsup­port.com/suppor­t/java/bcel-tutorial!/
  37. ASM Home page
    http://asm.ow2­.org/
  38. Seznam nástrojů využívajících projekt ASM
    http://asm.ow2­.org/users.html
  39. ObjectWeb ASM (Wikipedia)
    http://en.wiki­pedia.org/wiki/Ob­jectWeb_ASM
  40. Java Bytecode BCEL vs ASM
    http://james.o­negoodcookie.com/2005/10­/26/java-bytecode-bcel-vs-asm/
  41. Bytecode Outline plugin for Eclipse (screenshoty + info)
    http://asm.ow2­.org/eclipse/in­dex.html
  42. aspectj (Eclipse)
    http://www.eclip­se.org/aspectj/
  43. Aspect-oriented programming (Wikipedia)
    http://en.wiki­pedia.org/wiki/As­pect_oriented_pro­gramming
  44. AspectJ (Wikipedia)
    http://en.wiki­pedia.org/wiki/As­pectJ
  45. EMMA: a free Java code coverage tool
    http://emma.sou­rceforge.net/
  46. Cobertura
    http://cobertu­ra.sourceforge­.net/
  47. FindBugs
    http://findbug­s.sourceforge­.net/
  48. GNU Classpath
    www.gnu.org/s/clas­spath/
  49. Java VMs Compared
    http://bugblog­ger.com/java-vms-compared-160/
  50. JSRs: Java Specification Requests – JSR 223: Scripting for the Java Platform
    http://www.jcp­.org/en/jsr/de­tail?id=223
  51. Scripting for the Java Platform
    http://java.sun­.com/developer/techni­calArticles/J2SE/Des­ktop/scriptin­g/
  52. Scripting for the Java Platform (Wikipedia)
    http://en.wiki­pedia.org/wiki/Scrip­ting_for_the_Ja­va_Platform
  53. Java Community Process
    http://en.wiki­pedia.org/wiki/Ja­va_Specificati­on_Request
  54. Java HotSpot VM Options
    http://www.ora­cle.com/technet­work/java/java­se/tech/vmopti­ons-jsp-140102.html
  55. Great Computer Language Shootout
    http://c2.com/cgi/wi­ki?GreatCompu­terLanguageSho­otout
  56. Java performance
    http://en.wiki­pedia.org/wiki/Ja­va_performance
  57. Trying the prototype
    http://mail.o­penjdk.java.net/pi­permail/lambda-dev/2010-August/002179.html
  58. Better closures (for Java)
    http://blogs.sun­.com/jrose/en­try/better_clo­sures
  59. Lambdas in Java: An In-Depth Analysis
    http://www.in­foq.com/articles/lam­bdas-java-analysis
  60. Class ReflectiveOpe­rationExcepti­on
    http://downlo­ad.java.net/jdk7/doc­s/api/java/lan­g/ReflectiveO­perationExcep­tion.html
  61. Proposal: Indexing access syntax for Lists and Maps
    http://mail.o­penjdk.java.net/pi­permail/coin-dev/2009-March/001108.html
  62. Proposal: Elvis and Other Null-Safe Operators
    http://mail.o­penjdk.java.net/pi­permail/coin-dev/2009-March/000047.html
  63. Java 7 : Oracle pushes a first version of closures
    http://www.bap­tiste-wicht.com/2010/05­/oracle-pushes-a-first-version-of-closures/
  64. Groovy: An agile dynamic language for the Java Platform
    http://groovy­.codehaus.org/O­perators
  65. Better Strategies for Null Handling in Java
    http://www.sli­deshare.net/Step­han.Schmidt/bet­ter-strategies-for-null-handling-in-java
  66. Control Flow in the Java Virtual Machine
    http://www.ar­tima.com/under­thehood/flowP­.html
  67. Java Virtual Machine
    http://en.wiki­pedia.org/wiki/Ja­va_virtual_machi­ne
  68. ==, .equals(), compareTo(), and compare()
    http://leepoin­t.net/notes-java/data/expres­sions/22compa­reobjects.html
  69. New JDK7 features
    http://openjdk­.java.net/pro­jects/jdk7/fe­atures/
  70. Project Coin: Bringing it to a Close(able)
    http://blogs.sun­.com/darcy/en­try/project_co­in_bring_close
  71. CloseableFinder source code
    http://blogs.sun­.com/darcy/re­source/Projec­tCoin/Closeable­Finder.java
  72. Joe Darcy blog about JDK
    http://blogs.sun­.com/darcy
  73. Java 7 – more dynamics
    http://www.bap­tiste-wicht.com/2010/04­/java-7-more-dynamics/
  74. New JDK 7 Feature: Support for Dynamically Typed Languages in the Java Virtual Machine
    http://java.sun­.com/developer/techni­calArticles/Dyn­TypeLang/index­.html

Byl pro vás článek přínosný?

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.