C- ja muunkielisissä projekteissa tavataan kirjoittaa koodia ensin, ja sitten testataan. Tietysti vaatimus osittain syntyy koodin kääntämisestä; ilman kääntöä ei voi mitenkään testata. Dynaamisissa kielissä ei aina ole päinvastainen tilanne: kaikista interaktiivisen Python-tulkin ansioista huolimatta ainakin minulla Python-kehitys menee samalla tavalla kuin vaikkapa Java-koodin tapauksessa: ensin kirjoitan jotain testintapaista, sitten ajetaan. Lispit ovat aina olleet oman suoritusympäristönsä sisällä niin muokattavia, että siellä kehitysmalli on hioutunut aikojen saatossa. Ehkä Ruby- ja Python-yhteisöt1 seuraavat perässä.
Lispeissä on hyvin dynaaminen “maailma”, suoritusympäristö. Jos muuttuja määritellään uudestaan mille tahansa tyypille, niin tehdään mukisematta. Funktiotkin voi aina kirjoittaa uusiksi lennosta. Se johtaa siihen, että koodia ensin kokeillaan ja sitten vasta kirjoitetaan. Hyvät työkalut lispeille tekevät ihmeitä.
Staattiset systeemit vaativat enemmän esimerkiksi TDD:n apua sujuvaan kehittämistyöhön. Clojurea koodatessani TDD on hyvin pienellä prioriteetilla. Ensin voin kokeilla REPLissä perustavan konseptin idealleni, sitten kirjoittaa jonkinlaisen funktion asiasta. Koska Clojure on hyvin tiivistä koodia, se auttaa myös ihmisen rajoitusten ylitulemisessa. Hyvinkin ilmaisurikkaat lausekkeet saa mahtumaan seitsemään sanaan, ihmisen työmuistin äärirajoille. Se on kuin ohjelmoija kävisi suoritinrekisterimuisteilla. Vasta tiukemmissa konsepteissa saatan sitten kirjailla parit testit. En kuitenkaan niitäkään valmiiksi. Koodi ja funktioiden ulostulo usein muovautuu lopulliseksi muutaman yritys-erehdys -iteraation kautta.
Clojuren bottom-up -menetelmä on siitä erinomainen. Jos lähtee alkulähteiltä, ei tarvitse huolehtia funktioiden signatuureista tai yhteensopivuudesta. Suunnittelutta on helpompi lähteä liikkeelle, joskin visio tiedon virtaamisesta on hyvä omata päässä. Kun lähdetään ihan alhaalta, eli syötedatan lukemisesta tietorakenteiksi, tietovirta tulee luontevasti mukana. Valitettavasti useimmat epätriviaalit ohjelmat haarautuvat useaksi osaseksi, ja tietovirtoja sekä aiempia funktioita joutuu väistämättä refaktoroimaan uusiin muotoihin.
Kuitenkin omissa projekteissani olen voinut seurata tietovirtaa aika tyydyttävästi. Lähes aina lähden siitä, että tiedosto luetaan muistiin, ja siitä parsitaan haluttu tieto ulos vaikkapa sanakirjaksi. Sitten jatketaan siitä sanakirjasta ja niin pois päin. Viimeisenä kaikin puolin käsitelty tietorakenne saa lopullisen muotonsa; usein tekstiesityksen.
Pythonissa on hyvähkö interaktiivinen tulkki. Ehkä jos editorin konffaa lähettelemään koodinpalasia siihen, Python-kokemus lähentelee jo Lisp/Clojure -kehityskokemusta. Vimiä ei tunneta parhaana IDE:nä maailmassa, mutta VimClojure on jotain, joka saa mielestäni Emacsinkin SLIME-moodin punastelemaan. Tosin SLIME voittaa kyllä, jos lisp-valintani ei olekaan Clojure.
1 Todettakoon, että rubyläiset voivat hyvinkin jo toteuttaa tätä, mutta enhän minä tiedä varmaksi.