You are on page 1of 72

Abstiaction Oiiented Piogiamming

lunctioneel piogiammeien op de
JVM met Clojuie
Auteui Studentnummei
Rik van Achterberg 1..:+,.
Biian van der Bijl 1.o:e+
Woutei Hassing 1..,o1
Mauhijs Steen 1.eo1:
Docent Michiel Borkent
Ondeizoeksveislag vooi het ondeizoekssemestei
Abstiaction Oiiented Piogiamming
Hogeschool Utiecht laculteit Natuui en Techniek
:; juni :o11
Samenyatting
Clojuie is een ielatief nieuwe piogiammeeitaal geiicht op het bien-
gen van een Lisp naai de Java Viitual Machine (JVM) en (in de toe-
komst) het .NET platfoim van Miciosof. Het doel bij het ontwikkelen
van Clojuie was om een modeine Lisp te maken op het Java platfoim
die goede suppoit leveit vooi meeideie piocessoicoies. Op dit mo-
ment heeist Object-Oiiented Piogiamming (OOP) als het meest toege-
paste piogiammeeipaiadigma, maai deze talen kunnen niet optimaal
gebiuik maken van de huidige haidwaie ontwikkelingen. Daaiom zien
we een heinieuwde inteiesse ontstaan in lunctional Piogiamming (lP)
talen - die hiei veel betei vooi geschikt zijn. ln dit veislag zullen we
uiteenzeuen wat deze ontwikkelingen inhouden en hoe het ondeiwijs
hieiop kan inspiingen. Clojuie is hiei in het bijzondei vooi geschikt
omdat het goed kan samenweiken met Java, waai al veel les ovei woidt
gegeven binnen het ondeiwijs op hogescholen.
ii
Voorwoord
Vooi u ligt een ondeizoeksveislag welke het iesultaat is van een ondeizoek
naai Abstiacted Oiiented Piogiamming in Clojuie, namens de Hogeschool
Utiecht in opdiacht van onze begeleidei Michiel Boikent. Dit ondeizoek is
uitgevoeid in ons zesde semestei als invulling van de specialisatieiuimte
vooi infoimaticastudenten.
Dit ondeizoeksveislag is bedoeld vooi iedeieen die inteiesse heef in het
piogiammeien in Clojuie, de veischillen met Java, of het piogiammeien in
functionele en/of declaiatieve talen in het algemeen. Dit veislag is in het bij-
zondei bedoeld vooi onze docenten en medestudenten.
Onze dank gaat uit naai Michiel Boikent die ons het afgelopen half jaai
uitstekend heef begeleid en ons met zijn technische en piaktische kennis
heef ondeisteund. Daainaast willen we de Hogeschool Utiecht bedanken
vooi het aanbieden van de mogelijkheid tot voeien van ondeizoek naai ei-
gen keuze.
Rik van Achteibeig
Biian van dei Bijl
Woutei Hassing
Mauhijs Steen
Utiecht, juni :o11
iii
Inhoudsopgaye
Inhoudsopgaye iy
1 Inleiding 1
z Doel yan het onderzoek =
:.1 Ondeizoeksdoel . . . . . . . . . . . . . . . . . . . . . . . . . .
:.: Ondeizoeksviagen . . . . . . . . . . . . . . . . . . . . . . . . .
+ Onderzoeksmethode ;
+.1 Beschiijvend . . . . . . . . . . . . . . . . . . . . . . . . . . . ;
+.: Veigelijkend . . . . . . . . . . . . . . . . . . . . . . . . . . . ;
+.+ Denieiend . . . . . . . . . . . . . . . . . . . . . . . . . . . . ;
Wat is Clojure' o
.1 LlSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,
.: Clojuie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1o
.+ De JVM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1:
. lilosoe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1+
= VersHillen met Jaya 1;
..1 Key concepts van OO in Clojuie . . . . . . . . . . . . . . . . 1;
..: Veilig codeheigebiuik . . . . . . . . . . . . . . . . . . . . . . :;
o Casus RiHRail +1
e.1 Sofwaie paueins en ontweip . . . . . . . . . . . . . . . . . . +1
e.: De Java-veisie . . . . . . . . . . . . . . . . . . . . . . . . . . +:
e.+ De Clojuie-veisie . . . . . . . . . . . . . . . . . . . . . . . . ++
; Clojure als lesstof +
8 Nawoord =
s.1 Piogiammeien blijf mensenweik . . . . . . . . . . . . . . . .
o Conclusie ;
A AHterliggende theorie en wiskunde o
A.1 Monads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,
iv
lNHOUDSOPGAVE
A.: De Paisei monad . . . . . . . . . . . . . . . . . . . . . . . . . .o
A.+ De Log monad . . . . . . . . . . . . . . . . . . . . . . . . . . .o
A. MonadPlus . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
B RiHRail Assignment =+
C Macros in Clojure =;
C.1 Weiking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .;
C.: Vooibeeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .;
Denitielijst o1
Bibliograe o=
v
1 Inleiding
Het afgelopen semestei hebben wij ondeizoek gedaan naai lP in Clojuie. Op
het eeiste gezicht zal Clojuie waaischijnlijk ingewikkeld en vieemd lijken.
Clojuie is namelijk een vaiiant op LlSP, een functionele piogiammeeitaal
die in 1,.s veischeenLU] en bekend staat om zijn gebiuik van vele geneste
haakjes. Dit leidt eitoe dat, vooi iemand die niet bekend is met LlSP, de code
eiuit ziet als een soep van haakjes.
Clojuie is een ielatief nieuwe functionele piogiammeeitaal en diaait bo-
venop de JVM. De eeiste publieke ielease was eind :oo;lH11] en de eeiste
stable ielease was in begin :oo,.
Binnen Clojuie zijn functies ist-class membeis. luncties komen dus op
dezelfde plaats als e.g. integeis en stiings. Dit maakt het mogelijk ombijvooi-
beeld functies aan functies dooi te geven of deze tijdens iuntime te geneie-
ien.
Veel piogiammeitalen ondeisteunen tegenwooidig een voim van lP, zoals
Cr, PHP, Ruby en Peil. Bij Clojuie is dit echtei het hoofdpaiadigma, aange-
zien het een LlSP is.
lP piobeeit mutable state te vooikomen. De focus binnen een lP-taal ligt
op veel behavioui (functies) en weinig data. Een functionele taal valt daai-
omondei het declaiatieve paiadigma. Het beschiijf namelijk de logica, maai
niet de contiol ow. Dit in tegenstelling tot Object-Oiiented (OO) talen zoals
Java en C--, waaibij de focus op het veiandeien van de mutable state ligt.
Het OO piogiammeei-paiadigma valt deihalve ondei het impeiatieve paia-
digma.
ln declaiatieve piogiammeeitalen woidt beschieven wat ei moet gebeu-
ien, teiwijl in het impeiatieve paiadigma ook woidt beschieven hoe dit moet
gebeuien (de contiol ow).
Het idee achtei functionele piogiammeeitalen is dat je op die maniei
maai weinig datatypes hoef te denieien waaiop een giote hoeveelheid
functies kan woiden toegepast, zodat ei zo min mogelijk boileiplate-code
ontstaat en ei zoveel mogelijk behavioui heigebiuikt kan woiden. Het mag
dus duidelijk zijn dat het functionele piogiammeeipaiadigma om een heel
1
1. lNLElDlNG
andeie denkwijze viaagt.
De ieden dat wij gekozen hebben om Clojuie te ondeizoeken is dat de
meeste infoimatica-opleidingen zich uitsluitend bezighouden met piogiam-
meien in impeiatieve piogiammeeitalen. Deze talen hebben op dit moment
dan ook de giootste useibase, maai het is nuuig om ook in aaniaking te
komen met een andei spectium van piogiammeeitalen. Het aanleien van
veischillende manieien van piogiammeien kan studenten leien om op vei-
schillende manieien naai een piogiammeeipiobleem te kijken.
Nog een ieden om aandacht te besteden aan lP is dat dit paiadigma
momenteel in populaiiteit toeneemt. Dit is ondei andeie een gevolg van
de giootschalige opkomst van multicoie-piocessoien. lunctionele piogiam-
meeitalen maken (indien goed gebiuikt) geen gebiuik van globale vaiiabelen,
waaidooi een functioneel geschieven piogiamma althans in theoiie ge-
makkelijk veispieid ovei veischillende coies kan diaaien.
Ei kan beaigumenteeid woiden waaiomin dat geval niet iedeie piogiam-
meui met functionele piogiammeeitalen weikt. De hoofdieden hieivooi is
dat de haidwaie van vioegei niet zo kiachtig was als nu de hoeveelheid ie-
souices waien eig bepeiktWikb]. Volledige contiole ovei hoe de sofwaie
met de kostbaie iesouices omging had dus een giote meeiwaaide. Dit is pie-
cies waai de focus van het impeiatieve paiadigma ligt en de ieden waaiom
dit paiadigma in de laatste decennia zo populaii is gewoiden.
Dit heef tot gevolg gehad dat bediijven veel hebben genvesteeid in pio-
giammeeitalen van het impeiatieve paiadigma. Op hun beuit zijn piaktijk-
geiichte scholen hieiop ook de focus gaan leggen, ei was immeis veel viaag
naai piogiammeuis met eivaiing in impeiatieve piogiammeeitalen. Hiei-
dooi is lP in het bediijfsleven naai de achteigiond geschoven.
De ontwikkelingen in de haidwaie hebben echtei niet stilgelegen. Hiei-
dooi is een situatie ontstaan waai de vooidelen van het volledig in contiole
zijn ovei iesouices niet altijd meei opwegen tegen de nadelen. Men heef te-
genwooidig dusdanig veel iesouices en giote piogiammas dat het niet meei
noodzakelijk is omte beschiijven hoe een piogiamma exact weikt (zoals wel-
ke geheugenadiessen woiden gebiuikt), maai men eigenlijk alleen willen be-
schiijven wat ei gedaan moet woiden. Zo kan men veel ecientei piogiam-
meien.
Ook in de academische weield heef het ondeizoek naai het functionele
paiadigma niet stil gelegen. Clojuie maakt gebiuik van iesultaten van veel
ondeizoeken die zijn gedaan in de academische weield, maai is ontwoipen
:
1. lNLElDlNG
dooi piogiammeuis, met het doel om ook in de piaktijk gebiuikt te woiden.
Dit is goed teiug te zien in de ontweipkeuzes van Clojuie. Clojuie is
bijvooibeeld geen puie functionele piogiammeeitaal. Men mag side-eects
gebiuiken maai Clojuie is zo opgezet dat men hiei altijd bewust van is. Daai-
naast heef Clojuie een zeei goede integiatie met Java waaidooi men gebiuik
kan maken van alle bestaande Java-libiaiies. Dit is n van de iedenen waai-
om Clojuie in koite tijd ielatief populaii gewoiden is. Clojuie leunt op de
schoudeis van Java.
+
z Doel yan het onderzoek
2.1 Onderzoeksdoel
Het doel van dit ondeizoek is het in kaait biengen van de veischillen tus-
sen het declaiatieve Clojuie en het impeiatieve Java en wat de eventuele
vooidelen zijn van het piogiammeien in een functionele piogiammeeitaal.
Bovendien willen we beooidelen of het haalbaai en adviseeibaai is om op
(HBO) infoimatica-opleidingen les te geven in lP, in het bijzondei in Cloju-
ie.
2.2 Onderzoeksvragen
Wat zijn de voornaamste verschillen tussen Clojure en Java?
Ons ondeizoeksteambestaat uit deidejaais (technische) infoimatica-studenten,
waaibij wij tot dusvei alleen nog kennis hebben gemaakt met impeiatieve /
OO talen zoals Java, PHP en C--. Zodoende is het vooi ons inteiessant om
de zaak van een andeie kant te bekijken, namelijk de declaiatieve piogiam-
meeitalen. Met dit ondeizoek willen we kennis maken met het declaiatieve
paiadigma en de piogiammeeitaal Clojuie. Het doel is niet om een hand-
leiding vooi Clojuie te schiijven en daaiom zullen we niet alle ondeidelen
behandelen. Ons doel is juist te ondeizoeken wat deze veischillen betekenen
vooi studenten die oveischakelen van OOP naai lP, welke stiuikelblokken
of vooidelen dit kan opleveien. Dit doen we aan de hand van het uitweiken
van de RichRail-casus.
Wat zijn de voornaamste voor- en nadelen van Functioneel Program-
meren in Clojure t.o.v. Object-georinteerd programmeren in Java?
lunctionele piogiammeeitalen hebben zondei twijfel een kleineie useibase
dan de talen waaiin we gewend zijn te ontwikkelen. ls dit teiecht` Als we
the iight tool foi the iight job willen gebiuiken, waai staat lP dan` Wat
zijn de limieten`
.
:. DOEL VAN HET ONDERZOEK
Zou de Hogeschool Utrecht er goed aan doen om Functioneel Pro-
grammeren in het informatica-curriculum op te nemen?
De vooinaamste viaag. Aan de hand van de vooigaande twee viagen en
de leeiweg die we zelf hebben ondeigaan moeten we iedelijkeiwijs kun-
nen beooidelen of het veistandig is om lP te ondeiwijzen in de infoimatica-
opleidingen.
e
+ Onderzoeksmethode
Bij ons ondeizoek is vooial oiienteiend te weik gegaan aangezien Clojuie
bij geen van ons bekend was. We kunnen de toegepaste ondeizoekmethodes
veidelen in de volgende categoiieen
3.1 Beschrijvend
ln dit document zullen de kenmeiken van Clojuie in kaait woiden gebiacht.
Ei woidt bewust niet op alle kenmeiken ingegaan aangezien het veislag be-
doeld is vooi mensen die geen eivaiing hebben met Clojuie. Enkele uitge-
bieide infoimatie is vooi de genteieseeiden teiug te vinden in de apendices.
Hieivooi zijn bestaande bionnen geiaadpleegd, zoals iecent veischenen
boeken en ociele documentatie. Daainaast hebben wij een Java casus Rich-
Rail van een vak (Paueins and liamewoiks) binnen ons cuiiiculum heige-
biuikt in dit ondeizoek. Hiei is bewust vooi gekozen omdat de doelgioep van
dit veislag vooinamelijk bestaat uit onze medestudenten die bekend zijn met
deze lesstof en daaiom weinig moeite zullen hebben met veigelijken. Daai-
naast geef deze casus mooi de veischillen weei in de benadeiing tussen de
twee pioigammeeitalen.
3.2 Vergelijkend
Bij het bepalen van de kenmeiken van Clojuie woidt in dit veislag vaak de
veigelijking gemaakt met Java. De ieden hieivooi is dat dit document be-
stemd is vooi mensen die al eivaiing hebben met Java, maai genteiesseeid
zijn in alteinatieven. ln de meeste veigelijkingen is gebiuik gemaakt van de
RichRail casus, waaivan de backend zowel in Java als in Clojuie is uitge-
weikt. Deze backends zijn beide volledig teiug te vinden in de appendices.
ln enkele gevallen valt een vooibeeld buiten de context van de casus. ln dat
geval is ei gebiuik gemaakt van een eenvoudig te begiijpen vooibeeld.
3.3 Definirend
Dit document beschiijf in welke categoiie de piogiammeeitaal Clojuie valt
en vooi welke pioblemen het gebiuik van Clojuie een goede oplossing zou
;
+. ONDERZOEKSMETHODE
zijn. Dit gebeuit dooi middel van het obseiveien van onze eigen vooitgang
met de taal en het uitweiken van de casus RichRail. Daainaast hebben we
bestaande Clojuie piojecten bestudeeid en veischillende bionnen geiaad-
pleegd zoals boeken, blogposts en foia.
s
Wat is Clojure'
Zoals andeie LlSPs behandelt Clojuie code als data en ondeisteunt het een
veijnd en kiachtig maciosysteem (zie appendix C). Om te leien hoe Clojuie
te weik gaat, zal men eeist moeten begiijpen wat een LlSP is. Veel techneu-
ten hebben wel eens van LlSP gehooid, maai weten niet piecies wat de teim
inhoudt.
4.1 LISP
Als ei ovei LlSP woidt gespioken dan woidt niet zozeei de ooispionkelijke
LlSP implementatie bedoeld, maai eeidei de familie van piogiammeeitalen
die gebaseeid is op de syntax van LlSP. Clojuie is hiei een iecente van.
De eeiste LlSP is ontwoipen in 1,.s en is daaimee een van de oudste
modeine piogiammeeitalen die weieldwijd nog veel woidt toegepast. Mede
dooi de leefijd en wijdveispieidheid van LlSP, bestaan hieivan veischillen-
de implementaties.
LlSP is ooispionkelijk ontwoipen als een piaktische wiskunde-notatiewijze
vooi computeipiogiammas, zwaai gebaseeid op de Lambda calculus, een
foimeel systeem dat in de wiskunde en theoietische infoimatica gebiuikt
woidt om ondeizoek te doen naai het denieien en uitvoeien van beieken-
baie functies. Het weid in 1,+e gentioduceeid dooi Alonzo Chuich en Step-
hen Kleene als ondeideel van hun ondeizoek naai de giondbeginselen van
de wiskunde.
LlSP weid al snel de favoiiete piogiammeeitaal vooi Aiticial lntelligen-
ce (Al) ondeizoek. De meest bekende geneial puipose LlSP implementaties
zijn Common LISP, Seme en nu ook Clojuie. LlSP heef veel betekend vooi
de evolutie van piogiammeitalen zo zijn in LlSP veel nieuwe ideeen gen-
tioduceeid, zoals Automatic Stoiage Management (ASM), dynamic typing en
de self-hosting compilei (de compilei kan zijn eigen souice code compilen).
,
. WAT lS CLOJURE`
De naam LlSP slaat op List Piocessing. Dit houd in dat alle code is ge-
schieven in de voim van lijsten, en daaimee dus in datastiuctuien van LlSP.
Data kan dus code vooistellen. Dit is een eig kiachtig piincipe en zoigt vooi
een eenvoudige syntax. Omdat LlSP code bestaat uit lijsten is het beiucht om
zijn haakjes die je dan ook oveial in de code teiugvindt.
Iisting .1 Voorbeeld
1 (+ 1 (- 4 2))
2 ; De stappen die worden uitgevoerd zijn als volgt.
3 ; (- 4 2) = 4 - 2 = 2
4 ; (+ 1 2) = 1 + 2 = 3
ln dit vooibeeld zijn + en - bijvooibeeld een functie en zijn en : aigu-
menten. Vooi mensen die alleen bekend zijn met niet LlSP-gebaseeide pio-
giammeeitalen is deze andeie denkwijze eig wennen. Ei komt viijwel geen
syntax kijken bij het piogiammeien in een LlSP Met het vooibeeld hieibo-
ven is het belangiijkste gedeelte van de hoeveelheid syntax al behandeld.
Bijna alles bestaat uit deze voim van lijsten. Deze voim van expiessies woi-
den S-expiessies genoemd. ln een S-expiessie is het eeiste item de functie en
woidt de iest als data/aigumenten beschouwd. S-expiessies kunnen goed ge-
nest woiden en in LlSP zie je dit vaak teiug, zoals in het vooibeeld hieiboven
ook al is toegepast. De kiacht van S-expiessies is dat ze datastiuctuien zijn,
dus code is data en data in de voim van S-expiessies kan woiden uitgevoeid
als code.
4.2 Clojure
Clojuie is een vooibeeld van een LlSP dialect. Het bevat dus de hieiboven
beschieven piincipes. Men heef het ovei idiomatic Clojuie code als de code
voldoet aan de losoe van Clojuie (zie .). Dit is een belangiijk element
bij de beooideling van andeimans Clojuie code, aangezien het optimaal ge-
biuikmaken van een piogiammeeitaal inhoudt dat men de taal gebiuikt zoals
deze bedoeld is. Als vooibeeld zou men bijvooibeeld in een Java-applicatie
alle code in de main-methode kunnen schiijven. Hieidooi veiliest men echtei
veel van de kiacht die Java piogiammeuis biedt om code op een modulaiie
en heibiuikbaie maniei op te zeuen.
Zo heef ook Clojuie een bepaalde losoe. Als men hiei geen gebiuik
van maakt heef dit giote invloed op de kwaliteit van de code. Op welke ap-
plicatie bouw je lievei veidei een applicatie die volledig is geschieven in
een main-methode, of een applicatie die volgens OO losoe is opgezet` Dit
1o
.:. CLOJURE
is veigelijkbaai met de losoe van Clojuie- en net als bij de OO losoe
is het soms moeilijk om goed code volgens dit piincipe te schiijven. Geluk-
kig ziet men daaiom vaak de viaag is this idiomatic Clojuie` langskomen
op inteinetfoia. Vaak kun je met de mening van andeie piogiammeuis snel
achteihalen of een stuk code idiomatic Clojuie is, zodat zowel een andeie
Clojuie-piogiammeui als de Clojuie compilei ei goed mee oveiweg kan.
Java is statisch, Clojure is dynamisch
Java is een static typed taal. Dit betekent dat men in het geval van Java de
compilei moet veitellen wat het type van een vaiiabele is. Clojuie is daaien-
tegen een dynamic, stiongly-typed taal. De meeideiheid van de contiole van
types woidt bij Clojuie uitgevoeid tijdens iun-time in plaats van tijdens het
compileien. Dynamic typed houdt in dat waaiden een type hebben maai va-
iiabelen niet. Dit wil zeggen dat een vaiiabele kan veiwijzen naai een waaide
van elk type. Veigeleken met static typed kan dynamic typed typeiing veel
exibelei zijn. Dit gaat echtei ten koste van peifoimance.
Clojuie is standaaid dynamic typed, maai dooi gebiuik te maken van ty-
pe hints kan men aan de compilei veitellen welk type deze kan veiwachten.
Dooi het gebiuik van deigelijke type hints kan de peifoimance van een stuk
code veihoogd woiden. Het is echtei belangiijk om op te meiken dat het en-
kel om een hint gaat, de typeiing zal dynamisch blijven.
Immutable Data Structures
De makkelijkste maniei om te vooikomen dat een mutable state veiandeit,
is dooi gebiuik te maken van immutable data structures. Clojuie biedt een
ieeks onveiandeilijke lijsten, vectoien, sets en maps aan. Aangezien deze
datastiuctuien niet kunnen woiden veiandeid, betekent dit dat als ei iets
toegevoegd aan of veiwijdeid woidt van een onveiandeilijke collectie,
deze collectie een nieuwe identieke collectie cieeeit met de noodzakelijke
veiandeiing. Persistence is een teim die gebiuikt woidt om de eigenschap te
beschiijven waaibij de nieuwe collectie haai oude veisie (oude collectie) nog
kent na de veiandeiing.
Recursie in plaats van looping
Dooidat ei in Clojuie gebiuik woidt gemaakt van immutable datastiuctu-
ien, is ei geen ondeisteuning vooi e.g. foi of while loops, die gebiuik
11
. WAT lS CLOJURE`
moeten maken van mutable datastiuctuien. Dit is bij veel functionele pio-
giammeeitalen het geval, en daaiom woidt ei in veel van deze talen gebiuik
gemaakt van iecuisieve functie-aanioepen om hetzelfde iesultaat te beiei-
ken. Deze talen waaiboigen dat deze functie-aanioepen plaatsvinden in de
staaitpositie (de laatst aangeioepen S-expiessie), zodat ze geen stackiuim-
te consumeien (tail-call-optimalisatie). Omdat Clojuie echtei gebiuik maakt
van Java kan Clojuie niet dezelfde tail-call-optimalisatie aanbieden. Clojuie
biedt in plaats van deze optimalisatie de recur opeiatoi aan.
Hoewel niet zo algemeen als tail-call-optimalisatie, staat recur wel dezelf-
de elegante constiuctie toe en biedt recur het vooideel dat ei gecontioleeid
kan woiden of recur wel in de staaitpositie plaatsvindt.
Iisting .z Voorbeeld yan recursie in Clojure
1 (defn countdown [result x]
2 (if (zero? x)
3 result
4 (recur (conj result x) (dec x))))
4.3 De JVM
Clojuie is een geneial-puipose piogiammeeitaal geschieven bovenop de JVM.
Ondanks dat de JVM zijn ooispiong heef in Java betekent dit niet dat de JVM
alleen geschikt is vooi Java. Steikei nog, dat hiei vanuit gegaan weid is teiug
te vinden in eig vioege speciciaties van de JVMCow11]. Natuuilijk heefJa-
va als piogiammeeitaal de focus binnen de JVMen daaiombevat de JVMook
Java-specieke instiucties. Het giootste gedeelte is echtei taalimplementatie-
onamankelijk. Om deze ieden woidt oveiigens eivooi gepleit om de naam
aan te passen naai iets geneiiekeisWieos]. De JVM heef zich in de loop dei
jaien bewezen als een stabiel platfoim om haidwaie- en OS-onamankelijk
sofwaei op te kunnen bouwen. Daaiom ziet men de laatste jaien een gioei
in het aantal piogiammeeitalen dat eivooi kiest om bovenop de JVM te gaan
bouwen. Zo zijn ei veel nieuwe piogiammeeitalen ontstaan die als veivan-
ging vooi Java willen dienen. Niet alleen nieuwe talen kiezen echtei vooi de
JVM ei is ook een gioei van bestaande piogiammeeitalen die hun imple-
mentatie oveizeuen naai de JVMLeios]. Het giote vooideel hieivan is dat
zon piogiammeeitaal zich veivolgens meei kan focussen op hetgeen wat
de taal uniek maakt de taalspecieke ondeidelen. De JVM is dus ideaal als
stabiele basis vooi piogiammeeitalen. De peifomance oveihead die de JVM
met zich meebiengt is eig laag en komt in de buuit van C/C-- Wika]. Dit
1:
.. llLOSOllE
is te danken aan de vele peifoimance-optimalisaties die de JVM kan uitvoe-
ien, waaiondei Just in Time (JlT) compilaties waaidooi code kan woiden
geoptimaliseeid zodat bijvooibeeld het aantal functieaanioepen kan woiden
geieduceeid.
Bij de JVM is ei spiake van veischil tussen niveaus waaiop een taal zich
bevindt. JRubys implementatie is bijvooibeeld geschieven als een inteipie-
tei in Java. Hieidooi zal JRuby nooit dezelfde peifoimance kiijgen als Java.
Omdat JRuby een inteipietei is kan de JVM een gioot aantal optimalisaties
niet meei uitvoeien, aangezien code niet woidt omgezet naai Java byteco-
de, maai woidt geevalueeid dooi Java-code. Clojuie daaientegen piobeeit
zo dicht mogelijk bij de JVM bytecode te komen. Zo piobeeit Clojuie zo min
mogelijk eigen wiappeis te intioduceien en zoveel mogelijk gebiuik te ma-
ken van bestaande Java-wiappeis totdat ei piimitive suppoit is. Dit heef als
gevolg dat de peifoimance van Clojuie eig dicht in de buuit komt , omdat
veel van de JVM optimalisaties dankzij het low level gebiuik van toepassing
zijn. De giootste hoeveelheid peifoimance oveihead ontstaat dooidat Clo-
juie dynamic typed is in plaats van static typed waaidooi ei veel gebiuik
moet woiden gemaakt van ieectie. Dit is oveiigens een aandachtspunt van
de Clojuie-ontwikkelaais en veimoedelijk zal in de komende Clojuie-veisies
(op dit moment is 1.: de stable veisie) de peifoimance hieivan woiden vei-
beteid.
4.4 Filosofie
Clojuie is een dialect van LlSP waaibij de focus duidelijk op het functionele
paiadigma ligt (cf. Common LlSP, dat meei een manusje-van-alles is wat be-
tief veischillende paiadigmata). Deihalve ligt de focus eiop dat code woidt
geschieven die succinct en duidelijk is. Met succinct woidt bedoeld compact,
maai dat is wat andeis dan zo klein mogelijk. Een beteie veitaling zou zijn,
dat het zo min mogelijk moeite kost om de code te begiijpen. Met code ob-
fuscation in Perl is het bijvooibeeld mogelijk veel te doen met weinig iegels
code, maai omdat iedeie iegel code een hoop moeite kost om te lezen, is de
code nog steeds niet succinct.
Kleine code is dus een vooideel, zolang dit aan de leesbaaiheid niet af-
doet. Clojuie code is vaak kleinei dan een veigelijkbaai piogiamma in bij-
vooibeeld Java, maai betei leesbaai.
ln Clojuie is code dus compact maai toch leesbaai. Dit komt dooi het
declaiatieve kaiaktei van de taal. Waai in talen als Java alle nodige stap-
pen expliciet staan uitgeschieven, blijf dit in Clojuie veel meei bepeikt. ln
1+
. WAT lS CLOJURE`
veel gevallen is de compilei in staat uit te vinden hoe een taak moet woiden
voltooid, waaidooi het volstaat enkel de taak zelf te denieien. Java daaien-
tegen, veiwacht dat de piogiammeui de oplossing denieeit, stap vooi stap.
Zie hieiondei tei veigelijking twee vooibeelden, waaibij de getallen in de
libonacci ieeks woiden beiekend
Iisting .+ Voorbeeld in Clojure
1 (def fib-seq
2 (lazy-cat [0 1]
3 (map +
4 (rest fib-seq) fib-seq)))
5
6 (defn fib [n] (nth fib-seq n))
7
8 (defn main [] (map (comp println fib) (range 46)))
Iisting . Voorbeeld in Jaya
1 public class Fibonacci {
2 public static int fib(int n) {
3 int prev1 = 0, prev2 = 1;
4 for (int i = 0; i < n; i++) {
5 int savePrev1 = prev1;
6 prev1 = prev2;
7 prev2 = savePrev1 + prev2;
8 }
9 return prev1;
10 }
11
12 public static void main(String[] args) {
13 for (int i = 0; i <= 46; i++)
14 System.out.println(fib(i));
15 }
16 }
Hiei valt alleieeist het feit aan op dat in Clojuie geen klasse moet woi-
den aangemaakt. ln Java (en enkele andeie OO talen) is dat wel het geval
Een klasse is de enige plaats waai methoden kunnen woiden geplaatst, en
een methode is de enige plaats waai code kan vooikomen.
1
.. llLOSOllE
Wat echtei veel belangiijkei is, is de maniei waaiop het piogiamma
woidt beschieven ln de Java-vaiiant woidt stap vooi stap aangegeven wat ei
moet gebeuien. Het Clojuie vooibeeld daaientegen legt een veiband tussen
input en output. Het iesultaat woidt als het waie beschieven op basis van
de input. Alleieeist woidt gedeclaieeid wat de libonacci ieeks piecies is. Dit
gebeuit op basis van een aantal basiswaaiden (de eeiste o en 1), gevolgd dooi
de iegels die nodig zijn om opeenvolgende getallen in de ieeks te beiekenen,
dooi de bestaande, huidige ieeks op te tellen bij de voiige veisie van de ieeks
0 : 1 0 : 1 :
0 : 1
1 +
1 0 : 1 :
0 : 1 : 1
1 : 1 +
1 : 2 0 : 1 :
0 : 1 : 1 : 2
1 : 1 : 2 +
1 : 2 : 3
Veivolgens woidt aan de computei veiteld hoe een gegeven bonacci
getal hieiuit woidt gehaald. Tot slot voimt een ieeks van getallen de input
vooi een seiie aanioepen van (de samenstelling van) println en fib. De twee-
de stap in het Clojuie vooibeeld is hiei oveiigens eigenlijk een omweg. Veel
makkelijkei zou het zijn de eeiste e getallen van de lijst te pakken, in plaats
van e keei het n-de getal op te viagen. ln dit geval is echtei gekozen vooi
de meei omslachtige aanpak, omdat deze meei oveieenkomt met de Java va-
iiant. De functie en methode fib komen hieidooi van buitenaf gezien zoveel
mogelijk oveieen.
Duidelijkheid
Duidelijkheid dankt Clojuie code aan het stieven naai iefeiential tianspa-
iency. Dit houdt in dat de uitkomst van een tianspaiante functie slechts
amankelijk is van de paiameteis die bij de aanioep gebiuikt woiden. Dat
klinkt misschien eig vooi de hand liggend, maai in impeiatieve code is dit
vakei niet dan wel het geval. Dit komt dooidat in impeiatieve code mutable
state toegestaan is. Als vaiiabelen gewijzigd kunnen woiden, is niet altijd
duidelijk wat de waaide van een vaiiabele nu is. Dit houdt in dat je hiei als
piogiammeui iekening mee moet houden - of fouten iiskeeit. Mutable state
komt vakei vooi dan men misschien denkt lteiatois bijvooibeeld, of instan-
tievaiiabelen. De waaide van al deze vaiiabelen kan van invloed zijn op de
weiking van een piogiamma, en moet dus in de gaten woiden gehouden.
Het andeie uiteiste, geheel zondei mutable state, is echtei ook niet goed
piogiammeien Als ei niets kan veiandeien, betekent dat dus in wezen dat
iedei mogelijk piogiamma niets tot gevolg heef. Dit is niet gewenst. De mid-
denweg die bij Clojuie is gekozen houdt in dat het veiandeien van vaiiabelen
ontmoedigd woidt, maai niet onmogelijk is. Zo lang dit niet in een functie
gebeuit is deze iefeientieel tianspaiant, en is het gediag eivan dus vooispel-
1.
. WAT lS CLOJURE`
baai, wat duidelijke code tot gevolg heef.
Zondei mutable state zijn een aantal piogiammeeimethoden die een im-
peiatieve piogiammeui dagelijks gebiuikt onmogelijk. Gelukkig zijn ei in het
functionele paiadigma alteinatieven ontwikkeld, zodat mutable state veime-
den kan woiden. Het meest vooi de hand liggende vooibeeld is hieibij de
loop. Om iets meeimaals uit te voeien woidt in impeiatieve talen gebiuikt
gemaakt van iteiatie in de voimvan bijvooibeeld for- en while loops. Een ite-
iatoi is echtei een vaiiabele die constant gepdatet woidt. Dit is niet wense-
lijk. Clojuie gebiuikt hieivooi, in de basis, iecuisie. Dooi een functie zichzelf
te laten aanioepen, met iets andeie paiameteis, heef iedeie aanioep zijn ei-
gen scope en kan met zijn eigen paiameteis tot een iesultaat komen. Hieiin
kan het iesultaat van een nieuwe iecuisieve aanioep gebiuikt woiden, of
het iesultaat kan woiden teiuggegeven naai de voiige aanioep zodat deze
het iesultaat kan gebiuiken.
Naast de gewone iecuisie, woiden in Clojuie veel hogeie-oide func-
ties gebiuikt op plaatsen waai andeis iteiatie zou woiden toegepast. Highei-
oidei functions zijn functies die een andeie functie als aigument hebben, en
deze op n of meeide waaiden toepassen. map en reduce zijn veelgebiuikte
functies
Iisting .= Hogere orde Functie
1 (defn double [x] (* 2 x))
2 (map double [1 2 3])
3 ; Dit heeft hetzelfde resultaat als
4 ; [(double 1) (double 2) (double 3)] = [2 4 6]
5
6 (reduce + [1 2 3])
7 ; Dit vertaalt naar (+ (+ 1 2) 3), of in wiskunde
8 ; (1 + 2) + 3 = 6
9
10 ; Map werkt zelfs op meerdere lijsten:
11 (map * [1 2 3] [1 2 3])
12 ; Heeft hetzelfde resultaat als [(* 1 1)
13 ; (* 2 2) (* 3 3)] = [1 4 9]
1e
= VersHillen met Jaya
5.1 Key concepts van OO in Clojure
Een veel gemaakte opmeiking wanneei Clojuie woidt veigeleken met an-
deie JVM-talen is dat Clojuie niet OO is. Hieidooi woidt vaak de conclusie
getiokken dat Clojuie niet de key concepts van een OO taal heef. Clojuie
pakt deze concepten alleen andeis aan. Dit is veigelijkbaai met zeggen dat
een geweei niet pijl-geoiienteeid isHalo,b].
Encapsulation
Encapsulation is het veibeigen van de implementatiedetails zodat de gebiui-
kei van de code niet pei ongeluk amankelijk kan woiden van een imple-
mentatie. Op deze maniei kan de implementatie veiligei woiden aangepast,
omdat de gebiuikei ei niet diiect van amankelijk is.
Binnen class-based OO piogiammeeitalen woidt dit gedaan op class ni-
veau dooi modieis als public, piotected of piivate op te geven. De maniei
waaiop Clojuie encapsulation iealiseeit is dooi gebiuik te maken van closu-
ies, namespaces en immutability.
Closures
Een closuie sluit zich ovei de omgeving waai deze is aangemaakt. De clo-
suie onthoudt deze omgeving. Omdat veel piogiammeuis bekend zijn met
Javasciipt en deze taal hetzelfde piincipe bevat, volgt nu een vooibeeld van
wat ei bedoeld woidt met closuies in Javasciipt. Hieina volgt een vooibeeld
in Clojuie.
Iisting =.1 Closures in Jayascript
1 function create() {
2 var remembers = 5;
3 return function() {
4 return remembers;
1;
.. VERSCHlLLEN MET JAVA
5 }
6 }
7 alert(create()());
Het bovenstaande Javasciipt fiagment zal iesulteien in een aleitbox met
de tekst ..
1. function create { ... }, denieeit een functie genaamd cieate.
:. var remembers = 5 denieeit een vaiiabele genaamd iemembeis die
de waaide . bevat.
+. return function() { return remembers; } maakt een anonieme functie
aan die de waaide van de vaiiabele iemembei teiuggeef.
. alert(create()()) ioept de cieate functie aan die op zijn beuit diiect
de anonieme functie aanioept (daai is de extia () vooi) die veivolgens
de waaide van iemembeis teiuggeef.
Hetzelfde piincipe bevindt zich in Clojuie
Iisting =.z Closures in Clojure
1 (defn create []
2 (let [remembers 5]
3 (fn [] remembers)))
4 (println ((create)))
Het bovenstaande Clojuie fiagment zal iesulteien in een output van ..
1. (defn create [] ...) denieeit een functie genaamd cieate.
:. (let [remembers 5] ...) denieeit een vaiiabele genaamd iemembeis
die de waaide . bevat.
+. (fn [] remembers) maakt een anonieme functie aan die de waaide van
de vaiiabele iemembei teiuggeef.
. (println ((create))) ioept de cieate functie aan die op zijn beuit
diiect de anonieme functie aanioept (daai zijn die extia ionde haakjes
om de aanioep naai cieate vooi) die veivolgens de waaide van ie-
membeis teiuggeef.
1s
..1. KEY CONCEPTS VAN OO lN CLOJURE
ln dit geval is iemembeis piivate vooi de anonieme functie die is te-
iuggegeven dooi de functiecreate. Men kan iemembeis niet van buitenaf
benadeien. Deze vaiiabele is alleen beschikbaai binnen die closuie (gesloten
omgeving).
Closuies kunnen eenvoudig genest woiden en maken eig kiachtige en-
capsulations mogelijk. De data-oveikoepeling die closuies mogelijk maken
is veel kiachtigei dan het eenvoudige model dat woidt aangeboden dooi de
modieis piivate, piotected, public, etc. binnen OO talen. Closuies zijn na-
melijk veel exibelei in het aangeven welke data zichbaai mag zijn en welke
niet. Men is niet gebonden aan een stel gelimiteeide vooigeneeide scopes,
maai men kan zelf stiategieeen denieien. En een functie die gedenieeid is
binnen een closuie zal toegang hebben tot de vaiiabelen van zijn oveikoe-
pelende closuies, zelfs na het eindigen van de oveikoepelende functie.
Gebruik binnen de casus Binnen de casus hebben we veelvoudig gebiuik
gemaakt van closuies. Dit is vooial goed teiug te zien bij de functies die daad-
weikelijk de commandos uitvoeien.
Iisting =.+ Gebruik yan closures binnen de casus
1 (defn- new-train [id]
2 (try-if-exists :no id
3 (fn [coll] [(cons {:train id :twagons (list)} coll) [(
str > train id created)]])
4 (str no train created, id exists!)))
Zoals in het code te zien is, woidt ei een anonieme functie aangemaakt
waaiin woidt veiwezen naai het aigument id van de new-train functie. On-
danks datdeze anonieme functie eldeis in de code woidt aangeioepen behoud
deze nog wel de waaide van id.
Namespaces
Naast data encapsulation dooimiddel van closuies, ondeisteunt Clojuie na-
mespaces om geielateeide data en functies te gioepeien. Binnen een names-
pace kan een Clojuie vaiiable veiwijzen naai zowel data als functies en kan
public of piivate woiden gemaakt.
1,
.. VERSCHlLLEN MET JAVA
Iisting =. Public en priyate yariabelen in Clojure
1 (defn i-am-public [] public)
2 (defn- i-am-private [] private)
Het bovenstaande fiagment denieeit twee functies. Zoals de namen doen
blijken is de bovenste functie public en de ondeiste piivate. Het piivate ma-
ken woidt aangegeven dooi de - achtei defn.
Een vooideel van namespaces veigeleken met de encapsulation die clas-
ses bieden is dat men niet onnodig functies meei hoef te gioepeien. De
bekende statische Utils classes zijn hiei een goed vooibeeld van. Dooi het
gebiuikt hieivan komen vaak functies in classes te ziuen waai ze eigenlijk
niet thuis hoien. Bovendien kan ei veel tijd gaan ziuen in het bepalen waai
een functie thuishooit of vooi het bedenken van namen vooi eigenlijk niet-
bestaande gioepeiingen.
Gebruik binnen de casus Binnen de casus hebben we gebiuik gemaakt van
piivate functies die alleen beschikbaai zijn binnen de namespace waaiin ze
gedenieeid zijn. Dit is zoals al eeidei veinoemd te heikennen aan de -
postx binnen defn-.
Iisting =.= Gebruik yan namespaces binnen de casus
1 (defn- free-wagons [depot]
2 (filter (comp free-bool :status) (wagons depot)))
Bij de inteiop namespace denitie maken we gebiuik van de class gene-
iatie featuie die Clojuie biedt. Dooimiddel van :gen-class geven we aan dat
we van de code een Java class willen geneieien. Dit maakt inteiopability tus-
sen Java en Clojuie eig gemakkelijk.
Een andeie eigenschap die goed teiug te zien is het gebiuik van :use.
Met :use kan woiden aangegeven welke namespaces (of delen eivan) moe-
ten woiden gempoiteeid binnen de huidige namespace. Hieidooi woiden ze
beschikbaai in de huidige namespace alsof ze daaiin gedeneeid zouden zijn.
Iisting =.o Gebruik yan namespaces binnen de casus
1 (ns com.richrail.interop.exec
:o
..1. KEY CONCEPTS VAN OO lN CLOJURE
2 (:gen-class
3 :name com.richrail.console.ClojureExecutor
4 :prefix method-
5 :implements [com.richrail.console.Executor])
6 (:use com.richrail.core))
7
8 (defn method-execute [_ command]
9 (do-evaluate command))
Immutability
ln class-based OO piogiammeeitalen is nog een andei doel van encapsulati-
on het vooikomen dat object Ade inteine toestand van object Bs piivate data
niet zomaai kan aanpassen. Om deze ieden woidt het binnen class-based OO
talen aangeiaden om publieke velden en geuei-methodes (indien deze mu-
table data teiuggeven) te vooikomen.
ln Clojuie bestaat dit piobleem niet. Datastiuctuien zijn binnen Clojuie
namelijk immutable (onaanpasbaai). Het is onmogelijk om deze datastiuc-
tuien aan te passen of coiiupt te maken. Men kan dus piivate mutable state
teiuggeven zondei bang te zijn vooi datacoiiuptie. Ei hoeven geen tiucjes
zoals Data Tiansfei Objects (DTO) te woiden gebiuikt.
ln Java is standaaid alles mutable. Dit is een slecht uitgangspunt vooi
concuiiency. Mutable state is namelijk een bion van side eects. Mutable
state zoigt eivooi dat het eig moeilijk woidt om goed concuiient te pio-
giammeien in Java, want men moet continue iekening houden met eventue-
le wijzigingen. Omdat het ongewenst is dat state van buitenaf woidt aange-
past tijdens het veiweiken van een methode, woidt ei vaak gebiuik gemaakt
van locking. Bij locking moeten andeie thieads wachten tot de thiead die de
locking aanvioeg klaai is met zijn weik. ln Java is het modelleien naai de
weikelijkheid een belangiijk punt. Locking is niet veigelijkbaai met de wei-
kelijkheid Als bijvooibeeld tijdens een piesentatie iets woidt uitgelegd dat
lastig te volgen is, zal de piesentatoi niet langzamei gaan piaten. Locking
zoigt vooi veitiaging. lmmutable datastiuctuien maken het eenvoudig om
snapshots te maken en op deze maniei kunnen de toeschouweis onaman-
kelijk van elkaai hun weik amandelenHal11b].
ln Java mist goede suppoit vooi deze immutable datastiuctuien. Het ma-
ken van een deep copy is zo vaak eig lastigMil,,]. Dit komt dooidat Java
het amandelen van eigen veiantwooidelijkheden dooi classes aanmoedigt.
Dit is een mooi piincipe, maai in het geval van copy is het een show-stoppei.
:1
.. VERSCHlLLEN MET JAVA
Ovei het algemeen woidt alleen de copy method gemplementeeid zodia dit
noodzakelijk is. Als dit echtei niet gebeuit, houdt de copy chain daai op. De
inteine state die wellicht individueel wel kopieeibaai zou zijn, zal hieidooi
ook niet kopieeibaai zijn. Omdat dit type encapsualisatie in Clojuie niet be-
staat en Clojuie uitstekende ondeisteuning heef vooi immutable datatypes,
heef men geen last van dit piobleem.
Het missen van een goede copy-functie is echtei niet zozeei het pio-
bleem, want meeimaals een weikelijke kopie maken zou iesouicetechnisch
niet vooidelig zijn. Om weikelijk waaidevol te zijn moet deze ondeisteuning
vooial vanuit de taal zelf komen. ln Java is deze ondeisteuning niet aanwezig.
Men zou de immutable datastiuctuien van Clojuie in Java kunnen gebiuiken,
maai zo schiijf men geen idomatic Java code, ln Java is het bijvooibeeld niet
gebiuikelijk om een domain te speciceien in maps en vectoien.
Polymorphism
ln deze veigelijking woidt polymoiphism beschieven als het veimogen om
de implementatie van een methode af te laten hangen van het type van de
aanioepei.
Iisting =.; Jaya polymorhism
1 interface Walkable {
2 public void walk();
3 }
4 class Dog implements Walkable {
5 pblic void walk() {
6 System.out.println(Verzet poten naar voren.);
7 }
8 }
9 class Human implements Walkable {
10 public void walk() {
11 System.out.println(Verzet voeten naar voren.);
12 }
13 }
14 Walkable dog = new Dog();
15 Walkable human = new Human();
16 dog.walk();
17 human.walk();
::
..1. KEY CONCEPTS VAN OO lN CLOJURE
ln het bovenstaande vooibeeld is de implementatie van dog.walk() vei-
schillend met die van human.walk() aangezien de classes van een andei type
zijn.
Clojuie biedt een sooitgelijke functionaliteit genaamd multimethods.
Iisting =.8 Clojure multimethod denitie
1 (defmulti walk class)
Het bovenstaande vooibeeld beschiijf de denitie van een multimethod.
Alleieeist woidt een call naai de functie defmulti gemaakt. Hieina volgt de
naam die men wil geven aan de multimethod en als laatst aigumenten waai-
op de multimethod van toepassing is. ln dit geval willen we het bepalen van
de aangeioepen implementatie laten amangen van welke class de multime-
thod aanioept.
Iisting =.o Methodes yoor in de multimethod
1 (defmethod walk Dog [x] (move-paws-forward x))
2 (defmethod walk Human [x] (move-feet-forward x))
ln dit vooibeeld woiden twee veischillende implementaties van de me-
thode walk beschieven, amankelijk van de class. ln tegenstelling tot polymoi-
hism limiteeit dit men niet om de keuze alleen amankelijk te laten zijn van
het type. Het zou ook amankelijk kunnen zijn van andeie eigenschappen of
zelfs meeideie eigenschappen.
Iisting =.1o Afhangen yan meerdere eigensHappen
1 (defmulti walk
2 (fn [x] [(alive? x) (:animal x)]))
3 (defmethod walk [true true] [x] (move-paws-forward x))
4 (defmethod walk [true false] [x] (move-feet-forward x))
Zoals te zien zijn multimethods veel geneiiekei opgezet dan polymoiphism.
ln plaats van bij het bepalen van welke methode moet woiden aangeioepen
gelimiteeid te zijn tot het type, kan men het bepalen van multimethods laten
amangen van iedeie functie en aigumentenlijst naai wens. Dit is een veel
kiachtigei piincipe dan standaaid polymoiphism. Het gebiuik van multime-
thods zoigt ei tevens vooi dat het piogiammeeimodel dichtei bij de weike-
lijkheid ligt, in de weikelijkheid kunnen entiteiten immeis in de loop dei tijd
:+
.. VERSCHlLLEN MET JAVA
veiandeien van type. Als men bijvooibeeld een Child class in een domain
heef, dan moet het mogelijk zijn dat deze class in de loop dei tijd van Child
naai Adult veiandeit - tenminste als het domain gemodeleeid zou zijn naai
de weikelijkheid.
Gebruik binnen de casus Binnen de casus hebben we geen gebiuik hoeven
te maken van polymoiphism, omdat het een casus was waaibij we te maken
hadden met weinig veischillende en eenvoudige datastiuctuien.
Inheritance
ln class-based OOpiogiammeeitalen maakt inheiitance (oveieiving) het mo-
gelijk dat behavioui kan oveieiven van een basistype.
Iisting =.11 Jaya inheritance
1 class Person {
2 public String getFullName() { /* body */ }
3 }
4 class Employee extends Person {
5 public BusinessCard getBusinessCard() { /* body */ }
6 }
Dit type heigebiuik is zo vanzelfspiekend binnen Clojuie dat ei geen
apaite benaming vooi is.
Iisting =.1z Clojure functiehergebruik
1 (defn full-name [x]
2 (str (:first-name x) (:last-name x)))
3 (defn business-card [x]
4 [(full-name) (:mail-address x)])
ln het vooibeeld is een Employee een Peison, maai een Employee bevat
extia behavioui.
ln de Clojuie implementatie is deze extia behavioui gemplementeeid als
een nieuwe functie. Ei komt geen speciale syntax bij kijken, het is gewoon
een standaaid functie en heef geen besef van het Employee type. Het enige
wat van belang is vooi de functie is de aanwezigheid van de gebiuikte velden
:
..1. KEY CONCEPTS VAN OO lN CLOJURE
in de map.
Binnen Clojuie is het gebiuikelijk om dit sooit data op te slaan in een map of
een iecoid. Een iecoid heef stiengeie eisen dan een map (zoals welke velden
ei aanwezig moeten zijn) maai is biuikbaai als een map. Vooi het gebiuik
maakt het dus niet uit of van een map of een iecoid gebiuik woidt gemaakt.
Op dit moment woiden ei geen checks uitgevoeid om te testen of alle
velden aanwezig zijn in de map. Dit is ook niet noodzakelijk. Als het om een
publieke functie gaat, zou men eivooi kunnen kiezen om dit op te nemen in
de docstiing of aan de pie- en postcondities-map toe te voegen. Pie- en post-
condities zijn optioneel binnen een functiedeclaiatie en veivuilen dus niet
de body.
Iisting =.1+ Pre- en postcondities
1 (defn constrained-sqr [x]
2 {:pre [(pos? x)]
3 :post [(> % 16), (< % 225)]}
4 (* x x))
ln de Java-veisie is het alleen mogelijk omeen Employee omeen Busines-
sCaid te viagen. Bij de Clojuie-veisie hoef dit alleen iets te zijn wat lijkt op
een Employee. Ei staat namelijk neigens een iestiictie gedenieeid die be-
paalt dat alleen Employee-functies zijn toegestaan. Dit woidt duck typing
genoemd.
.
.
lf it walks like a duck and quacks like a duck, we assume it is a
duck, without asking it to piesent its lDuck papeis. .
.
Gebruik binnen de casus Net zoals polymoiphismhebben wij geen gebiuik
hoeven te maken van inheiitance, om dezelfde iedenen. Namelijk dat we een
ielatief weinig en eenvoudige datastiuctuien hadden binnen onze casus.
Veel functies, weinig types
Het voiige vooibeeld beschiijfnog een negatieve consequentie van het schiij-
ven in de idiomatic OO piogiammeeistijl. ln het Java-vooibeeld leveit het
opviagen van de BusinessCaid een instantie van het BusinessCaid-type op.
Elk nieuw type zoals BusinessCaid viaagt om een eigen levensloopsysteem,
zoals constiuctois, accessois, equals, etc.
:.
.. VERSCHlLLEN MET JAVA
ln de Clojuie-veisie leveit het opviagen van de businesscaid simpel-
weg een eenvoudige vectoi op. Geen nieuwe types, geen levensloopsysteem.
Daainaast kan een addiessbook nu woiden gemanipuleeid met de hele lading
sequencefuncties die Clojuie iijk is.
Iisting =.1 Jaya methode
1 // From Apache Commons Lang, http://commons.apache.org/lang/
2 public static int indexOfAny(String str, char[] searchChars)
{
3 if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
4 return -1;
5 }
6 for (int i = 0; i < str.length(); i++) {
7 char ch = str.charAt(i);
8 for (int j = 0; j < searchChars.length; j++) {
9 if (searchChars[j] == ch) {
10 return i;
11 }
12 }
13 }
14 return -1;
15 }
Het doel van indexOfAny is het bepalen wanneei de opgegeven chais searchChars
vooi het eeist vooikomen binnen de stiing str. Deze functie weikt echtei
dooi de statische typeiing alleen vooi stiings in combinatie met chai aiiays.
Iisting =.1= Clojure implementatie
1 (defn index-filter [pred coll]
2 (keep-indexed (fn [i x] (if (pred e) i)) coll)
Deze functie index-filter leveit niet alleen de eeist vooikomende van
n van de gezochte chais, maai alle matches. Deze functie geef van elke
match de indexes teiug, zoals de naam wellicht doet veimoeden
Iisting =.1o Meerdere indexes terug
1 (index-filter #{\a \e \i \o \o} The quick brown fox)
:e
..:. VElLlG CODEHERGEBRUlK
2 -> (2 6 12 17)
Omdat neigens is aangegeven dat het uitsluitend om chais moet gaan
weikt dezelfde functie ook op bijvooibeeld een lijst van integeis
Iisting =.1; Werkt ook yoor andere types
1 (index-filter #{2 3 5 7} (range 6))
2 -> (2 3 5)
Bovendien omdat Clojuie een LlSP is waaibij bijna alle syntax op dezelf-
de maniei weikt, kan men evengoed een functie meegeven als een set
Iisting =.18 Clojure is exibel
1 (index-filter #(> (.length %) 3) [The quick brown fox
])
2 -> (1 2)
Dit is een vooibeeld waaibij de kiacht van LlSP goed naai voien komt.
Deze vooibeeldfunctie is bovendien een stuk kleinei veigeleken de Java-
veisie.
Gebruik binnen de casus Binnen de casus hebben wij die piincipe aan-
gehouden. We hebben in veihouding veel meei functies dat datatypes. Dit
maakt het domain eenvoudigei en zoigt tot een beteie functionele style van
piogiammeien.
5.2 Veilig codehergebruik
ln een puui class-based OO taal zoals Java kan men alleen code heigebiuiken
dooi deze ovei te eiven van een andeie class. Hieidooi ziet men vaak class
hieiaichies ontstaan die losstaan van de weikelijkheid. Omdat classes veel
code delen woidt in deze gevallen - vaak vanuit het Dont Repeat Youiself
(DRY) piincipe - gekozen om zon hieiaichy te gebiuiken. Dit kost echtei
vaak uiteindelijk meei kosten aan ondeihoud, aangezien dooi gebiuik van
een veikeeide hieiaichy niet meei exibel met de wensen van de klant kan
woiden omgegaan. Vaak leiden deze ontweipen namelijk tot veischuivin-
gen in hieichies waaibij veel fout kan gaan. Kleine fouten in classes en diens
:;
.. VERSCHlLLEN MET JAVA
subclasses kunnen vaak eenvoudig woiden opgelost, maai bij gioteie wijzi-
gingen mist vaak het oveizicht welke gevolgen wijzigingen kunnen hebben
vooi diens subclasses.
Iisting =.1o Pas op yoor oyereryingen
1 class MyList {
2 ArrayList<Item> items;
3 void add(Item x) { ... }
4 void addAll(Collection<Item> xx) {
5 for (Item x: xx) {
6 add(x);
7 }
8 }
9 }
10 class MyLinkedList extends MyList {
11 LinkedList<Item> linkedItems;
12 void add(Item x) { ... }
13 }
Het vooigaande vooibeeld geef aan waai het oveieiven van een class
vooi pioblemen kan zoigen als de paientclass in de loop dei tijd woidt aan-
gepast. De MyList class heef een add en een addAll methode. De addAll me-
thode ioept op zijn beuit vooi iedei item de add methode aan. De subclass
MyLinkedList maakt hiei gebiuik van, en implementeeit daaiom alleen een
eigen add methode. Deze subclass gaat ei dus vanuit dat addAll altijd zijn add
zal gaan aanioepen.
Als in de loop dei tijd een andeie piogiammeui naai MyList kijkt en be-
denkt dat addAll veel ecientei zou zijn als deze methode diiect de lijst met
items zou bijweiken in plaats vooi iedei item een method call zou uitvoeien
Iisting =.zo Waar het mis kan gaan
1 class MyList {
2 ArrayList<Item> items;
3 void add(Item x) { ... }
4 void addAll(Collection<Item> xx) {
5 items.addAll(xx);
6 }
7 }
:s
..:. VElLlG CODEHERGEBRUlK
Bovenstaande code is een vooibeeld van een nieuwe situatie. Deze co-
de zal wat ecientei zijn, maai veivolgens is de subclass MyLinkedList stuk
gegaan, omdat deze subclass van de implementatie van zijn paientclass af-
hankelijk was. Een mooie uitspiaak hieiovei
.
.
lnheiitance of implementation happens any time you deiive fiom a
class that does things, and then tiy to change what that class does
slightly by oveiiiding pait of its implementation. l would desciibe this
as the code equivalent of an oigan tiansplant - lets just iip out the
pancieas, put a new one in (maybe its not even the same species) and
hope it all plays nice togethei.Supo;] .
.
De oplossing die talen zoals Java hieivooi bieden zijn inteifaces. lnteifa-
ces zijn echtei nogal een giove oplossing, ze lossen het piobleemwel degelijk
op (het piobleem zou zich niet zou hebben vooigedaan als men inplaats van
class-oveieiving inteifaces had gebiuikt), maai bij het gebiuik van inteifaces
vindt ei geen code heigebiuik plaats. Uiteiaaid kan veel van dit diiecte hei-
gebiuik woiden veiholpen dooi functionaliteit te delegeien naai een andei
object, maai dan komen een aantal van de hieiboven genoemde pioblemen
weei om de hoek kijken.
1. Men moet weei een nieuw type en diens levensloop denieien. Daai-
naast kan het lastig zijn om tot een goede en beschiijvende naam te
komen, aangezien het type vaak maai een gedeelte van iets uit de wei-
kelijkheid moet beschiijven.
:. Talen zoals Java zijn niet eig exibel in hun typesysteem en dus loopt
men tegen dezelfde pioblemen aan als beschieven staat bij het indexO-
fAny-vooibeeld. Om tot een geneiieke oplossing te komen die weikt
vooi alle classes die deze oplossing mogelijk zullen gaan gebiuiken
moet met veel aspecten iekening woiden gehouden, teiwijl dit bij Clo-
juie vaak van natuie al uit de taal komt.
+. De applicatie gioeit snellei. Dit is niet noodzakelijk slecht, maai dit
zoigt ei wel vooi dat het oveizicht snellei kan woiden kwijtgeiaakt.
Clojuie echtei is een functionele piogiammeeitaal. Dit houdt in dat func-
ties, mits ze toegankelijk zijn (in namespaces kunnen functies piivate woi-
den gemaakt), viij heigebiuikt kunnen woiden. luncties zijn dus niet zoals
:,
.. VERSCHlLLEN MET JAVA
in Java gekoppeld aan een speciek type. Het piobleem van onveilig hei-
gebiuiken woidt opgelost dooi geen gebiuik te maken van side-eects. En
van de doelen van lP is functies zondei side-eects te schiijven. Het kan
echtei pei implementatie veischillen hoe stiict dit doel woidt genomen zo
zijn side-eects binnen Clojuie wel toegestaan - aangezien men in de ieali-
teit nu eenmaal te maken heef met side-eects - maai het gebiuik woidt wel
afgeiaden en ei zijn speciale naamconventies omhieivooi te waaischuwen
1
.
Nog een belangiijke factoi die het heigebiuik mogelijk maakt is dat alle
datastiuctuien binnen Clojuie standaaid immutable zijn, wat het mogelijk
maakt om sooitgelijke contiacten te maken als bij inteifaces. Bij een functie
zondei side-eects is het namelijk ook het geval dat men bij een bepaalde
input (aigumenten) altijd dezelfde output zal kiijgen, onamankelijk van de
implementatie. Hieidooi heef men zowel de vooidelen van inteifaces als de
vooidelen van compositie en inheiitance, zondei dat men steeds veiplicht is
om een afweging te maken tussen een nieuwe inteiface intioduceien, inheii-
tance toepassen of kiezen vooi compositie.
Gebruik binnen de casus We hebben waai nuuig code heigebiuik toege-
past. Een goed vooibeeld hieivan in de casus is de try-if-exists functie.
Deze functie woidt gebiuikt om te bepalen of een tiein of wagon bestaat.
Als dit niet het geval is maakt de functie hieivooi een foutmelding aan.
Iisting =.z1 Gebruik yan code hergebruik binnen de casus
1 (defn- try-if-exists [exist id f error]
2 (fn [coll]
3 (if ((exists? exist) (some (comp (partial = id) obj-id)
coll))
4 (f coll)
5 [coll [(str > error)]])))
1
Dit woidt gedaan dooi een uitioepteken (') achtei de functie naam te plaatsen.
+o
o Casus RiHRail
Om een goede veigelijking te kunnen maken tussen Java en Clojuie hebben
we besloten een pioject van het vak Paueins & liamewoiks (zie appendix
B) ook in Clojuie uit te weiken. ln dit hoofdstuk schetsen wij de opbouw
van de Clojuie veisie, vooidelen die we hebben ondeivonden en moeilijk-
heden die we zijn tegengekomen bij de implementatie, en enige belangiijke
veischillen met de Java-veisie.
6.1 Software patterns en ontwerp
Waai we in de Java-veisie veel tijd kwijt zijn geweest aan het ontweipen van
onze applicatie (UML schemas en deigelijke) is dit in Clojuie veel mindei
noodzakelijk gebleken. De eeiste veisie is iedelijk bouom-up ontstaan, met
simpele datastiuctuien vooi de belangiijke objecten (geneste lijsten, vecto-
ien en hash-maps) en functies die hieiop weiken. Deze functies zijn veivol-
gens geabstiaheeid om de hoeveelheid dubbele code teiug te biengen Zodia
een functie weid geschieven die op veel punten oveieenkwam met een be-
staande, is de functionaliteit van deze functie opgedeeld in een gezamelijk
deel en een functiespeciek deel, die in Clojuie weei makkelijk te koppelen
zijn. De muteeibaie toestand, het depot (een lijst tieinen en een lijst wagons),
is in een atom gezet.
Latei is de code gedeeltelijk heischieven, waaibij gepiobeeid is meei top-
down te weiken. ln de casus zijn namelijk e.g. het uitvoeien van een func-
tie op het gehele depot en het enkel toepassen van een functie op de wa-
gons of de tieinen beide veelvooikomende acties (nagenoeg alle functies
helpeifuncties daaigelaten zijn in te delen in deze diie categoiien). Deze
top-level functies accepteien als aigument een functie die weei specieke-
ie taken vooi zich neemt. Ook zijn deze functies vooizien van de Log mo-
nad, die veideiop woidt uitgelegd. Koit gezegd zoigt deze monad eivooi dat
naast een iesultaat ook een log-boodschap kan woiden teiuggegeven, en dat
meeideie logboodschappen achteieen woiden gezet. Deze logboodschappen
kunnen dan bij het veiweiken woiden uitgepiint, zodat dit niet tijdens de
swap! functie van het atom gebeuit, en potentieel meeideie keien geschiedt.
+1
e. CASUS RlCHRAlL
6.2 De Java-versie
Bij de Java-veisie hebben we eeist veel tijd gestoken in het ontweipen van
de applicatie. We hebben hiei extia aandacht aan besteed omdat het vooi
het vak Paueins & liamewoiks was bestemd en we hoofdzakelijk weiden
beooideeld op onze sofwaiedesign-keuzes. We hebben hieivooi veischillen-
de technieken toegepast. Alleieeist hebben we een inventaiisatie gemaakt
van de veieisten van het pioject. Daaina zijn we gaan biainstoimen ovei de
mogelijke indelingen van de applicatie en aspecten waai iekening mee ge-
houden moest woiden. Om een goed oveizicht te kiijgen van de applicatie
hebben we eeist een class-diagiam gemaakt. Dit diagiam hebben we gedu-
iende het pioject steeds veidei uitgebieid. We hebben gepiobeeid om zoveel
mogelijk zinvolle abstiacties te implementeien en vooi de juiste design pat-
teins te kiezen. We hebben ons design echtei niet laten leiden dooi design
paueins, aangezien paueins niet automatisch de oplossing zijn vooi alle pio-
blemen.
Binnen de applicatie is ei een scheiding gemaakt tussen een view-kant
en een model-kant. Hieibij is uitgegaan van de hypothetische situatie waaiin
de view dooi een andeie gioep piogiammeuis zou zijn ontwikkeld. De view
kan enkel via de Command Line lnteiface (CLl) wijzigingen aanbiengen aan
de state van de model-kant. De Depot class dient als biug tussen de view- en
model-kant. De scheimen van de view kunnen luisteien naai de Depot, en als
ei een wijziging is toegepast zullen de scheimen hiei melding van kiijgen.
Deze scheimen kunnen veivolgens de nieuwe state opviagen bij het Depot.
Het is echtei belangiijk om op te meiken dat de view-kant onmogelijk diiect
toegang kan kiijgen tot model-objecten via het Depot, de view-kant kan al-
leen een veizoek doen om de nieuwe state op te viagen. De state die woidt
teiuggegeven bestaat uit een collectie van state-objecten volgens het Data
Tiansfei Object (DTO) design pauein. Op die maniei kan een klant wel wij-
zigingen maken aan deze objecten, maai zullen de wijzigingen niet woiden
dooigevoeid op de daadweikelijke model-objecten.
Om de CLl commands te paisen woidt gebiuikt gemaakt van ANothei
Tool foi Language Recognition (ANTLR). ANTLR is een paisei-geneiatoi
die aan de hand van een giammaticabestand een complete compilei kan
geneieien. Omdat in de aangeleveide documentatie gebiuik weid gemaakt
van een notatiewijze die giotendeels oveieenkomt met die van ANTLR en
ANTLR bovendien goed bekend staat, hebben wij eivooi gekozen om on-
ze paisei in ANTLR te speciceien. We hebben hieivooi de aangeleveide
giammatica aangepast zodat deze confoim de ANTLR-specicatie was. Vei-
volgens hebben we inline Java code toegepast om commands naai het juiste
command-object te delegeien, waai de daadweikelijke amandeling plaats-
+:
e.+. DE CLOJURE-VERSlE
vindt.
6.3 De Clojure-versie
Core
Centiaal in de coie module staat het depot de datastiuctuui die de tieinen
en wagons bevat. Het depot is een vectoi die twee lists bevat. Het depot is
opgeslagen in een atom, een datastiuctuui vooi mutable state die veideiop
zal woiden behandeld.
Iisting o.1 Depot
1 (def depot (atom [(list) (list)]))
Een tiein en wagon woiden gedenieeid als een hash-map. Een tiein be-
vat een id stiing, met als keywoid :train om makkelijk heikenbaai te zijn
en een lijst :twagons waaiin de wagons als id woiden opgeslagen. Wagons
bevauen een id met als keywoid :wagon, een aantal seats (als een getal, key-
woid :seats) en een waaide :status die :free kan zijn vooi een losse wagon
of :connected vooi een wagon aan een tiein.
Iisting o.z Train en Wagon
1 [:train id :twagons (list)]
2 [:wagon id :seats int :status :free]
Daainaast woiden een aantal functiesynoniemen en simpele helpeifuncties
gedenieeid, zodat de uiteindelijke code duidelijkei leesbaai is
Iisting o.+ Helper Functies
1 (def wagons first)
2 (def trains second)
3 (def obj-id second)
4
5 (def select {:trains trains :wagons wagons})
6 (def other {:trains wagons :wagons trains})
7 (def order {:trains partial :wagons (fn [f x] (fn [y] (f y
x)))})
8 (def free-bool {:free true :connected false})
9 (def exists? {:yes identity :no not})
10
++
e. CASUS RlCHRAlL
11 (defn- find-first [id coll]
12 (first (filter (fn [x] (= (obj-id x) id)) coll)))
Vooigaande functies moeten iedelijk vooi zich spieken. De volgende functies
veigen misschien iets meei toelichting. free-wagons zoekt alle wagons die
niet aan een tiein zijn gekoppeld. Dit gebeuit dooimiddel van een filter
met als piedicaat een functie die het :status veld van een wagon omzet tot
een boolean.
apply-to-id-only is een functie met een collectie, een id en een functie
die een collectie teiuggeef, en daaibij f toepast op alle waaiden met het
geviaagde id.
Iisting o. Nog meer helperfuncties
1 (defn- free-wagons [depot]
2 (filter (comp free-bool wagon-free?) (wagons depot)))
3
4 (defn- apply-to-id-only [coll id f]
5 (map (fn [x] (if (= (obj-id x) id)
6 (f x)
7 x))
8 coll))
9
10 (defn try-if-exists [exist id f error]
11 (fn [coll]
12 (if ((exists? exist) (some (comp (partial = id) obj-id)
coll))
13 (f coll)
14 [coll [(str > error)]])))
Vooi de meeste functies geldt dat deze enkel uitgevoeid dienen te woi-
den indien een object met de geviaagde id wel of juist niet bestaat Een tiein
toevoegen met een bestaand id moet woiden vooikomen, net als het veiwij-
deien van een tiein wiens id niet vooikomt. Met de functie try-if-exists kan
dit makkelijk woiden beweikstelligd. De functie neemt een keywoid :yes of
:no die aangeef of de id wel of niet al moet bestaan, een id, een functie die
al dan niet woidt toegepast en een zinvolle foutmelding vooi het geval dat
de functie niet woidt uitgevoeid. Meik op dat deze functie en de meeste vol-
gende, in de log-monad staan (zie appendix A). Vooilopig woidt nog niets
speciek monadisch gedaan, en woidt enkel een waaide teiuggegeven die
opgebouwd is in de monad. Bij de log-monad houdt dat in dat naast het ie-
sultaat ook een monode woidt teiuggegeven (zie appendix A), in dit geval
+
e.+. DE CLOJURE-VERSlE
een lijst van stiings die eventuele beiichten vooistellen. Resultaat en loglijst
voimen samen een vectoi
1 (defn try-if-exists [exist id f error]
2 (fn [coll]
3 (if ((exists? exist) (some (comp (partial = id) obj-id)
coll))
4 (f coll)
5 [coll [(str > error)]])))
De eeiste echte functie die woidt gedenieeid is de functie om een nieu-
we tiein te maken. Als een tiein met het opgegeven id nog niet bestaat, woidt
een functie gemaakt die een tiein met het gegeven id aan een collectie toe-
voegt. Deze woidt samen met een log-beiicht teiuggegeven. Als de tiein al
bestaat woidt enkel een log-beiicht teiuggegeven.
1 (defn new-train [id]
2 (try-if-exists :no id
3 (fn [coll] [(cons {:train id :twagons (list)} coll) [(
str > train id created)]])
4 (str no train created, id exists!)))
new-train maakt een functie in plaats van dat een depot diiect woidt
aangepast. Dit gebeuit omdat new-train enkel aangeioepen woidt vanuit de
functie do-to, die een functie als iesultaat veiwacht. do-to maakt een nieuwe
functie die de iesultaat-functie van bijvooibeeld new-train toepast op een col-
lectie binnen een gegeven depot. Meteen denieien we twee helpei-functies,
die iespectievelijk de tieinen en de wagons binnen het depot aecteien
1 (defn do-to [obj-type func]
2 (fn [depot]
3 (let [selected (func ((select obj-type) depot))
4 others ((other obj-type) depot)]
5 (with-monad log-m
6 (m-bind selected (comp m-result ((order obj-type)
vector others )))))))
7
8 (def in-trains (partial do-to :trains))
9 (def in-wagons (partial do-to :wagons))
De functie die gemaakt woidt in do-to woidt op zijn beuit weei aange-
ioepen vanuit een andeie functie die de iesultaat-functie toepast op het de-
+.
e. CASUS RlCHRAlL
pot binnen een atom, en gelijk de geaggiegeeide log-beiichten achtei elkaai
uitpiint
1 (defn modify! [at funcs]
2 (let [action (with-monad log-m (m-chain funcs))
3 [_ msg] (action @at)]
4 (swap! at (comp first action))
5 (doseq [msg msg] (println msg))))
Nu we deze functies hebben, kunnen we nog een aantal functies denie-
ien die vanuit do-to kunnen woiden aangeioepen. Sommige functies gebiui-
ken een extia aigument, zoals new-wagon die (mogelijk) een aantal stoelen
meekiijgt, en set-wagon, die een wagon zowel op :connected als :free kan
zeuen. wagon-to-train en wagon-from-train hebben logischeiwijs twee ids
nodig, een tiein en een wagon.
Iisting o.= Enkele Functies
1 (defn new-wagon [id & arg]
2 (try-if-exists :no id
3 (fn [coll] (let [seats (if (nil? arg) 20 (first arg))]
4 [(cons {:wagon id :seats seats :status :free} coll)
[(str > wagon id created)]]))
5 (str no wagon created, id exists!)))
6
7 (defn get-train [id]
8 (try-if-exists :yes id
9 (fn [coll]
10 [coll [(str > number of seats in train id :
11 (apply + (map (fn [x] (wagon-seats (
find-first x (wagons @depot))))
12 (train-wagons (find-first id
coll)))))]])
13 (str train id does not exist!)))
14
15 (defn set-wagon [id is-free]
16 (try-if-exists :yes id
17 (fn [coll] [(apply-to-id-only coll id (fn [wagon] (assoc
wagon 3 is-free))) [(str > wagon id is now (
name is-free))]])
18 (str I cannot alter id for it does not exist!)))
19
20 (defn get-wagon [id]
+e
e.+. DE CLOJURE-VERSlE
21 (try-if-exists :yes id
22 (fn [coll] [coll [(str > number of seats in wagon id
: (wagon-seats (find-first id coll)))]])
23 (str wagon id does not exist)))
24
25 (defn del-vehicle [id]
26 (try-if-exists :yes id
27 (fn [coll] [(remove (comp (partial = id) obj-id) coll)
[(str > id deleted)]])
28 (str id not deleted, it wasnt there to begin with!
)))
29
30 (defn wagon-to-train [wagon-id train-id]
31 (try-if-exists :yes train-id
32 (fn [coll] [(apply-to-id-only coll train-id
33 (fn [train] (assoc train 2 (conj (train-wagons train)
wagon-id))))
34 [(str > wagon-id added to train-id)
]])
35 (str no wagons can be added to train-id for it
does not exist!)))
36
37 (defn wagon-from-train [wagon-id train-id]
38 (try-if-exists :yes train-id
39 (fn [coll] [(apply-to-id-only coll train-id
40 (fn [train] (assoc train 2 (remove (partial = wagon-id
) (train-wagons train)))))
41 [(str > wagon-id removed from
train-id)]])
42 (str no wagons can be removed from train-id for
it does not exist!)))
Sommige functies moeten simultaan met een andeie functie woiden toe-
gepast op twee veischillende collecties. Als een wagon aan een tiein woidt
gekoppeld moet de wagon ook meteen als veibonden woiden aangemeikt.
Ook andeisom, als een wagon woidt losgekoppeld moeten zowel de tiein
als de wagon woiden aangepast. Hieivooi bestaat de functie do-to-both, die
twee functies als aigument neemt en de eeiste toepast op de wagons en de
tweede op de tieinen. Dankzij het gebiuik van de log-monad kunnen beide
functies in n keei woiden behandeld, waaidooi ook de modify! functie (en
daaiin de swap! functie) maai n keei woidt aangeioepen. Beide acties zijn
dus samen atomaii. Om eenheid te cieeeien met de functies in-trains en
in-wagons woidt ook het synoniem in-both gedenieeid.
+;
e. CASUS RlCHRAlL
Iisting o.o Functies op twee collecties
1 (defn do-to-both [wfunc tfunc]
2 (fn [depot]
3 (with-monad log-m
4 ((m-chain [(in-trains tfunc) (in-wagons wfunc)])
depot))))
5
6 (def in-both do-to-both)
Op het moment woiden alle functies nog aangeioepen als (modify! depot
[(in-trains (get-train tr1))]). Om dit een beetje te stioomlijnen woiden
synoniemen gedenieeid vooi de binnenste twee functie aanioepen. modi-
fy! blijf op zichzelf, zodat ook lijsten van acties makkelijk atomaii kunnen
woiden behandeld.
Iisting o.; Nog meer synoniemen
1 (defn new-wagon-cmd [id] (in-wagons (new-wagon id)))
2 (defn new-train-cmd [id] (in-trains (new-train id)))
3 (defn del-wagon-cmd [id] (in-wagons (del-vehicle id)))
4 (defn del-train-cmd [id] (in-trains (del-vehicle id)))
5 (defn get-wagon-cmd [id] (in-wagons (get-wagon id)))
6 (defn get-train-cmd [id] (in-trains (get-train id)))
7
8 (defn add-wagon-to-train-cmd [wid tid]
9 (in-both (set-wagon wid :connected) (wagon-to-train wid
tid)))
10
11 (defn remove-wagon-from-train-cmd [wid tid]
12 (in-both (set-wagon wid :free) (wagon-from-train wid tid))
)
Tot slot woidt een simpele REPL gemaakt, die de gebiuikei in staat stelt
commandos uit te voeien zoals in de opdiacht staat beschieven. De functie
do-evaluate woidt toegepast op iedeie stiing die in de REPL woidt ingevoeid
(met uitzondeiing van de stiing quit die de loop bieekt). ln do-evaluate
woidt de gecombineeide paisei op de stiing losgelaten en als de paisei slaagt
geef deze een functie teiug die op het depot woidt toegepast. Zo niet, dan
woidt dit aan de gebiuikei kenbaai gemaakt.
Iisting o.8 De REPI
+s
e.+. DE CLOJURE-VERSlE
1 (defn do-evaluate [string]
2 (let [[func str] (parse-command string)]
3 (if (not (nil? func))
4 (println (eval (func depot)))
5 (println Nothing happens...))))
6
7 (defn repl []
8 (print # )(flush)
9 (let [input (read-line)]
10 (if (not (= input quit))
11 (do (do-evaluate input)
12 (recur)))))
Parser
De paisei die we hebben gebiuikt vooi RichRail is gebaseeid op de paisei die
beschieven staat in Monadic Parsing in Haskell HM,s]. We hebben eivooi
gekozen de paisei zelf te schiijven omdat dit een duidelijk vooibeeld is van
hoe lP tot duidelijke neue code kan leiden. De paisei moest de volgende code
kunnen paisen
BaHus-Naur Form yan de grammatica
grammar RichRail;
command : newcommand | addcommand | getcommand | delcommand | remcommand;
newcommand : newtraincommand | newwagoncommand;
newtraincommand : new train ID;
newwagoncommand : new wagon ID (numseats NUMBER)?;
addcommand : add ID to ID;
getcommand : getnumseats type ID;
delcommand : delete type ID;
remcommand : remove ID from ID;
type : (train) | (wagon);
ID : (a..z)(a..z|0..9)*;
NUMBER : (0..9)+;
WHITESPACE : ( \t | | \r | \n| \u000C )+;
De paisei is opgebouwd uit simpele paiseis, die bijvooibeeld een teken
of een stiing paisen, zoals in de volgende vooibeelden
+,
e. CASUS RlCHRAlL
Iisting o.o Parser om een bepaald Haracter te parsen
1 (defn- any-char [strn]
2 (if (= strn)
3 nil
4 (list (first strn) (. strn (substring 1)))))
5
6 (defn- char-test [pred]
7 (domonad parser-m
8 [c any-char
9 :when (pred c)]
10 (str c)))
11
12 (defn- is-char [c]
13 (char-test (partial = c)))
Iisting o.1o Parser yoor een bepaalde string
1 (defn- match-string [target-strn]
2 (with-monad parser-m
3 (if (= target-strn)
4 (m-result )
5 (domonad parser-m
6 [c (is-char (first target-strn))
7 cs (match-string (apply str (rest
target-strn)))]
8 (str c cs)))))
Iisting o.11 Parser yoor een new command
1 (def new-command-parser
2 (domonad parser-m
3 [ _ (match-string new)
4 _ whitespace
5 obj-type type-parser
6 _ whitespace
7 id id-parser
8 seats (optional numseats-parser)
9 ]
10 (if (= obj-type train)
o
e.+. DE CLOJURE-VERSlE
11 (fn [depot] (com.richrail.core/modify! ~depot [(
new-train-cmd ~id)]))
12 (if (nil? seats)
13 (fn [depot] (com.richrail.core/modify! ~depot [(
new-wagon-cmd! ~id)]))
14 (fn [depot] (com.richrail.core/modify! ~depot [(
new-wagon-cmd! ~id ~seats)]))))))
Iisting o.1z Parser yoor alle commands
1 (def parse-command
2 (m-plus [add-command-parser new-command-parser
get-command-parser delete-command-parser,
3 remove-command-parser, print-command-parser]))
1
; Clojure als lesstof
En van onze ondeizoeksviagen luidt Zou de Hogeschool Utiecht ei goed
aan doen om lP in het infoimatica-cuiiiculum op te nemen`. Op het mo-
ment van schiijven woidt op computeitechnische opleidingen op de Hoge-
school Utiecht lesgegeven in o.a. de volgende talen Java, C, C-- en Cr. Dit
zijn uitsluitend impeiatieve piogiammeeitalen. De viaag is of studenten ei
baat bij zouden hebben om naast deze talen les te kiijgen in declaiatieve,
functionele piogiammeeitalen zoals Clojuie.
Het afgelopen semestei hebben wij als studenten met piogiammeeiei-
vaiing in vooinamelijk impeiatieve OO talen kennis gemaakt met functi-
oneel en declaiatief piogiammeien in Clojuie. Omdat Clojuie bovenop de
JVM diaait en bovendien goede ondeisteuning heef vooi Java-inteiop (het
gebiuik van Java-classes in Clojuie), was de diempel van het leien van een
nieuwe piogiammeeitaal betiekkelijk laag.
Het schiijven van juiste, idiomatic code in Clojuie veieist een gioten-
deels nieuwe maniei van denken We moesten vanaf sciatch beginnen met
een Hello Woild-piogiamma en hebben vanaf daai veidei geleeid. Vanaf
hiei ging het echtei ielatief snel, mede omdat we teiug konden vallen op
Java-inteiop.
Naast de vele giatis online beschikbaie documentatie, waaiondei ociele
documentatie en community documentatie, beschikt Clojuie ovei een inke
community die online suppoit leveit via foia, mailinglists en chatkanalen.
Daainaast hebben we gebiuik kunnen maken van enkele goede leeiboeken
van technische uitgeveiijen (zie hieivooi onze bibliogiae).
Het piogiammeien in Clojuie heef ons geleeid te piogiammeien vol-
gens het functionele paiadigma, waaidooi we onszelf nu zondei veel moei-
te andeie (toekomstige) talen uit ditzelfde paiadigma kunnen aanleien. Als
de veiwachtingen kloppen en dankzij haidwaieontwikkelingen functionele
piogiammeeitalen in de nabije toekomst veel aan populaiiteit toenemen, is
dit een waaidevolle competentie. Bovendien hebben we hieidooi op een an-
deie maniei naai piogiammeeipioblemen leien kijken.
Een andeie ieden omomondeiwijs te geven ovei lP is dezelfde ieden dat
+
;. CLOJURE ALS LESSTOl
de Hogeschool Utiecht zich bezig houdt met ondeiwijs in Game Develop-
ment Het is een maniei om zich te ondeischeiden van andeie hogescholen.
Wij zouden het een zeei positieve ontwikkeling vinden als de Hogeschool
Utiecht de huidige lesstof in piogiammeien zou aanvullen met ondeiwijs in
lP. Hiei is Clojuie een bijzondei geschikte taal vooi.

