Jeg har holdt øye med programmeringsspråket Go, eller Golang som det ofte skrives hvis du vil at Google skal skjønne hva du prater om. Språket har vokst eksplosivt de siste årene og har tatt en posisjon som standardspråket for infrastrukturverktøy. Docker og Kubernetes har vært bjellesauer for språket og viser at Go kan takle komplekse oppgaver. Nå er det på tide å se og føle litt på kroppen hvordan det er å løse oppgaver med Go.
I forbindelse med et prosjekt trengte jeg et verktøy for å kunne rapportere temperatur og lufttrykk på utvalgte steder i Norge. Ideen er å hente data fra Yr, behandle disse litt, og late som om dette er reelle målinger som vi så skal mate inn i en maskinlæringsmodell. Siden jeg hadde god tid var dette et godt utgangspunkt for et eksperiment i Go.
Etter litt over en uke, er det på tide å gjøre opp status. Resultatet er over all forventning; jo mer Go jeg skriver jo morsommere er det! Det er mange år siden det har vært så gøy med et nytt språk. Nok til at jeg blir sittende å pusle med Go på kveldstid i stedet for å rase rundt i marka på ski.
Go er først og fremst et enkelt programmeringsspråk. Det er 25 nøkkelord du trenger å lære før du kan begynne å lese Go-kode. I motsetning til de andre språkene jeg har plukket opp de siste årene, tok det bare noen timer før jeg kunne lese kode og forstå hva som skjer. Dette er en nokså sterk kontrast til komplekse språk som Java, Kotlin og C++, hvor du som nybegynner ofte kan komme over kode hvor du kan bruke timer på å forstå hva en enkelt linje med kode gjør.
Jeg kunne begynne å skrive kode etter ca. en dag. Etter omtrent en uke følte jeg at jeg behersket mesteparten av språket og kunne stort sett få til alt jeg ville. Det er fortsatt elementer av språket jeg ikke fullt ut behersker og "best practices" jeg ikke bruker, men det antar jeg kommer på plass i løpet av den kommende tiden.
Go er på noen områder litt gammeldags. Funksjonelle elementer har kommet inn i stort sett alle moderne programmeringsspråk de siste årene, men i Go er det lite av dette. Du kan sende funksjoner som parametre til andre funksjoner og kalle dem, men det stopper egentlig der. Du har ingen lamdaer, ingen map- eller reduce-utsagn eller andre funksjonelle elementer. Du gjør alt med for-loops.
Men du kan fortsatt skrive kode hvor du unngår delt tilstand og sideeffekter, og for meg er dette viktigere enn om koden min er ren funksjonell kode.
Feilhåndteringen i Go er enkel. Stort sett returnerer kall som kan feile to verdier, og du må selv sjekke om du fikk en feilkode tilbake. For oss som har vært vant til å lene oss på exceptions for å håndtere alle feil som kan oppstå i en kodesnutt, er det slitsomt å måtte håndtere en tilsynelatende endeløs strøm av potensielle feil. Det svekker lesbarheten i koden. Kode som dette er ikke vakker:
Generics mangler, men det er på vei, så når du leser dette er det kanskje allerede en del av språket. Opsjonelle parametre savnet jeg også, men du kan jobbe deg omkring begge disse begrensningene, så savnet er ikke stort.
Jeg har vært litt bortskjemt med mocking i dynamiske språk og i Go må du lage litt mer bambus for å mocke ordentlig, men det er vel felles for alle statiske språk. Du må faktisk legge til rette for dependency injection selv og skrive kode som lar deg overstyre en avhengighet under testing. Selv om det er litt mer jobb, slipper du å lure på hva i granskauen det er som skjer.
Noe av det som har forårsaket mest grå hår i språk som Kotlin har vært rundt samtidighet. Kotlin har, i likhet med SIMULA67, korutiner. Men siden mange av bibliotekene har antatt at de blir kjørt i en tråd, oppstår det rare feil som kan ta timevis å oppdage og jobbe seg rundt. Go har ikke antydning til slikt. Alt er korutiner og du kan ikke kontrollere om de får en egen tråd eller ei. Semantikken er veldig tydelig, som med det meste.
Det tok tid før jeg forsto at jeg ikke skal lage delte datastrukturer, men heller sende data i channels. Forsøker du deg på delte datastrukturer så ender du fort opp med kaotisk kode som er full av lock/unlock-utsagn.
I tillegg har det vært utrolig fint å slippe alt fjaset jeg har slitt med i Python, hvor det å distribuere koden er en uendelig strøm av smerte. Der har jeg brukt måneder på å skrive Python-kode for Python 3.8, for så å oppdage at det skal kjøre på Python 3.6. I Go spytter du ut en binær og du kan kjøre denne på alle versjoner av operativsystemet du bruker, uavhengig om at det skjer i Debian, RHEL eller i en Alpine-basert kontainer.
Go er også et komplett programmeringsspråk. Dette innbefatter et test-rammeverk og et komplett og modent standardbibliotek. Du trenger ikke å lure på hvilken HTTP-tjener du skal bruke eller hvilket test-rammeverk du skal velge. Med mindre du har spesielle behov, bruker du det som følger med Go. Dette i sterk kontrast til f.eks. JavaScript hvor det å velge testrammeverk eller HTTP-tjener er en krevende oppgave. Det er også en del av språket hvordan koden skal formatteres, så alle diskusjoner om tabs eller mellomrom legges døde.
Jeg har funnet få biblioteker for Mocking. I Python er jeg vant til å finne nydelige pakker som gjør det enkelt å mocke stort sett alt du kan finne på å trenge. Når jeg først innså at jeg måtte lage disse selv, gikk det greit.
Jeg digger ikke at språket kontrolleres av Google, men jeg tar av meg hatten for den disiplinen de har vist i forvaltning av språket. De har ikke gitt etter for presset om å innføre komplekse abstraksjoner eller semantikk som senior-utviklerne har ønsket seg. Hvis de greier å holde på denne selvdisiplinen vil Go fortsette å være et enkelt språk, og da er det helt greit at ikke språket forvaltes av en komite. Python sine "list comprehensions" er kjekke og kompakte, men du dør ikke om du må skrive en for-loop eller 20.
En siste ting som jeg setter utrolig pris på, har vært fokuset på kompatibilitet. Go-prosjektet er helt klare på at kode som er skrevet for 10 år siden skal fortsette å kunne kjøre. Denne holdningen har jeg tidligere bare sett i C og C++. Hvis du først investerer tusenvis av timer på et Go-prosjekt, kan du stole på at denne koden vil fungere uten endringer om 10 år.
Konsulentbransjen i Oslo er relativt konservativ og har klamret seg til Java gjennom tykt og tynt. Kanskje på tide å vurdere noe nytt? For meg har det vært veldig gøy å jobbe med noe annet. Jeg tror du vil bli overrasket over hvor greit det går.
De første ukene kommer nok hastigheten på utviklingen til å gå tregere, og hvis du er en Java-guru vil du nok kjenne på ubehaget med å være ute på tynn is. Men etter kort tid vil hele teamet være helt komfortable, og løse problemer raskt og effektivt. Siden språket er såpass minimalt er det lite rom for personlig stil. Både min og din kode vil stort sett lik ut og vi vil begge kunne hverandres kode.
Som med andre typede språk anbefales det på det sterkeste å ha et IDE som evaluerer koden du skriver. Jeg har brukt Jetbrains sin Goland, men VS Code er like bra. Og for de konservative blant oss så tipper jeg det finnes fullgode plugins til Vim og Emacs.
Bilde: Renee French, CC BY-SA 3.0, via Wikimedia Commons