5. dubna 2017

Kniha Living Clojure

Jsem beznadějný čtenář knih. Musím denně číst a ačkoliv jsou dnes k dispozici tuny textů v různých formách, mě nejvíc vyhovují knihy.

Jedinou úlitbou modernosti je, že pro odbornou literaturu mi více vyhovují ty digitální. Přece jenom - do Kindlu se toho vejde kupa a zastaralé vydání vám nepřekáží v reálném světě.

Back to the Future

Ani nevím, co mě to cvrnklo přes nos, ale po pětileté přestávce se vracím ke Clojure. Pět let je v softwarovém inženýrství dlouhá doba. Technologie můžou zaniknout, či se nečekaně rozvinout, nebo nabrat úplně jiný směr. A těší mě, že Clojure stále rozkvétá.

Říkal jsem si - jak se do toho zase dostat? No dobře, je to řečnická otázka. Spíš jsem si říkal, kterou knihu si vybrat? Když jsem s Clojure začínal, byla na trhu jediná kniha - Programming Clojure od @StuartHalloway. Byla to tehdy bible Clojure. A možná ještě je - letos vyjde třetí edice!

Udělal jsem si seznam a jako první volbu jsem hodně zvažoval oceňované Joy of Clojure, jejíž první edici jsem kdysi nedočetl. Nakonec ale převážila náhoda. (Mimochodem, kdyby vás ten seznam zajímal, najdete ho u mne na Goodreads. Nebo ve webové verzi zaskrolujte po pravé straně dolů.)

Gigasquid!

Že jsem zase vlítnul do Clojure je více méně náhoda. Nebo osud. Minulý podzim jsem se byl po čase podívat na Java konferenci - český GeeCON - a tam jsem potkal Carin Meier, aka @Gigasquid. (Už jsem o tom psal na svém druhém blogu - GeeCON Prague 2016, den 2.)

Carin stojí za to sledovat. Kromě výše a níže zmíněné knihy, pracuje v Cognitectu. Ano, v té firmě, kde se koncentruje Clojure smetánka (posuďte sami), včetně polo-boha Riche Hickeyho.

Pokud budete mít možnost, určitě si s Carin popovídejte. Zvládl jsem to i já, zavilý introvert. Zakecal jsem se s ní tak moc, až jsem v podstatě prošvihnul následnou přednášku.

Alice in Wanderland

No dobře, to bylo keců... co ta kniha? Je dobrá, dal jsem jí na Goodreads 5 hvězd. Samozřejmě, v daném kontextu - je to dobrá kniha pro začátečníky, nebo pro někoho, kdo si potřebuje po čase Clojure oživit.

Kniha prochází všechny základní témata, která byste v učebnici čekali a skládá je v rozumném pořadí:
  • Kolekce a sekvence
  • Funkcionální programování
  • Stav a konkurence
  • Java interoperabilita
  • Leiningen a Clojure projekt
  • Asynchronni komunikace s core.async
  • Clojure web applikace
  • Makra
Napsáno pěkně, stručně, přehledně. Kromě toho, ale přináší druhá část knihy tréninkový program: Clojure v 7 týdnech.

Jak píše Carin v úvodu, učení se nového jazyka má silné paralely, jako když chcete zčista jasna začít běhat: důležitá je motivace, pravidelnost a... nepřetrénovat se.

Ohledně běhání, na webu je dnes spousta tréninkových plánů od 5 kilometrů až po maraton. Carin k tomu přistupuje obdobně - začít zvolna a postupně navyšovat objemy a obtížnost.

Prvních pár týdnů jde o řešení problémů na 4clojure. Pak se přesuneme na GitHub, kde má Carin několik kata, inspirovaných příběhem Alenky v říši divů: wonderland-clojure-katas. Poslední týden je pak věnovaný deploymentu Clojure aplikace na Heroku.

A je to! Kniha je přečtená a vy jste fluent v Clojure :-)  No, tak jednoduché to není. Ale je to dobrý začátek. Jeden z možných.

25. března 2017

Clojure concurrency: Vars

Významnou vlastností Clojure jsou neměnitelné datové struktury. Je to taková dvojsečná vlastnost (i když benefity výrazně převažují). Na jednu stranu to vývoj zjednodušuje, protože se nemusíme bát, že se nám data změní pod rukama.

Nadruhou stranu vyvstává otázka, jak s neměnitelnými daty pracovat - nic v našem světě není neměnné (a všechno jednou pomine). Jak tedy Clojure řeší změnu stavu a s tím související konkurenci?

K dispozici jsou čtyři mechanizmy, jak měnit stav:
  • Vars jako globální úložiště, pro eventuální per-thread změny.
  • Atoms pro synchronní, nekoordinované změny.
  • Refs pro synchronní, v transakci koordinované změny.
  • Agents pro asynchronní, nekoordinované změny.
Postupně bych se chtěl podívat na všechny způsoby, ale dnes začneme tím nejjednodušším, čemu se žádný začátečník v Clojure nevyhne.

Vars

Var je způsob, jakým Clojure odkazuje na úložiště. Toto úložiště obsahuje "standardní", neměnná data. Var, ale můžeme dočasně přesměrovat na jiné úložiště. Podstatnou vlastností je, že toto dočasné přesměrování - binding - je vidět jenom v rámci aktuálního vlákna, ostatní vlákna vidí pořád původní hodnotu.

Statické Vars

Klasické Var se vytvoří speciálním formem def: (def x 42). Takto definováno, je Var statické - pokud bychom ho chtěli svázat s jiným úložištěm, vyhodí Clojure výjimku IllegalStateException.


Dynamické Vars

