Elixir och en framtid med större möjligheter

Elixir är ett programmeringsspråk som vunnit mycket mark på senare tid och i min erfarenhet vinner ovanligt mycket mark bland mer erfarna, seniora, utvecklare. Jag vill belysa lite av de systematiska fördelar jag ser Elixir ge företag och utvecklare. Det blir ingen kod, bara översikt och förklaring i det här läget. För att kunna bekanta oss med Elixir och dess fördelar behövs en liten historielektion som ger oss Elixirs tekniska arv och sammanhang.

​Elixir bygger på arbetet med ett annat språk som heter Erlang. Det är ett språk som utvecklades på Ericsson på 80-talet och därefter släpptes som open source. Det skapades för att bygga system med fokus på driftssäkerhet, tillförlitlighet. Mer specifikt byggdes det för att ge mjuka realtidsgarantier för distribuerade system inom telekomsystemen som Ericsson skapade. Erlang har ovanliga egenskaper som man inte ser i särskilt många andra språk. Särskilt inte samlade:

  • Hot code reloading: Man kan uppdatera koden i en körande applikation och bibehålla existerande tillstånd, utan omstart.
  • Stark introspektion under pågående körning.
  • Mjuk realtid, tillförlitliga latency, preemptive scheduling: Under körning kan VM:en avbryta pågående arbete för att säkerställa att alla pågående processer får chans att köras på CPU:n. Detta hindrar flera patologiska feltillstånd, t.ex. oändliga loopar, från att krascha eller låsa applikationen.
  • Distribution & klustring: Erlang har en inbyggd lösning för distribuerad körning och klustring som bygger på message passing. Detta grundar sig på att Erlang är byggt enligt Actor-modellen.
  • Concurrency & Parallellism (använda flera kärnor) Väldigt få språk kan effektivt använda CPU-kärnor hejvilt men i Erlangs fall så hanteras det med samma modell som utvecklades för distribution. Lättviktiga “processer” istället för trådar. Immutability och message passing för tråd-säkerhet. Så det är billigt och tämligen ofarligt att nyttja flera kärnor i en applikation, utan att använda en worker-pool i någon slags applikations-server eller köra fler instanser av applikationen.

Erlang har aldrig varit särskilt populärt men har länge respekterats i sin niche. För vissa företag har det varit ett hemligt vapen. Det är skapt för att kunna bygga extremt tillförlitliga system med goda prestandagarantier och det har såvitt jag vet alltid levererat väl på det området. Det har förstås också utvecklats löpande sedan 80-talet. Och det har körts i seriösa driftsammanhang sedan dess.

​Elixir ger Erlang en fräsch och enklare syntax. Det lägger vidare till en hel del smidigare funktionalitet för modern utveckling och har blivit en renässans för Erlang och BEAM:en, den VM som Erlang och Elixir körs på.

Så varför bör vi bry oss om Elixir?

Grundplåten

 

​Antalet språk som har ett gott rykte som exceptionellt pålitliga är få. De är också ofta trögarbetade. Elixir är ett tight och uttrycksfullt högnivåspråk som har mycket av sitt syntaktiska arv från Ruby. Elixir är dock funktionell programmering, inte objekt-orienterat. Precis som Erlang.

Webbramverket Phoenix, Ruby on Rails andliga efterträdare

 

​Elixir skapades av José Valim som tidigare varit en aktiv Ruby-utvecklare. Rails är ett extremt populärt webbramverk. För Elixir är Phoenix det motsvarande ramverket och en stor mängd utvecklare från Ruby och Rails har rört sig över till Elixir och Phoenix.

Det går att skriva mycket om Phoenix, det är ett kraftfullt och lättarbetat webbramverk. Utifrån det så har även en del mycket imponerande tekniska lösningar byggts. En intressant utveckling är t.ex. tillägget LiveView som låter utvecklare skapa mycket dynamiska lösningar utan Javascript. Den här videon från Chris McCord kan vara en bra dragning.

Ekosystemet

 

