torsdag 24. juni 2010 Clojure
Siden jeg sitter og leker meg med Clojure tenkte jeg det kunne passe med en liten revamp av filtrer, projiser, aggreger blogposten fra et par uker tilbake. Her er de tilsvarende høyereordens-funksjonene i en kodesnutt som viser hvordan jeg kan løse den samme oppgaven i Clojure. Merk at LISP/Clojure kaller projiseringsfunskjonen for map (som de fleste andre språk forsåvidt), og aggregeringsfunksjonen heter reduce.
Uforklarlig? Til å begynne med ser LISP-syntax litt kryptisk ut ja. Men jeg kan i alle fall forsøke å forklare noe av det for deg. Bruken av #-tegnet er syntaktisk sukker for å lage en anonym funksjon, hvor %/%1, %2 etc. refererer til funksjonens parametre. Linje 57 kunne for eksempel vært skrevet på følgende måte uten å bruke #:
Begynner du med den innerste parantesen ser du her et kall til funksjonen rem, som kalkulerer resten (reminder) når n deles på 2. En parantes lengre ut ser du et kall til =, med parametrene 0 og reminderen som nettopp ble kalkulert – altså sjekker man om reminder er lik 0. fn [n] betyr at vi deklarerer en anonym funksjon som tar en parameter vi kaller n. Helt ytterst kaller jeg filter-funksjonen som har to parametre: den anonyme funksjonen for å avgjøre om et tall er et partall, og kollekjonen av tall.
Dette er altså ikke er helt ulikt det man for eksempel ville ha skrevet i F#:
Jeg forsøkte også å lage en variant av pipeliningen (linje 66 til 70) som bruker inline funksjoner og partial application, slik som jeg gjorde med F# helt til slutt i filtrer, projiser, aggreger, men det har jeg sålangt ikke fått til. Noen som kan Clojure eller LISP som kan bistå/kommentere? Får vel lese litt mer…