Pokud chceme, aby Var ukazovalo na jiné úložiště, musíme ho explicitně definovat jako dynamické pomocí instrukce ^:dynamic. Samotné přesměrování se provádí makrem binding. Po dobu trvání bloku binding směřuje Var na nové úložiště, aby se po jeho skončení vrátilo ke své původní hodnotě.

Dle konvence se dynamické Vars uzavírají do *earmuffs*. Označují se tak věci, určené pro re-binding.


Vars jsou globální

Vars jsou globální - viditelné pro všechny thready. Pokud tedy vytvoříme Var v jiném vlákně, je dosažitelné také ze všech ostatních vláken.

V následujícím příkladu vytvoříme Var v jiném vlákně pomocí makra future:


Namespace

V rámci namespace, v němž byly vytvořeny, jsou Vars přístupné svým názvem. Pokud se přepneme do jiného namespacu, je potřeba na Var odkazovat plně kvalifikovaným názvem, nebo ho "naimportovat" z původního namespace pomocí funkce refer.


Funkce jsou také Vars

Ve Vars se neukládají jenom data, ale také funkce. Všechno výše napsané tedy platí pro funkce úplně stejně, včetně toho, že je můžeme dynamicky re-bindovat.

To může být zajímavý mechanismus, jak v runtimu dynamicky měnit chování funkcí. Nicméně, užívejte s mírou - jazyk to umožňuje, ale je to výjmečné řešení.


A kde je ta konkurence?

Se samotnými Vars si moc konkurentního programování neužijeme. Je to ale základní stavební kámen, od kterého se odvíjejí ostatní způsoby. Konec konců, všechny v úvodu zmíněné mechanizmy - Atomy, Refs a Agenti - jsou ve výsledku uloženy ve Vars.

Související články

  • TBD: Clojure concurrency: Atoms
  • TBD: Clojure concurrency: Refs
  • TBD: Clojure concurrency: Agents

Starší související články

18. března 2017

Catalanova čísla a syntax highlighting

Je to téměř 5 let, co jsem naposled napsal něco na tento blog. Ale doufám, že se to teď změní - moje láska ke Clojure opět propukla s neztenčenou silou a tak snad ponese nějaké užitečné ovoce.

Chvilku ale potrvá, než uvedu blog do použitelného stavu, takže začnu takovým zahřívacím tématem. Tedy, dvěma tématy - sice to není úplně fér, ale vrazil jsem do titulku dva nesouvisející motivy.

Syntax highlighting 3.0

Když jsem s Clojure před šesti lety začínal, bylo ve verzi 1.2 a jeho podpora v různých nástrojích byla nízká, nebo žádná. Jednu z věcí, které jsem tehdy řešil, bylo jak zobrazit na blogu syntax highlighting.

Moje první volba padla na tehdy všudypřítomný SyntaxHighlighter. Musel jsem použít jakýsi externí Clojure brush, protože SyntaxHighlighter dodnes nemá nativní podporu Clojure.

S výsledkem jsem nebyl spokojen, takže jsem po čase zvolil nové řešení - jako letitý uživatel famózního editoru Vim, jsem se rozhodl pro trochu ruční práce a zaangažoval vimovskou funkci :TOhtml. S tou jsem maximálně spokojen a používám ji i na svém druhém blogu SoftWare Samuraj. Přesto jsem se rozhodl potřetí pro změnu syntax highlightingu.

Ten třetí důvod má konsekvence s oživením blogu. Aniž bych si tady vylíval srdíčko, jeden z důsledků mých aktuálních rozhodnutí je, vybudovat si na svém GitHubu jakési Clojure portfolio (už jsem o tom kdysi psal).

Volba GitHubu pro mne nebyla úplně přímočará - nejsem "git guy" a pokud můžu, preferuji Mercurial. Pravdou ale je, že veškerá Clojure komunita je GitHubu, tak proč se tomu vzpírat. No, a když GitHub, tak Gist, to dá rozum.

Catalanova čísla

V rámci svého Clojure-zmrtvýchvstání jsem procházel své staré Clojure kódy a narazil jsem na jeden, který se mi líbil - funkce pro výpočet Catalanových čísel. Pikantní je, že si po těch pěti letech nepamatuju, proč jsem to napsal, nicméně funkce se mi líbily natolik, že jsem se rozhodl se o ně - v rámci zahřátí na provozní teplotu - podělit.

Catalanova čísla jsou sekvencí přirozených čísel, která má zajímavé využití v kombinatorice - binární stromy, průchod mřížkou(?), rozdělení polygonu na trojúhelníky ad. Sekvence je definována následujícím vztahem:


Pokud, tak jako já, nejste úplně kovaní v matematice, tak chviličku googlování potrvá, než zjistíte, že pro implementaci tohoto vzorečku budete potřebovat kombinační číslo (binomial coefficient) a tím pádem faktoriál. Pak už je jednoduché poskládat tyto základní funkce do sebe, jako matrojšku:


Když už jsem se v tom tak vrtal, říkal jsem si: nedá se to udělat nějak jednodušeji, efektněji, víc "Clojure"? A dá. Jen je potřeba vyjít z jiného vzorečku, který definuje Catalanova čísla rekurzivně:
Při použití posledního vzorečku nám tak vyjde pěkná Clojure rekurze. Klíčová slova jsou speciální operátory loop a recur:


GitHub project

Pokud si chcete pohrát s Catalanovými čísly trochu víc, anebo dostat malý bonus navíc, podívejte se na můj projekt na GitHubu:
Navíc dostanete Leiningen projekt, testy v Midje a lazy sekvenci Catalanových čísel.

Související články