Denne posten er tiltenkt lesere som ikke kjenner Clojure så godt.

Jeg begynte å jobbe fulltid i Clojure først på nyåret 2020. Clojure kom i 2007. Jeg hadde riktignok hatt Clojure i sidesynet en stund før 2020. Men, jeg var nølende. Fordi jeg syntes Lisp så forferdelig ut, var kun middels nysgjerrig på funksjonell programmering, og sterk typing er gull.

Så hva er så elevator pitchen, som gjør at jeg allikevel elsker å komme tilbake til Clojure?

Det har vist seg for meg å være noe helt annet enn lisp, immutability eller typesystemet til Clojure- selvom disse også har vokst på meg etterhvert.

REPL

Du har kanskje sett et REPL, og testa det litt? Ja hvis du har gjort som meg, så har du gjort deg opp en tanke om at det er en grei plass å teste kodesnutter.

user=> (+ 1 2)
3

Ok, Clojure klarer å legge 1 og 2 sammen.

Ok, hva nå? Var dette heis-pitchen? Litt pusling i REPL!?

Mjo, men det var ikke hele pitchen. Nå skal jeg kjapt forklare hvorfor å dykke littegrann dypere i REPL gir deg superkrefter du nok aldri har hatt før.

REPL prosessen

Når du starter et Clojure-prosjekt i IDE-et ditt, så starter du opp en REPL temmelig umiddelbart som du skal skrive kode. REPL-drevet utvikling.

Den kjørende REPL-instansen (en jvm prosess) skal kjøre hele arbeidsdagen din. I motsetning til (+ 1 1) -REPL-et som vi snakka om over her – som kun var et eksperiment som vi kasta bort etterpå.

Stopp en hal! Sa du hele arbeidsdagen med én REPL instans?

Nja, det er en sannhet med modifikasjoner. Det er mer sannsynelig i prosjekt-oppsett som er modent enn et helt nyoppsatt prosjekt. La oss ta et eksempel nå.

En enkel webserver

Vi lager en webserver som returnerer ‘fisketur’, og vi bruker REPL-instansen som partneren vår som skal være med hele veien.

Jeg bruker IntelliJ og Cursive Plugin, men du kan bruke VSCode (med Calva) eller noe annet. Det er sterkt anbefalt å bruke et utviklingsmiljø som støtter Clojure godt for å ikke rable til parantesene dine.

$ mkdir fisketur
$ cd fisketur
$ mkdir -p src/core

2 filer

deps.edn Prosjektfila, den inneholder clojure og undertow (en webserver lib).

{:deps {
        org.clojure/clojure {:mvn/version "1.11.1"}
        luminus/ring-undertow-adapter {:mvn/version "1.3.1"}}}

src/core/main.clj Koden vår.

(ns core.main)
Nå har vi åpnet dette prosjektet i editoren, og skal starte REPL før noe ekte kode skal lages.

Starte REPL

Først må vi sette opp REPL konfigurerer; en 'Clojure REPL Local' konfigurasjon som vi skal starte.
Høyre fane popper opp med output som viser at en REPL er startet

Nå har vi en kjørende REPL og kan evaluere til den fra fila vår.

Det ser kanskje unødvendig ut, men nå kjørte vi 1 + 1 for å se at alt kjører. Systemet er friskt og klart for kode.

Først lasta jeg fila med Alt+l (load file), så evaluerte jeg med Alt+Shift+e (evaluate expression)

Superkreftene

La oss ta på oss kappen og gjøre noe annet enn barnehagematte - starte webserveren i REPL-et. Ingen restart av REPL, vi fortsetter fra (+ 1 1). Jeg får ikke understrekt nok at vi ikke restarter noe som helst. Hvis noen leste denne posten uten å ha fått seg poenget om ingen restart, så bomma jeg og må sansyneligvis slutte å skrive bloggposter.

Visker bort gammel kode, require undertow (libben har vi allerede i prosjektfila), så skrive en håndteringsmetode for http, så starte. Alt+Shift-e på slutten så kjører webserveren i REPL-instansen
Så sier nettleseren at vi er i mål

Nå står REPL og svarer på http, og den kan besvare så mange web-requests du gidder å sende den.

Du kan nå modifisere koden, oppdatere med ny kode – Alt-Shift-e så oppdateres instansen.

Du trenger ikke trikse med unit-testing for å få et kjøremiljø. Eller ty til magisk hotreloading for å se at kode fungerer. Du blir trygg. Du har full kontroll over hva du sender inn. Under hele utviklinga så lever og puster du med den koden din.

Til slutt, for å lage produksjonsklare greier så er det ingen sak å lage main entry point (aka main-metoden din), og da bruker du bare nøyaktig samme kode som du repla rundt og koda funksjonalitet.

Siste ord

Først må jeg si at koden vi nettopp laga har en slags bug. Vi må ta vare på resultatet fra run-undertow i en variabel - for å bruke referansen for å stoppe undertow-serveren. For å kunne starte den igjen enda en gang. Tenker du sånn så kan en REPL leve evig.

Når en gjør sånne tabber så må du restarte REPL. Ved å drepe jvm-instansen så får du tatt livet av alt du har mista kontakt med. I tillegg må REPL restartes når du oppdaterer avhengigheter til biblioteker.

Dette var slutten på pitchen og jeg håper du fikk noe å tenke på.

pssst

Du kan gjøre nøyaktig det samme med ClojureScript. REPL-e rett fra editoren din og inn nettleseren.