​Språket har ett starkt växande ekosystem och de mjukvarubibliotek som behövs finns i allmänhet i mogna implementationer. Det har även fördelen av att kunna luta sig på och använda bibliotek som skapats för Erlang när Elixir-varianter helt saknas. T.ex. bygger Phoenix på en HTTP-server som heter Cowboy som utvecklades för Erlang.

IoT & Connected Devices

Inom Elixir har ett projekt som heter Nerves skapats som har ett exceptionellt ambitiöst och synnerligen kapabelt sätt att närma sig arbete med hårdvara för IoT och liknande embedded-projekt. Om det kan köra Linux så kan det tjäna på Nerves. Det är en verktygskedja med exceptionellt snabb iterationshastighet för hårdvarunära utveckling. Det nyttjar en kombination av gedigen erfarenhet av hårdvaruutveckling och Erlangs egenskaper för att skapa pålitliga hårdvaruenheter. Det har även skapats ett verktyg vid namn NervesHub som löser säkra uppdateringar av produkter som är ute hos kunder i fältet vilket kan vara väldigt komplext. Det går att läsa mer här.

 

​Ett annat ramverk som gör nytta inom IoT och Connected Devices är Scenic. Detta är ett UI-ramverk som använder OpenGL för att rendera lättviktiga UI med ett starkt säkerhetstänk och god flexibilitet. Scenic är enormt lättviktigt jämfört med den populära lösningen att bädda med en hel webbläsare och webbapplikation. Det är få system som har egna lågnivå-ramverk för att rendera användargränssnitt och Scenic är en imponerande lösning för det. Här presenteras det på ett talk på Code BEAM i Stockholm.

Varför Elixir?

 

​Så varför bör vi överväga Elixir?

 

​Med en stark modell för concurrency och parallellism drar det bättre nytta av serversresurser än genomsnittliga applikationer skapta i t.ex. Python, Node.js, Ruby, PHP och många fler. Detta sparar pengar, ofta rejäla pengar, på hårdvara eller notan hos molnleverantören.

 

​Det är en stark grund att stå på. Elixir och Erlang erbjuder verktyg som i princip inga andra språk eller ramverk rimligt kan erbjuda när det gäller slagtålighet i drift, distribution och skalbarhet,

 

​Funktionell programmering är enligt många avsevärt enklare att resonera kring. Min erfarenhet som konsult som klivit in i andra organisationers Elixir-projekt är att jag är feature-produktiv dag ett eller två och blir bekant med systemet snabbare. Vare sig jag återbesöker kod jag skrev för 6 månader sedan, dyker ner i koden i ett open source-bibliotek så är den lättare att plocka upp då jag inte behöver hålla en klass-hierarki och objekt-state i huvudet när jag läser och skriver kod. Input, output och minimalt med bieffekter.

 

​Den största utmaningen är väl just att funktionell programmering är ett annat paradigm än objekt-orienterat och att objekt-orienterat fortfarande är dominant. Men sen har ju många ekosystem, särskilt Node.js/Javascript plockat upp funktionella koncept så det är mer och mer bekant för utvecklare.

 

​Man kan bygga webbsystem och backends i nästan vilket språk som helst och få det att fungera fint. Det är min bestämda uppfattning att Erlangs VM, BEAM, erbjuder egenskaper som man inte hittar i något annat moget ekosystem eller språk. Och att de egenskaperna är enormt användbara för majoriteten av backendsystem som byggs idag. Elixir är nyckeln till att göra Erlang lika enkelt som andra moderna språk. Och därav ser jag att Elixir, till sin största fördel, höjer taket för hur bra ett system kan byggas.

Mail: lars@underjord.io

Webisite: underjord.io

Twitter: @lawik

Lars Wikman
Rådgivare & problemlösare


Introduktion till Flutter för utvecklare

Varje gång ett nytt ramverk, programmeringsspråk eller verktyg presenteras så blir vi lovade att detta kommer lösa alla problem som de tidigare alternativen misslyckades att hantera. Flutter, Googles cross-platform lösning för appar, är egentligen inte annorlunda ur den aspekten. Det som talar för Flutter handlar mer om att Google undvikit de misstag som andra cross-platform lösningar gjorde, och på så vis har de skapat något som jag tror kommer ta över en stor del av app-utvecklingen framöver. 