8 Nawoord
8.1 Programmeren blijft mensenwerk
Ondanks dat het bij piogiammeien het ei uiteindelijk omdiaait omeen com-
putei aan te stuien, blijf piogiammeeiweik menselijk weik. Om die ieden
zijn ei veel menselijke eigenschappen teiug te vinden bij het ontwikkelen
van sofwaie. De keuze van een piogiammeeitaal bijvooibeeld - wat is de
ieden dat piogiammeeitalen met een beteie featuieset niet pei se meei ge-
biuikt woiden` Dit komt dooidat ei een giote menselijke factoi meespeelt.
Om deze ieden blijf de sofwaieweield vaak achteilopen op de haidwaie-
weield.
Bij de keuze van haidwaie zal eeidei vooi de haidwaie met beteie speci-
caties woiden gekozen woiden, omdat de menselijke factoi hieibij mindei
aanwezig is. Een ieden waaiom deze factoi zoveel steikei is bij sofwaie, is
bijvooibeeld dat piogiammeuis die vooinamelijk bepaalde piogiammeeita-
len zullen gebiuiken, ook in deze talen zullen gaan denken - dit is iets heel
menselijks. Het veiandeien van piogiammeeitaal heef daaiom ook een veel
gioteie impact vooi een piogiammeui dan het veiandeien van haidwaie.
Ei woidt wel eens de claim gemaakt dat Clojuie een beteie Java zou zijn
dan Java zelfHal11a], vanwege de goede inteiop en de featuies die Clojuie
biedt. Dit is echtei niet zwait op wit ei speelt altijd een menselijke factoi
mee. Een eivaien Java-piogiammeui zal ongetwijfeld betei piesteien met
Java dan met met Clojuie, omdat de piogiammeui bekend is met de Java-
cultuui en de bijbehoiende tools. Bovendien weet de piogiammeui zich betei
uit te diukken in Java dan in Clojuie, ook al zou Clojuie (theoietisch gezien)
expiessievei zijn.
Het is gevaailijk om te claimen dat een piogiammeeitaal betei is dan een
andeie. Dit kan wellicht vooi n peisoon gelden, maai hoef niet noodzak-
lijk vooi een andei te gelden. De featuieset van een taal is van gioot belang,
maai de menselijke factoi moet niet moeten ondeischat. Dit is de hoofdieden
dat Smalltalk ten ondei is gegaanMaio,]. Dooidat Smalltalk op dat moment
een beteie featuieset had dan de meeste andeie piogiammeeitalen van die
tijd, vonden de piogiammeuis zichzelf betei dan de iest en sloten ze zich
uiteindelijk af van de buitenweield.
.
s. NAWOORD
Dit is veigelijkbaai met nationalistisch gediag Als een land eig nationa-
litisch is, zal men zich als buitenstaandei daai mindei snel pieuig voelen en
het land lievei mijden. Ditzelfde gebeuit binnen piogiammeeitalen en diens
cultuien. Net zoals het belangiijk is om als peisoon cultuui op te doen vooi
de ontwikkeling, is het belangiijk om als piogiammeui kennis te maken met
andeie piogiammeeicultuien, waaiondei andeie paiadigmata.
e
o Conclusie
Clojuie is een veelbelovende jonge LlSP, geschieven vooi de JVM. De eeiste
ielease was in :oo;. De huidige stable veisie is 1.:.1.
ln tegenstelling tot bekendeie talen zoals Java, C-- en Cr, is Clojuie een
functionele, declaiatieve taal. Dit in tegenstelling tot vooigenoemde talen,
die ondei het impeiatieve en OO paiadigma vallen. ledei paiadigma heef zo
zijn steikeie en zwakkeie punten.
lP heef enkele vooidelen ten opzichte van andeie paiadigmata. luncties
met duidelijke in- en uitgangen zijn gemakkelijk te lezen en te begiijpen. Bo-
vendien zijn multicoie-machines in staat om functies die onamankelijk van
elkaai woiden geevalueeid paiallel uit te voeien, iets wat een diastische vei-
beteiing van peifoimance kan betekenen.
Clojuie heef dynamic, stiongly-typed typeiing. Java heef daaientegen
static typed typeiing. Java gebiuikt mutable datastiuctuies, Clojuie immuta-
ble datastiuctuies. Hieidooi gebiuikt Clojuie iecuisie om te iteieieien ovei
e.g. een lijst met data.
Wij denken dat de HU ei goed aan zou doen om lP in het cuiiiculum
op te nemen. Het leien van andeie piogiameeipaiadigmata is een belang-
iijke ontwikkeling vooi een piogiammeui omdat hij op deze wijze zal leien
om op andeie manieien tegen een piobleem aan te kijken. Daainaast zal een
piogiammeui leien wat de steike en zwakke punten van declaiatieve paia-
digmata zijn tegenovei impeiatieve paiadigmata.
;
A AHterliggende theorie en
wiskunde
A.1 Monads
Hoewel monads in Clojuie mindei vaak gebiuikt woiden dan sommige an-
deie functionele talen (e.g. Haskell) zijn ei zekei situaties waaiin ze nuuig
zijn. ln tegenstelling tot in Haskell zijn monads in Clojuie geen noodzake-
lijkheid, maai kunnen ze wel helpen elegante en duidelijke code te schiijven,
zoals in het geval van onze paisei. Ook in de coie van onze applicatie woidt
een monad gebiuikt vooi het bijhouden van log-boodschappen. monads zijn
een concept uit de categoiietheoiie, een abstiact deelgebied van de modeine
wiskunde. De categoiietheoiie beschiijf veischillende categoiien met daai-
in objecten en moismen die tussen die objecten weiken, wat zich veitaalt
in typen en functies in functionele piogiammeeitalen.
Een monad binnen de categoiietheoiie is een combinatie van functoi (een
map van n categoiie naai een andeie), waaibij iedei object en iedei mois-
me woidt geassocieeid met een object of moisme in een andeie categoiie
Als C en D categoiien zijn is l een functoi die van C naai D mapt. l
associeeit iedei object X C naai F(X) D en iedei moisme f : X
Y C naai F(f) : F(X) F(Y ) D, waaibij geldt dat F(id
X
) = id
F(X)
vooi iedei object X C en F(g f) = F(g) F(f) vooi alle moismen
f : X Y en g : Y Z.
Een monad is de combinatie van een functoi en twee natuuilijke tiansfoi-
maties, in Clojuie m-result en m-join geheten, waaibij m-result een waaide
in de monad zet (O M(O)) en m-join een geneste monad een laag teiug
biengt (M(M(O)) M(O)). Dooi deze twee tiansfoimaties te combine-
ien is een nuuigeie tiansfoimatie te maken, die dan ook vakei woidt gebiuikt
in de piogiammeeiweield, en dooi de meeste mensen samen met m-result
woidt gezien als de functies waaiuit een monad bestaat. Deze functie heet
m-bind, en ziet ei uit als volgt M(O) (O M(P)) M(P). Deze
functie maakt het dus mogelijk een monadische waaide in te voeien in een
functie die van een gewone waaide een monadische maakt (een monadi-
sche functie. Hieidooi is het dus mogelijk een seiie monadische functies aan
elkaai te koppelen.
Goed, zovei de theoiie, wat betekent dit nu vooi het piogiammeien ei-
mee` Een monad stelt de piogiammeui in staat een waaide in een monad
,
A. ACHTERLlGGENDE THEORlE EN WlSKUNDE
te plaatsen, en via m-bind (of in het geval van onze code, domonad, een ma-
cio die zoigt vooi syntactische suikei) te combineien. De meeiwaaide van
een waaide in een monad, is dat amankelijk van de monad meei waaiden of
zelfs functies (denk eiaan, functies zijn ook waaiden, of eigenlijk andeisom)
ondei watei mee te smokkelen zijn. Denk hiei bijvooibeeld aan toestand of
een logbestand. Dooidat de compositie van monadische functies met m-bind
gebeuit is het tiiviaal deze functie vooi een monad zo te denieien dat de-
ze extia waaiden meegenomen woiden zondei dat de piogiammeui daai
iekening mee moet houden.
A.2 De Parser monad
De Paisei monad is gedenieeid dooi twee standaaid-monads te combine-
ien Het is een tiansfoimatie van de State monad op de Maybe monad. De
Maybe monad op deze monad-stapel betekent simpelweg dat een waaide wel
of niet aanwezig kan zijn, en dat in het geval van een niet-waaide (in dit ge-
val vastgesteld op nil) geen veideie actie hoef te woiden ondeinomen. ln
een seiie monadische functies in de Maybe monad zal een nil eivooi zoi-
gen dat veidei geen nieuwe beiekeningen plaatsvinden en het iesultaat nil
woidt dooigegeven. Vooi de paisei is dit nuuig, omdat veischillende paiseis
aan elkaai kunnen woiden gekoppeld met m-plus. Deze functie neemt meei-
deie (seiies) paiseis, en gaat deze allemaal piobeien. Als een seiie paiseis
geen iesultaat opleveit, woidt de hele seiie genegeeid en woidt de volgende
seiie paiseis gepiobeeid. Het tweede component van de paisei is een Sta-
te monad. Een State monad heef een functie als waaide, namelijk een die
van een toestand uitgaat en een uitkomst met nieuwe toestand opleveit. De
toestand is in dit geval de te paisen stiing, de uitkomst van een paisei kan
alles zijn (e.g. een gepaised getal, een datastiuctuui op basis van een aan-
tal gepaisede waaiden, of een functie aanioep). Een paisei, of eigenlijk een
paisei-combinatoi, is opgebouwd uit allemaal kleine, tiiviale paiseis. Een
paisei die n kaiaktei inleest is iecuisief aan te ioepen tot een paisei die
een hele stiing inleest, of enkel bepaalde kaiakteis en stopt zodia een andei
kaiaktei woidt tegengekomen. Al deze paiseis geven een iesultaat, plus de
iest van de stiing (dat deel dat succesvol gepaised is ontbieekt). Als de paisei
faalt woidt een iesultaat nil teiuggegeven, plus de compelete stiing, zodat
een andeie paisei het kan piobeien.
A.3 De Log monad
De Log monad is gedenieeid als een vectoi, waaivan de eeiste waaide het
iesultaat is van een monadische functie en de tweede waaide een monode
is die log-infoimatie kan bevauen. Een monode is de combinatie van een
.o
A.. MONADPLUS
veizameling met een enkele associatieve binaiie opeiatie, en een neutiaal
element, dat van de binaiie opeiatie een identiteitsopeiatie maakt
1
. Concieet,
een set S is een monode met opeiatie waaibij geldt dat de veizameling
gesloten is ondei (A.1), dat associatief is (A.:) en dat ei een neutiaal
element is (A.+).
a, b S : a b S (A.1)
a, b, c S : (a b) c = a (b c) (A.:)
e S : a S : e a = a e = a (A.+)
ln dit geval is vooi de tweede waaide gekozen vooi een vectoi, waaiin de
logbeiichten als stiings zijn weeigegeven. De opeiatoi hieibij is concat en
de neutiale waaide is een lege vectoi. Bij het binden van twee monadische
functies woiden eventuele logbeiichten toegevoegd aan de lijst. Veidei woi-
den de functies simpelweg achtei elkaai uitgevoeid.
Iisting A.1 De denitie yan de Iog monad
1 (defmonad log-m
2 [m-result (fn [x] [x, []])
3 m-bind (fn [[v l] f]
4 (let [[v- l-] (f v)]
5 [v- (concat l l-)]))])
A.4 MonadPlus
Bij de Paisei monad woidt koit stilgestaan bij de functie m-plus. Deze func-
tie woidt dooi sommige monads ondeisteund, die met MonadPlus woiden
aangeduid (wel dooi de Paisei bijvooibeeld, maai niet dooi de Log monad).
Monads die m-plus ondeisteunen moeten naast m-plus ook m-zero bieden, die
een lege waaide aangeef (in het geval van de Paisei is dit een nil), die aan-
geef dat de paisei gefaald heef. Hieibij moeten m-plus en m-zero iespectie-
velijk de binaiie opeiatie en de neutiale waaide van een monode voimen.
Daainaast moeten (m-bind m-zero f) en (m-bind m (fn [x] m-zero)) beide
evalueien tot m-zero. Het nut van een MonadPlus zit hem in het feit dat twee
of meei monadische functies met m-plus kunnen woiden gecombineeid tot
een enkele functie. Slechts een van de functies zal uiteindelijk ook woiden
uitgevoeid. Dooi lazy-evaluation woidt een tweede monadische functie pas
uitgevoeid als blijkt dat de eeiste geen succes heef opgeleveid. Zodia een
1
Een vooibeeld zou zijn de natuuilijke getallen met als opeiatie +en als neutiale waaide
o, of met opeiatie en als neutiale waaide 1. ln beide gevallen geldt dat als je de opeiatie
toepast op de neutiale waaide de functie in piincipe niets doet x.x + 0 en x.x 1
.1
A. ACHTERLlGGENDE THEORlE EN WlSKUNDE
functie wel succes heef (en een andeie waaide teiuggeef dan m-zero) woidt
deze waaide als iesultaat beschouwd van de som van de monadische func-
ties. ln het geval van de paiseis betekent dit dat een lijst paiseis kan woiden
gecombineeid, waaivan veivolgens net zo lang de volgende zal woiden ge-
piobeeid tot ei n succes heef. Als ei geen succesvolle paisei tussenzit
blijf het eindiesultaat m-zero, zodat ook de som van een lijst functies in een
samenstelling kan woiden gebiuikt.
.:
B RiHRail Assignment
Patterns & Frameworks - Assignment 2

