27. ledna 2011

Functions without side effects

Pročítal jsem si na webu nějaké materiály o funkcionálním programování. Jedním ze základních principů je, že funkce nesmí mít vedlejší efekty (side effects). Výčet a definice těchto principů se v různých zdrojích liší, mne konkrétně oslovily tyto:

  • Pokud je funkce volána s parametry, které nezpůsobují vedlejší efekty, její opakované volání (se stejnými parametry) vrací vždy stejný výsledek.
  • Funkce nesmí měnit vstupní parametry a globální proměnné.
  • Funkce nesmí měnit své chování na základě stavů definovaných mimo funkci.
Tyto principy se samozřejmě dají použít v jakémkoli typu programování, tedy i nejrozšířenějším OOP. A pokud se při vývoji používá TDD, nebo aspoň člověk zodpovědně píše unit testy, dojde k těmto principům zcela přirozeně.

Proč vlastně o něčem takovém (možná triviálním) píšu? Dopisoval jsem teď nedávno unit testy k hotové aplikaci a čas od času jsem narazil na kód, který porušoval všechny tři výše uvedené principy zároveň. Takový kód se samozřejmě velice špatně a také velice pracně testuje. Pro představu:

private void checkSMS() {
    if (sms == OperationEnum.ADDED) {
        if (servis24 == OperationEnum.ADDED
                        || servis24 ==
                            OperationEnum.NOT_CHANGED) {
            codeOperationsList.add(OperationCodeEnum
                            .FILING_SMS_WITH_S24
                                .getCode());
        } else {
            codeOperationsList.add(OperationCodeEnum
                            .FILING_SMS_WITHOUT_S24
                                .getCode());
        }
    }
}

Když to vezmu od "spoda":
  • Funkce se rozhoduje na základě (globálních) flagů sms a servis24.
  • Funkce mění globální/instanční proměnnou codeOperationList.
  • Funkce vrací void. Tedy ať už dělá cokoliv, je to side efect.
Předchozí ukázka je samozřejmě z Javy, takže s/funkce/metoda/g.

No a jaké z toho všeho plyne poučení? Pište funkcionální metody! A pište unit testy! Aplikace pak půjde líp otestovat. Lépe spravovat. A po čase snadněji porozumíte kódu.

21. ledna 2011

Konečně kód!

Uf! Tak jsem se pěkně dlouho mordoval se syntax highlighting. Člověk by řekl, že když je Blogger od Googlu, že už by to mohl tak nějak defaultně umět. Nebo na to mít nějaký plugin. No, možná je to věc použité šablony - každopádně, skončil jsem její úpravou, kdy jsem do ní doplnil reference na SyntaxHighlighter, plus externí skript pro Clojure. Zkoušel jsem i google-code-prettify, ale nepodařilo se mi dosáhnout toho, aby to "prettyfájovalo".

Takže nějaký kód. Zatím jen trivialitky na okoštování a vyzkoušení highlightingu. Ale už se těším, až se ponořím do studia transakčních referencí, agentů a atomů :-)
(+ 1 2 3)
; 6
(defn hello [name] (println "Hello," name))
; #'user/hello
(hello "Guido")
; Hello, Guido
; nil
(map + [1 2 3] [4 5 6])
; (5 7 9)

Jen vysvětlení pro Javisty ;-) výše uvedený výstup je z prostředí REPL a pro pochopení lispovské syntaxe:

Java:
void processSomething(Type valueOne, Type valueTwo) {
        // some code
}

processSomething(valueOne, valueTwo);

Lisp/Clojure:
(defn process-something [valueOne valueTwo] ())

(process-something valueOne valueTwo)

20. ledna 2011

Clojure web-app

Hledal jsem na webu nějaké reference, nebo projekty, které by používaly Clojure a narazil jsem na zajímavou prezentaci od lidí, kteří vytvořili aplikaci TheDeadline. Jde o aplikaci pro GTD, která by měla obsahovat nějakou umělou inteligenci. Zajímavé jsou samozřejmě technologie, které se za touto aplikací skrývají.

Aplikace samotná běží na Google App Enginu (GAE) a původně používala Clojure jak pro komunikaci s (Google) Datastorem, tak pro zobrazení HTML. Jak jsem pochopil z jiné, pozdější prezentace, tak v současnosti by měli pro UI používat Google Closure Templates (další zajímavá technologie).

Datastrore v GAE nabízí dva druhy interfaců - high-level pro Java objekty a low-level, který umožňuje přímo pracovat s key-value strukturami. Což je přesně to, co nativně nabízí Clojure - StructMaps. Je to jedna z myšlenek, které mě v prezentaci nejvíc oslovily - pokud vytvářím webovou aplikaci v Javě, musím udělat (nebo použít framework) mapování tabulka-objekty (ORM) a pak pro prezentaci zase převod objekty-HTML. Tato dvojnásobná transformace, abych zobrazil data z databáze v prohlížeči, by při použití Clojure měla odpadnout, protože obojí by mělo jít přímo. Ono to samozřejmě tak jednoduché nebude, ale ta myšlenka se mi líbí.


Kromě této "technické" prezentace je zajímavá i druhá "manažerská" prezentace, která téma probírá spíše z designového hlediska (a zmiňuje se právě o Google Closure Templates).


A na závěr ještě rozhovor, který vyšel na InfoQ:

18. ledna 2011

Sometimes Clojure

OK, Sometimes Clojure. Přišel čas naučit se další jazyk, a protože fandím jazykům, které běží v JVM, zalovil jsem primárně v těchto vodách. Kromě (mého) oblíbeného Groovy, které už pár let používám, jsem chtěl, aby to byl trošku "jiný" jazyk. A jelikož už nějakou dobu pošilhávám po funkcionálních jazycích, zvolil jsem Clojure. A zdá se, že je to láska na první pohled.

Proč trochu "jiný" jazyk? Představte si, že umíte celkem slušně anglicky, celkem slušně španělsky, cizí slova z latiny vám taky nejsou cizí a rozhodnete se pro francouzštinu. Z vlastní zkušenosti můžu říct, že francouzština je (zatím) nejtěžší evropský jazyk, který jsem se učil. Nicméně výše uvedené znalosti znamenají/způsobí, že učící křivka nového jazyka je velmi strmá. Co když se ale začnu učit nějaký neevropský jazyk? Jazyk, který vzniknul v jiné kultuře, postavený na jiných principech? Tak přesně to, takový neevropský jazyk, je pro mne momentálně Clojure.

Zatím jsem si Clojure nainstaloval v Linuxu i Win, vyzkoušel si základy a zkouknul pár prezentací. Doporučil bych:
A závěrem, proč vznikl tenhle blog? V češtině toho zatím o Clojure moc není, jen sem tam pár zmínek, že něco takového existuje. Takže než se Clojure v Česku trochu rozšíří, třeba se mezitím stanu Clojure guru :-)