La oss dikte opp et case som jeg vil tro høres kjent ut for mange. Jeg skal betjene en HttpRequest, kna litt, så svare noe fornuftig.

Jeg får et request i en funksjon som håndterer http

(defn handler [http-request])

Så henter jeg query-params

(defn handler [http-request]
    (:query-params http-request)
) 

Jeg vil ha fornavn fra query parameter

(defn handler [http-request]
    (:fornavn (:query-params http-request))
) 

La oss slå opp fornavnet i databasen

lookup-by-firstname er en oppdiktet funksjon som vi forutsetter at gjør det vi ønsker.

(defn handler [http-request]
    (lookup-by-firstname (:fornavn (:query-params http-request)))
) 

Lage en fin respons i JSON-format

(defn handler [http-request]
    (create-response (lookup-by-firstname (:fornavn (:query-params http-request))) :JSON)
) 

Koden begynner å bli uleselig. Allerede nå tar det uhensiktsmessig mye hjernekraft og stirring til for å se hvor koden starter.

Knep 1

Jeg skal vise 2 grunnleggende knep i Clojure; let og threading.

Først skal vi lette på de trykkende parantesene ved å binde med let.

(defn handler [http-request]
    (let [fornavn (:fornavn (:query-params http-request)) ; plukking fra http-request
          rad-fra-db (lookup-by-firstname fornavn)]       ; lookup
     (create-response rad-fra-db :JSON)))                 ; lag pen respons
     

I denne kodesnutten så observerer du at nøyaktig de samme operasjonene er her, men betydelig enklere å lese.

Knep 2 - threading

Threading er et knep som krever litt mer av deg. Threading (“thread first”) kjører koden i sekvens og gir neste statement det forrige resultatet som første argument. Det siste resultatet blir resultatet av hele threadinga, og threadinga blir resultatet til hele funksjonen vår.

(defn handler [http-request]
    (-> http-request
        :query-params
        :fornavn
        lookup-by-firstname
        (create-response :JSON)))

create-response stikker seg litt ut. Det er fordi resultatet av lookup-by-firstname sitt resultat skal være første argument, å havne bak før :JSON

Det var alt

Med disse to kan du bygge på med funksjonalitet – uten å drukne i uleselig parantes-wrapping.

Disse to er ikke bare knep - de blir fort nødvendig for å lage lesbar kodeflyt. Forøvrig skreiv Magnar en flott post dedikert til Threading en tid tilbake.