Oavsett om jobbar med backend, frontend, eller apputveckling, så är Flutter en teknologi som du borde känna till och förstå. Det som gör Flutter populärt är sådant jag är övertygad om kommer ha en inverkan på andra tekniker. Genom att förstå Flutter så blir du alltså bättre förberedd på hur både appar och webb kommer att byggas framöver.

Deklarativt UI

På senare år så har konceptet declarative programming dykt upp som ett populärt alternativ till det mer traditionella imperative programming. Jag kommer inte göra någon djupdykning i skillnaderna mellan dessa, utan istället fokusera på hur deklarativ programmering fungerar i Flutter. Min förhoppning är att min genomgång och exempel här ska få en bild om varför det är en stor fördel framför andra modeller, och varför Flutter också är ett bättre alternativ än andra deklarativa ramverk (sett till vad vi har för alternativ idag).

Flutter deklarativa modell för att bygga användargränssnitt bygger på Dart, det programmeringsspråk som Flutter använder. Genom en smart design av hur koncept som optional parameters och default values fungerar så har man kunnat skapa en modell för att beskriva användargränssnitt på ett konkret och lättläst vis. Andra ramverk, som React, har också en deklarativ modell, men där har man fått kompromissa med underliggande tekniker och befintliga standarder på ett sätt som skapar en mindre optimal modell för att bygga gränssnitt. Följande kod är ett exempel på hur man bygger en enkel widget i Flutter:

Ovanstående visar på hur Flutters deklarativa modell uppnås genom språket Dart. Ett antal olika widgets kombineras i ett träd för att komponera vår nya widget. Detta görs genom att i funktionen build() konstruera vårt träd. Column representerar helt enkelt en kolumn med flera andra widgets under sig. Vi skapar denna genom att anropa konstruktorn och skicka med två parameterar, mainAxisAlignemnt och children. Den första, mainAxisAlignment, är en valfri parameter och om den inte anges så får den värdet start, vilket medför att dess barn positioneras från toppen och nedåt. Den här modellen att ha valfria parametrar med standard-värden gör att man oftast bara behöver ange ett fåtal när man använder en befintlig widget, vilket i sin tur förenklar koden man behöver skriva.

I Flutter är widgets inte bara komponenter som är synliga, utan också komponenter som lägger till utfyllnad (padding) eller som asynkront laddar data och bygger om din widget när den är klar. Följande exempel visar hur widgeten FutureBuilder kan användas för att ladda data asynkront och visa en ikon (med en smiley) innan den är klar, för att sen bytas ut mot en Text med användarnamnet.

Observera att en widget alltså kan välja att rita om delar av sig själv och behöver inte ens returnera ett träd med samma typ av widgets när det sker. Det här gör det alltså möjligt att beskriva vårt användargränssnitt baserat på olika villkor, och fortfarande använda en deklarativ modell.

Developer Experience

Ett begrepp som har börjat användas mer på senare år är Developer Experience. Detta används för att beskriva hur användningen av ett utvecklingsverktyg, programmeringsspråk eller ramverk upplevs av utvecklare. En bra Developer Experience är alltså något som utvecklare uppskattar och upplever vara mer effektivt att arbeta med. Huruvida en teknik är bättre eller ej handlar ju ofta om subjektiva uppfattningar, vilket är anledningen till att en god Developer Experience är en viktig komponent när man ska välja teknik. Är verktygen undermåliga, programmeringsspråket föråldrat, eller ramverket komplicerat att använda så är risken stor att det kommer medföra att utvecklarna blir mindre effektiva.

Flutter har ett utmärkt stöd i den mest populära texteditorn på marknaden idag: Visual Studio Code. Det finns även tillägg till IntelliJ IDEA från JetBrains om man föredrar det verktyget. Bra stöd är viktigt, men för att bli riktigt framgångsrikt så måste verktygen också vara smarta. Flutter-stödet i Visual Studio Code (och IntelliJ IDEA) har flera viktiga funktioner för att snabbt kunna redigera koden för ett UI. I exemplet nedan visas hur man snabbt och enkelt kan modifiera sitt widget-träd med hjälp av enkla snabbkommandon.

