Hva er funksjonell programmering? 🤔

To norske eksperter forklarer deg hva funksjonell programmering er, og hvorfor du bør prøve.

Utviklerne Christian Johansen og Magnar Sveen og i Kodemaker skriver det meste som funksjonell Clojure- og ClojureScript-kode. Nå forklarer de deg hva funksjonell programmering egentlig er. 📸: Ole Petter Baugerød Stokke
Utviklerne Christian Johansen og Magnar Sveen og i Kodemaker skriver det meste som funksjonell Clojure- og ClojureScript-kode. Nå forklarer de deg hva funksjonell programmering egentlig er. 📸: Ole Petter Baugerød Stokke Vis mer

I kode24 sin spalte Ukas Koder har mange norske utviklere snakka varmt om funksjonell programmering.

«Det skjer så mye spennende i funksjonell programmering nå at Norge etterhvert må forstå at det er veien å gå» sa Kaare Nilsen i Arktekk.

«Jeg er en stor tilhenger av funksjonell programmering, spesielt i kombinasjon med god statisk typing» uttalte Ingar Almklov i Bekk.

Men vet den gjengse norske utvikler hva funksjonell programmering egentlig er? Vi spurte Facebook-følgerne våre, og etter 189 stemmer ledet «nei» med 71 prosent.

Så kode24 møtte utviklerne Magnar Sveen og Christian Johansen i Kodemaker for å prøve å forklare deg hva funksjonell programmering er for noe rart.

Det meste de gjør på jobben skrives i Clojure og ClojureScript; språk som er kompatible med henholdsvis Java og JavaScript, og som mer eller mindre tvinger utviklerne over på nettopp funksjonell programmering.

For å starte fra starten; hva er funksjonell programmering?

Det er en tilnærming til programmering, altså en paradigme.

Begrepet kommer fra matematikken; en funksjon skal være som en matematisk formel, som tar noe inn, og gir noe ut. Og dette skal være 100 prosent forutsigbart.

«Det skal være 100 prosent forutsigbart.»

Så funksjoner skal alltid gi de samme resultatene når de samme parameterne mates inn, uavhengig av tid.

Grunnideen, om man tar utgangspunkt i objektorientering, er å splitte data og funksjoner i to. I stedet for objekter med metoder på, lar vi data være det den er, og bruker løsrevne funksjoner.

Og hva fører dette til, rent praktisk?

I objekt-orienterte språk har du ofte veldig konkrete funksjoner, som for eksempel «game.changeScore(20)». I funksjonell programmering bruker man gjerne færre funksjoner, som følger med språket og er mer generelle. For eksempel «update(game, score, 20)».

Yatzy kan nesten utelukkende skrives med slike funksjoner. Her ser du Yayzy med ClojureScript og funksjonell programmering:

Yatzy med samme logikk i Javascript blir langt mer kode.

Dessuten har du ingen objekter, men verdier: strenger, tall, maps og lister. Du kan tenke på det som «snapshots» av objekter – som aldri endrer seg

Yatzy-koden er imponerende kort, men skremmende gresk. Så hva er vitsen?

Det slutter å være gresk når du har det grunnleggende vokabularet under huden. Når for eksempel «vals» og «frequencies» sitter like godt som «map» og «filter».

Den største fordelen er at dataflyten gjennom programmet blir eksplisitt. Det er tydeligere hvor ting kan endre seg og hvorfor, som gjør det lettere å komme inn som ny i en funksjonell kodebase.

Du ser fort at her skjer det ingen magiske ting, det skjer ingenting uten at du har bedt om det, så du slipper å forholde deg til hva som skjer i andre deler av kodebasen samtidig. Den luksusen får du ikke i en objekt-orientert kode.

Det er også mye enklere å finne feil; når ingen data endrer seg uten at du har bedt om det, slipper du å «håpe på» at den samme feilen melder seg igjen. I objektorienterte språk kan alle objektene finne på hva de vil til enhver tid, mens du i funksjonell programmering sitter i en mer sentral styringsrolle.

Dessuten kan du gjenbruke mye kode, og blir flink på å se generelle løsninger på problemer – i alle språk.

Ja, hvorfor finnes det egne språk for funksjonell programmering, egentlig?

Du kan programmere funksjonelt i alle språk. Men språket begrenser deg, og du kan bli avhengig av å bruke ting som imutable.js.

Med for eksempel Clojure eller Elm tvinges du over til funksjonell programmering, og de gir deg de generelle funksjonene du trenger.