From PoorRail to RichRail

A public transport company has a little system with which they are administrating their
trains and wagons. A screenshot can be seen below.


At the time the system was built they only had 3 different types of wagons, but now they
want to be able to add more wagon types. They also want the possibility of displaying
their trains in different ways. To be more flexible in using the program it was decided to
introduce a commandline and a domain-specific language (DSL).

A prototype has been built and validated, this is shown in the next picture.
.+
B. RlCHRAlL ASSlGNMENT


Furthermore these requirements have to be included in the new software:
- The display of the existing trains incl. wagons and wagontypes has to be
interchangeable, meaning that also other displaytypes should be easily
integratable. It also has to be possible to show one of the existing displays twice
or more (in another window). The realization of this requirement has to be shown
in the final presentation!
- the output has to be extensible (in such a way that it also can be e.g. logged to a
file)
- No persistency of the data is required

Organization
This assignment has to be done by student groups of 3 students. Download the source
code of PoorRail and use this as basis to implement RichRail.
Grading criteria
- Functionality:
o all required functionality must be implemented
- Design:
o Good structured code (components, layers etc.)
o Principles followed (high cohesion, low coupling)
.
B. RlCHRAlL ASSlGNMENT
o Sensitive and reasonable usage of design patterns
- Coding:
o Comprehensible. no code smells`

- Not graded:
o Performance
o Fancyness

This grade counts 50% in the total grade.

In week 4 all groups present their design to the whole class and explain the most
important design decisions (This is exercise X and is not part of grading, but required).

The final presentations of this assignment will take place in week 6. This date is also the
deadline for the delivery of all sources and available documentation.

See Sharepoint for actual dates.
Grammar
This grammar describes the Domein-specific language (DSL, see MDDT-slides) using a
modified version of the Backus-Naur form
(http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form).

Responses are displayed in extra textfield. If command is not correct, error-message is
displayed: 'command not correct. DeIault amount oI seats is 20. Also show list with
available wagons.

grammar RichRail;

command : newcommand | addcommand | getcommand | delcommand |
remcommand;

newcommand : newtraincommand | newwagoncommand;
newtraincommand : 'new' 'train' ID;
newwagoncommand : 'new' 'wagon' ID ('numseats' NUMBER)?;
addcommand : 'add' ID 'to' ID;
getcommand : 'getnumseats' type ID;
delcommand : 'delete' type ID;
remcommand : 'remove' ID 'from' ID;

type : ('train') | ('wagon');

ID : ('a'..'z')('a'..'z'|'0'..'9')*;
NUMBER : ('0'..'9')+;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+;

Examples:
language-words are bold
identifiers are italic
numbers are normal
..
B. RlCHRAlL ASSlGNMENT

new train tr1; // response is train tr1 created
new wagon wg1; // response is wagon wg1 created with 20 seats
new wagon wg2 numseats 15; // response is wagon wg2 created with 15
seats
add wg1 to tr1; // response: wagon wg1 added to train tr1
getnumseats train tr1; // response: number of seats in train tr1: 20
getnumseats wagon wg2; // response: number of seats in wagon wg2: 15
delete train tr1; // response: train tr1 deleted
delete train tr2; // response: train tr2 does not exist
remove wg1 from tr1; // response: wagon wg1 removed from train tr1
.e
C Macros in Clojure
Clojuie bevat een kiachtig maciosysteem dat veel lijkt op het maciosysteem
van Common Lisp.
Simpel gezegd is een macio veigelijkbaai met een functie die als ietuin-
value een stuk code kan hebben. Een macio evalueeit, in tegenstelling tot
een functie, zijn aigumenten niet. Bovendien woidt macio-code binnen iun-
time uitgevoeid, in tegenstelling tot functies die in compilei-time woiden
uitgevoeid. Op deze maniei stelt een macio de piogiammeui in staat om de
piogiammeeitaal zelf aan te passen en uit te bieiden. Met macios is het mo-
gelijk om functionaliteit in de taal te bouwen, in plaats van op de taal.
C.1 Werking
Maciosystemen vindt men vooial teiug in LlSP-dialecten in de voim van
syntactische piepiocessois. Piogiammeeitalen zoals C, C-- en Objective-C
bevauen echtei ook maciosystemen, in de voim van lexicale piepiocessois.
De bekendste hieivan is waaischijnlijk CPP, de C-PiePiocessoi.
Tussen syntactische piepiocessois en lexicale piepiocessois bestaat een
fundamenteel veischil. Lexicale piepiocessois weiken op basis van text sub-
stitution. Dit wil zeggen dat het maciosysteem geen kennis heef van de
weiking van de piogiammeeitaal. Macios in deze talen weiken simpelweg
dooi veivanging van tekst in een stuk code.
Het maciosysteem in Clojuie is echtei language-based. Zoals we weten
is Clojuie homoiconic data is code en code kan data zijn. Het maciosysteem
in Clojuie heef kennis van de weiking van Clojuie-code. ln Clojuie is de
macio-taal de piogiammeeitaal zelf, ei is geen kennis nodig van een apaite
macio-piogiammeeitaal om macios te kunnen schiijven.
C.2 Voorbeeld
Een simpele macio en tevens een goed vooibeeld is een debug-macio. De-
ze simpele macio voeit een meegegeven expiessie uit, maai piint tevens de
.;
C. MACROS lN CLOJURE
gehele expiessie naai de standaaid output buei. Om een expiessie te de-
buggen hoef deze slechts ingesloten te woiden dooi deze macio. Deze func-
tionaliteit is niet in een functie te bouwen omdat de aigumenten in een ex-
piessie woiden geevaluaeeid vooidat de functie woidt aangeioepen. Dooi
een macio te gebiuiken kunnen we dit gediag omzeilen.
Iisting C.1 Een simpele debug-macro in Clojure
1 (defmacro my-debug
2 Simple debug macro
3 [expression]
4 (let [evaluated# ~expression]
5 (println ~expression ==> evaluated#)
6 evaluated#))
Het special form defmacro woidt gebiuikt om een macio te cieeien. De
syntax is gelijk aan die van defn.
Op iegel begint het inteiessante deel van deze macio. De iegel begint
met een syntax-quote, waaimee het begin van een template-expiessie woidt
aangegeven. De expiessie woidt niet geevalueeid maai als data woidt be-
schouwd.
De tilde vooi expression betekent zoveel als evalueei en veivang dooi de
output. Op deze iegel woidt d.m.v. let de vaiiable evaluated# dus gebonden
aan de output van de ingevoeide expiessie.
Op iegel . woidt de debug-iegel gepiint. De tilde vooi expression betekent
wedeiom xpression evalueien. Op dezelfde iegel woiden een pijltje en de
output van expiessie die nu in evaluated# staat, gepiint.
Op de laatste iegel woidt simpelweg de output van de expiessie als ietuin-
waaide gegeven.
Iisting C.z Gebruik yan my-debug
1 (+ 2 3 4)
2 ; 9
3 (my-debug (+ 2 3 4))
4 ; (+ 2 3 4) ==> 9
5 ; 9
Dooi de Clojuie-functie macroexpand te gebiuiken, kunnen we zien hoe
de macio piecies weikt.
.s
C.:. VOORBEELD
Iisting C.+ macroexpand yan my-debug
1 (macroexpand (my-debug (+ 1 2)))
2 ; (opgeschoonde) output:
3 (let*
4 [evaluated (+ 1 2)]
5 (println
6 (quote
7 (+ 1 2)) ==> evaluated)
8 evaluated)
Dit is natuuilijk slechts een klein vooibeeld van wat men met macios
kan beieiken in Clojuie.
.,
Denitielijst
AI Aiticial lntelligence. ,
anonieme functie Lambda-expiessie, een functie die niet aan een vaiiabele
(naam) gebonden is. 1s
ASM Automatic Stoiage Management. ,
atom een methode om synchioon gedeelte mutable state te managen, een
atom kan enkel met de functie swap aangepast woiden, waaibij woidt
gegaiandeeid dat alle weizigingen atomaii gebeuien. +1, ++
boilerplate-code een stuk code dat op veischillende plaatsen in een stuk
sofwaie gebiuikt woidt (iedundantie). 1
class-based de meest bekende voimvan OO, waaibij inheiitance amankelijk
is van klassen van objecten, in tegenstelling tot van objecten zelf. 1;,
:1, :+, :e
closure de combinatie van een functie en een eigen vaiiabelen-omgeving.
1;1,
declaratieye een piogiammeei paiadigma waaibij piogiammas woiden op-
gebouwd uit beschiijvingen die gecombineeid kunnen woiden tot in-
gewikkeldeie beschiijvingen. 1, ., 1+, ;, ,
DRY Dont Repeat Youiself. :e
dynamic typed het feit dat een piogiammeeitaal het type-checken uitstelt
tot tijdens het diaaien, waaidooi een vaiiabele niet gebonden is aan
het type van de inhoud, cf. static typed. ,, 11, 1+, ,, e1
encapsulation het bepeiken van toegang tot details van de implementie van
een stuk code, om te vooikomen dat code die van de encapsulated code
gebiuik maakt amankelijk is van de implementatie. 1;, 1,:1
expressie een combinatie van functies en aigumenten die evalueien tot een
waaide. 1o, +,
e1
DEllNlTlELlJST
rst-class member een object binnen een taal dat tijdens iuntime gemaakt
kan woiden, kan woiden meegegeven als functieaigument, het iesul-
taat van een functie kan zijn, en aan een vaiiabele kan woiden toege-
wezen. 1
FP lunctional Piogiamming. ii, 1, :, ., :s, +,, ;,, eo
functie een blok code met nul of meeideie invoei-paiameteis en een uitvoei,
gemodelleeid op de wiskundige functie. 1, ,1:, 1., 1e, 1s:o, :::e, :s,
:,, +1, +++s, +, , ,, .1.+
functionele zie lP. 1, :, ., 11, 1+, 1e, :s, ;, ,, e1
higher-order function een functie die weikt op andeie functies, dooi deze
als aigument te veiwachten of als iesultaat op te leveien. 1e
homoiconic de eigenschap dat data en code op dezelfde maniei binnen een
piogiammeeitaal woiden weeigegeven. +, eo
idiomatic code die op een taaleigen wijze is geschieven, iekening houdend
met de kiachten en zwakke punten van een taal. 1o, :, ;
imperatieye een piogiammeei paiadigma waaibij piogiammas geschieven
woiden als seiie van opdiachten die diiect uitgevoeid kunnen woiden.
1, :, ., 1., 1e, ;, ,
inheritance oveieiving, als eigenschappen van een klasse woiden oveige-
nomen van een supeiklasse, of geneialei, stukken code heibiuik maken
van abstiacteie stukken code. :+, .,
iteratie het heihaaldelijk toepassen van code op steeds veiandeiende waai-
den, cf. iecuisie. 1e, e1
JIT Just in Time. 1:
JVM Java Viitual Machine. ii, 1, 1:, 1+, 1;, ;, ,
lambda calculus een foimeel systeembinnen de abstiacte wiskunde omfunc-
ties te ondeizoeken. ,
lexicale preprocessor een simpele piepiocessoi die vooiaf opgestelde to-
kens veivangt dooi andeie tokens, zondei kennis te hebben van syntax
van een taal. +
IISP een familie van piogiammeeitalen vanaf de jaien .o met een homoi-
conic syntax gebaseeid op S-expiessie. 1, ,, 1o, 1+, :e, +, ,, e1
e:
DEllNlTlELlJST
macro een stuk code dat piogiammeeicode kan tiansfoimeien, een macio
woidt uitgevoeid vooi het piogiamma gediaaid woidt. ,, +., e1
monad een combinatie van een functoi met twee natuuilijke tiansfoimaties,
O M(O) en M(M(O)) M(O). +1, +, +;, .1.+, eo
MonadPlus een monad met de functies m-plus en m-zero die tezamen een
monode voimen. =+
monode een set met een binaiie opeiatie en een neutiaal element. +, .:,
.+, eo
mutable state de toestand waaiin een piogiamma of een object daaibinnen
veikeeit. 1, 11, 1., 1e, :1, ++, .,
OO Object-Oiiented. 1, ., 1o, 1, 1;, 1,, :1, :+, :, :e, ;, ,, .,
OOP Object-Oiiented Piogiamming. ii, .
paradigma een stijl van piogiammeien die van andeie paiadigmata kan woi-
den ondeischeiden. 1, :, ., 1+, ,, .,, eo
polymorphism het uiteilijk gelijkvoimig zijn van datastiuctuien met onge-
lijke implementaties, waaidooi veischillende datastiuctuien op dezelf-
de maniei kunnen woiden benadeid. :1, :+
pure functionele programmeertaal een functionele piogiammeeitaal waai-
binnen side-eects expliciet veiboden zijn. +
recursie het toepassen van een functie dooi zichzelf, waaibij het iesultaat
van een iecuisieve aanioep gebiuikt woidt in het totale iesultaat, cf.
iteiatie. 11, 1e, ,, eo, e:
referential transparency de eigenschap dat het iesultaat van een functie en-
kel amankelijk is van de waaiden die de functie mee kiijgt. 1.
self-hosting compiler een compilei die geschieven is in de taal die het kan
compileien, en die in staat is zichzelf te compileien. ,
S-expressie code- en datastiuctuien gebaseeid op lijsten, in LlSP weeigege-
ven tussen haakjes. 1o, 11, eo
side-eects alle eecten die een functie heef naast het ietuin value. +, :s,
:,, e1
staartpositie de laatste instiuctie in een blok code, kan gebiuikt woiden vooi
tail-call-optimalisatie. 11, 1:, e:
e+
DEllNlTlELlJST
static typed het feit dat een piogiammeeitaal tijdens het compileien nagaat
of alle types juist zijn, waaidooi een vaiiabele een vooiaf bepaald type
moet hebben, cf. dynamic typed. 11, 1+, ,, .,
strongly-typed het feit dat een piogiammeeitaal het niet toe laat dat data
impliciet van type veiandeit. 11, ,
syntactisHe preprocessor een piepiocessoi die tiansfoimaties op syntax
tiees mogelijk maakt, zie macio. +
syntax de giammaticale iegels van een piogiammeeitaal, iegels waaiaan de
stiuctuui van code moet voldoen om gedenieeid te zijn. ,, 1o, :, :e,
eo, e1
syntax-quote een syntax quote maakt het mogelijk een eenvoudig code te-
iug te geven, in plaats van deze diiect uit te voeien, zondei dat je iedei
ondeideel apait zou moeten quoten.
tail-call-optimalisatie een voim van iecuisie waaibij de iecuisieve aanioep
de laatste instiuctie is (in staaitpositie staat), waaidooi optimalisatie
het mogelijk maakt niet vooi iedeie iecuisieve aanioep een stackfiame
aan te maken. 11, 1:, e1
e
Bibliograe
Cow11] Danny Cowaid. Java SE: A Youthful Maturity. http://www.infoq.
com/presentations/Java-SE-A-Youthful-Maturity. :o11.
lH11] Michael logus en Chiis Housei. e Joy of Clojure. 1st. Manning
Publications, :o11. isbn ,;s1,+.1s:e1.
Halo,a] Stuait Halloway. Programming Clojure. 1st. Piagmatic Bookshelf,
:oo,. isbn 1,++.e++e, ,;s1,++.e+++.
Halo,b] Stuait Halloway. Rie-Oriented Programming with Clojure. http:
/ / thinkrelevance . com / blog / 2009 / 08 / 12 / rifle - oriented -
programming-with-clojure-2.html. :oo,.
Hal11a] Stuait Halloway. Clojure-Java Interop: A Beer Java than Java.
http://www.infoq.com/presentations/Clojure-Java-Interop. :o11.
Hal11b] Stuait Halloway. Perception and Action: An Introduction to Clo-
jures Time Model. http : / / www . infoq . com / presentations / An -
Introduction-to-Clojure-Time-Model. :o11.
Hai1o] Sieiia van dei Hait. Practical Clojure. 1st. Beikely, CA, USA
Apiess, :o1o. isbn 1+o:;:+1;, ,;s1+o:;:+11.
HM,s] Giaham Huuon en Eiik Meijei. Monadic Paising in Haskell. ln
Journal of Functional Programming s. (juli 1,,s), p. +;-.
Leios] Reuven Leinei. JVM-Based Languages Grow In Popularity. http:
//ostatic.com/blog/jvm-based-languages-grow-in-popularity.
:oos.
LU] Association of Lisp Useis. History of Lisp. http://www.lisp.org/
alu/res-lisp-history.
Maio,] Robeit Maitin. What Killed Smalltalk Could Kill Ruby, Too. http:
//blip.tv/railsconf/railsconf-09-robert-martin-what-killed-
smalltalk-could-kill-ruby-too-2099970. :oo,.
Mil,,] Dave Millei. Java Tip : An alternative to the deep copy tenique.
http://www.javaworld.com/javaworld/javatips/jw- javatip76.
html. 1,,,.
Rat11] Amit Rathoie. Clojure in Action. 1st. Manning Publications, :o11.
isbn 1,+.1s:.,., ,;s1,+.1s:.,;.
e.
BlBLlOGRAllE
Supo;] Benjamin Supnik. Inheritance of Implementation is Evil. http :
/ / hacksoflife . blogspot . com / 2007 / 01 / inheritance - of -
implementation-is-evil.html. :oo;.
Vol11] R. Maik Volkmann. Clojure - Functional Programming for the JVM.
http://java.ociweb.com/mark/clojure/article.html. :o11.
Wieos] Geeitjan Wielenga. Farewell to the J in JVM? http://java.
dzone.com/news/farewell-j-jvm. :oos.
Wika] Wikipedia. Java performance. http://en.wikipedia.org/wiki/
Java_performance.
Wikb] Wikipedia. Moores law. http://en.wikipedia.org/wiki/Moores_
law.
ee

You might also like