Denna funktion blir extra viktig när man använder en annan funktion i Flutter: Hot Reload. Detta låter en utvecklare uppdatera en app som körs på en telefon eller emulator, utan att behöva starta om den helt. Det går alltså att i realtid se hur ditt UI påverkas bara genom att du sparar koden i texteditorn efter en ändring.

Smarta funktioner ger en bättre upplevelse för utvecklarna. Detta gör dem i sin tur mer effektiva när de arbetar med den tekniken, vilket reducerar tiden det krävs för att bygga klart appen. Developer Experience är en viktig komponent, och Flutter är idag bäst i klassen.

Fokus på prestanda

Ett vanligt problem med cross-platform lösningar är att de måste kompromissa på områden som gör att slutanvändaren kan bli lidande. Ett vanligt problem är att prestandan i användargränssnitten blir avsevärt mycket långsammare än om de skrivits med den native teknik som respektive operativsystem erbjuder.

Flutter har från början lagt ribban för prestanda riktigt högt. Motorn i Flutter garanterar minst 60 FPS (120 FPS om hårdvaran tillåter det), och det är svårt för en utvecklare att av misstag strypa den hastigheten. Detta gör att användarupplevelsen i en app byggt med Flutter känns rapp och responsiv utan att användaren behöver lägga särskilt stort fokus på det området.

Prestandan i Flutter handlar inte bara om hur många FPS den kan rita ut i, men också om att den kan bygga om ett stort och relativt komplext träd av widgets mellan två frames. Det är alltså inget större problem att ditt UI helt ändrar struktur och bygger om alla widgets, då motorn i Flutter är optimerad för att göra just detta. Det här gör att koden för en Flutter app blir enklare och lättare att återanvända. Man behöver inte längre bygga avancerade komponenter som klarar många olika utseenden. Istället bygger man widgets som är specialiserade och växlar snabbt mellan dem vid behov.

Fokus på användargränssnitt

Även om appar har ett stort fokus på användargränssnitt så finns det många situationer när man vill att en app ska köras i bakgrunden. Vanliga exempel är musikspelare eller träningsappar, som vi vill ska fortsätta att köra även om de inte ligger i förgrunden eller när skärmen är släckt. Detta är också exempel på de typer av appar där Flutter passar mindre bra.

Eftersom Flutter har fokuserat helt på att skapa ett ramverk för att bygga användargränssnitt, så har möjligheten att exekvera kod i bakgrunden fått tagit ett steg bakåt. Även om det finns ett visst stöd för detta så är det betydligt mer komplicerat och man kommer ofta få gå över till att skriva kod i Swift respektive Kotlin för att lösa vissa mer plattformsspecifika delar.

När man ska bestämma sig för att använda Flutter eller ej så är detta en bra utgångspunkt. Ska appen köras i bakgrunden, eller direkt använda mer avancerad hårdvara så är det inte rekommenderat att använda Flutter. Appar som musikspelare, rena kamera-appar, träningsappar, appar som använder Bluetooth, o.s.v. är alltså mindre lämpliga kandidater.

Om fokus däremot ligger på själva användargränssnittet och aktiv användning så kan Flutter mycket väl vara ett bra alternativ.

Sammanfattning

Flutter ger dig en avancerad, modern, och högpresterande lösning för att bygga appar. I dagsläget så har fokus legat på iOS och Android, men ramverket har också beta-stöd för webb och desktop (macOS, Windows och Linux). Google satsar stenhårt på att utveckla ramverket och andelen utvecklare som använder Flutter växer dagligen. I dagsläget är Flutter mer populärt än React Native på både GitHub och StackOverflow.

Sammantaget så ser framtiden för Flutter väldigt ljus ut. Tack vare att det har ett stort företag bakom sig, som dessutom driver utvecklingen av den vanligaste mobilplattformen idag (Android), så lämpar sig Flutter mycket väl för många olika typer av applikationer.

Du kan läsa mer om Flutter och hur man bygger appar på https://flutter.dev

För att läsa mer av Erik Hellman kan du klicka in på hans egen blog https://hellsoft.se

Erik Hellman
Mobilutveckling, IoT, Backend/Cloud & Webb