Her ser du litt av ClojureScript-syntaksen. Slike språk skal gjøre det lettere å skrive ren, funksjonell kode. 📸: cljs.info
Her ser du litt av ClojureScript-syntaksen. Slike språk skal gjøre det lettere å skrive ren, funksjonell kode. 📸: cljs.info Vis mer

Da jeg skulle lære meg Clojure rakk jeg å skrive én parantes før «høh, hvordan gjør jeg egentlig dette?». Tidligere hadde jeg for eksempel bare skrevet «score++» for å øke et tall, men nå gikk ikke det. Hvis det hadde gått, hadde jeg ikke lært noe – disse egne språkene lar deg ikke hoppe over læringen.

Også kan du eventuelt gå tilbake til hverdagen i Javascript eller Java med en ny verktøykasse.

Men når man ser på funksjonell kode er det lett å tenke at det er mye vanskeligere enn tradisjonell programmering?

Det er annerledes enn det du er vant til. Og jeg vil tvert i mot si at funksjonell programmering er veldig mye enklere, når du har kommet inn i det.

Jeg jobba i mange herrens år med objektorienterte språk, og når jeg slutta med dem var det en veldig lettelse. Det er så mye du ikke lenger trenger å ta hensyn til, som var så inngrodd i meg at jeg ikke klarte å se at det var et problem før jeg slapp å ha problemet.

Det handler jo mest om forutsigbarhet. Du vet at når du sender datastrukturen dit, så endrer den seg ikke, og funksjonene gjør alltid det samme. Det høres kanskje litt kult ut? Men det er veldig kult! Og du må bare oppleve det!

Også finnes det visst to skoler innen funksjonell programmering?

Ja. Blant annet Clojure og ClojureScript, som vi tar utgangspunkt i her, er dynamisk typet funksjonell programmering. Mens blant annet Elm og Haskell er statisk typet funksjonell programmering.

De ber deg modellere verdenen din på forhånd; «sånn ser alle typene mine ut, de er lagt opp sånn og sånn». Deretter inspiseres koden din for en sanity-sjekk, typene flyter gjennom funksjonene og slikt, og du får en streng og god sjekk på om koden kommer til å kjøre.

Så med statisk typet funksjonell programmering får du endel hjelp, men du betaler også en kostnad. For om du for eksempel skal få JSON inn i koden din, må du definere hvordan all dataen kommer til å se ut. Så om JSON-dataen på et tidspunkt endres, kan koden din slutte å fungere. Mens det i et dynamisk typet språk kanskje ville sklidd inn og fungert.

Statisk typing kan i enkelte språk dras veldig langt, og fort ende opp som en nokså avansert øvelse – litt "universitetsprogrammering", om du vil.

Men det høres litt «universitet» ut det dere driver med, også. Er dere mer opptatt av koden enn produktet?

Vi er vel litt mer i den skolen som er opptatt av koden i seg selv, men det er bare fordi vi har kjent ettersmaken av den første skolen – som bare er opptatt av å få ut produktet.

Det handler ikke nødvendigvis om at koden skal bli så vakker, men at man skal skjønne hva som skjer, og hvorfor. For påstanden om at det ikke spiller noen rolle hva slags språk man bruker bare det gir verdi for kunden, er feil.

Poenget med software er å holde den soft. Man må kunne endre den. Og når software slutter å være soft, som jeg tror veldig mange har opplevd, blir det veldig vondt for veldig mange.

De to koderne har laget ZombieCLJ for å lære andre å programmere med Clojure og ClojureScript. 📸: zombieclj.com
De to koderne har laget ZombieCLJ for å lære andre å programmere med Clojure og ClojureScript. 📸: zombieclj.com Vis mer

Hvor bør man starte, om man vil prøve seg på funksjonell programmering?

Clojure er den ene Lisp-dialekten som har litt medvind, men i det store og det hele er det et nisjespråk. Elm har kanskje mest traction nå, mens det var Scala som var stort for noen år siden. Så dette går litt opp og ned.

Men selv er jeg veldig fornøyd med Clojure; det fungerer så bra for meg, som jobba i veldig mange år med Javascript og Java. Og uansett ville jeg starta med et funksjonelt språk. Man blir flinkere på funksjonell programmering ved å starte med et funksjonelt språk.

Vi har laget screencast-en zombieclj.no, hvor vi lager et spill med Clojure, som har fått mye skryt. Også ville jeg sett talk-en Simple made Easy av Clojure-skaper Rich Hickey. Gir den gjenklang, er det på tide å finne fram parantesene og skrive Clojure.

Og hvilke type utviklere bør prøve seg?

Alle! Selv om det er et kjedelig svar.