Föreläsning 3 – Kommentarer
Läsanvisningar
Section titled “Läsanvisningar”Färgförklaring för chipsen nedan:
- Läs
- Skumma
- Hoppa över
Clean Code- Ch. 4
- Ch. 5
Föreläsning
Section titled “Föreläsning”Föreläsningen har två delar: en genomgång av Clean Code kapitel 4 (kommentarer), kompletterad med nyare forskning om kommentarer och AI, följt av ett livekodningsavsnitt där arbetet med spelet Ripe Tomato från förra föreläsningen fortsätter.
Föreläsningen: kommentarer (Clean Code kapitel 4)
Section titled “Föreläsningen: kommentarer (Clean Code kapitel 4)”Slides markerade med en grön (teal) kant och etiketten “NYTT” är tillägg genererade med hjälp av AI för den här kursomgången; övriga slides bygger på den tidigare föreläsningen, översatt till svenska. Föreläsningens huvudbudskap: kvaliteten på dina kommentarer är viktigare nu än för några år sedan.
Innehållsvarning: “inga kommentarer” är fel slutsats
Section titled “Innehållsvarning: “inga kommentarer” är fel slutsats”En vanlig feltolkning efter den här föreläsningen är att kommentarer är dåliga och att du ska sluta skriva dem. Boken är visserligen negativ – kommentarer beskrivs som ett nödvändigt ont som inte skulle behövas om programmeringsspråken vore tillräckligt uttrycksfulla – men forskningen ger en blandad bild, och kodläsare är i regel positiva till kommentarer. Studenter har dessutom fått tillbaka inlämningar i andra kurser efter att ha rensat bort alla kommentarer. Målet är att du blir medveten om hur och varför du skriver kommentarer, inte att du slutar.
Kommentarer i en tid med AI
Section titled “Kommentarer i en tid med AI”Kommentarer ger utrymme att förmedla sådant som koden inte säger, och det kan hjälpa både människor och AI-modeller att förstå koden – men bara om texten är relevant och korrekt. Överflödiga och felaktiga kommentarer är skadliga. En människa sorterar ofta bort en kommentar som uppenbart hamnat ur synk med koden; en språkmodell tenderar i stället att tro på den. En kommentar kan också fungera som en prompt: du beskriver först vad du vill ha och låter sedan koden genereras (“engelska är det nya programmeringsspråket”). Den gemensamma nämnaren i forskningen som presenterades: rätt information på rätt abstraktionsnivå – inte maximal mängd text.
Vad forskningen säger
Section titled “Vad forskningen säger”- Kommentarer för syns skull. I en manuell analys av ett urval Java-filer (ett examensarbete)
innehöll ungefär 40 % av kommentarerna ingen information utöver det koden redan sa, till exempel
@param String fileName, filens namn. - Operativsystemskod (ICSE 2009). I Linux, FreeBSD och OpenSolaris bestod 23–30 % av koden av
kommentarer. 22 % av dem förklarade vad ett heltal betydde (vanligt i prestandakritisk kod med
bitmasker), 17 % förklarade dataflöde, kontrollflöde och beroenden, och 11 % hade kunnat uttryckas
med annoteringar (till exempel att ett värde aldrig får vara
null). - Människor (eye-tracking, 2026). Effekten av kommentarer på programförståelsen varierade kraftigt mellan kodstycken – kommentarer kunde både hjälpa och störa, och de ökar den kognitiva belastningen. Författarna betonar kvalitet, relevans och kontext, inte “fler kommentarer”.
- Språkmodeller (NAACL 2024). Felaktig dokumentation försämrade LLM:ers kodförståelse tydligt, medan saknad eller ofullständig dokumentation inte gav samma försämring. En inaktuell kommentar är alltså inte bara ett underhållsproblem för människor utan aktivt missledande AI-kontext.
- Kodöversättning med LLM:er (FASE 2026). Kommentarer kunde både förbättra och försämra översättningen kraftigt, från −90 % till +435 % jämfört med okommenterad kod. “Kommenterad kod” är alltså inte i sig en kvalitetsegenskap för en LLM.
- AI-agenter (ICLR 2026-workshop). Kontextfiler som
AGENTS.mdgav ingen högre task success men mer än 20 % högre inferenskostnad. Skriv inte mer för AI:ns skull – skriv bättre information. - Comment smells (Empirical Software Engineering 2024). En taxonomi med 11 typer av dåliga kommentarer, framtagen ur 2 447 inline-kommentarer – många av typerna känns igen från bokens första upplaga från 2008, så problemen är fortfarande högst aktuella.
Kommentarer ljuger – föredra exekverbar sanning
Section titled “Kommentarer ljuger – föredra exekverbar sanning”Kod förändras, och ingenting tvingar kommentaren att följa med: ingen kompilator kontrollerar att
kommentar och kod överensstämmer. Ett exempel från föreläsarens egen kod: $num = 4; //three values we want to extract – värdet hade ändrats men inte kommentaren. Problemet var dubbelt: kommentaren
upprepade ett hårdkodat värde, och det var bara det intetsägande variabelnamnet num som gjorde
kommentaren nödvändig från början. Med ett namn som numberOfValuesToExtract hade kommentaren varit onödig.
Principen “sanningen finns bara på ett ställe: i koden” betyder att en viktig begränsning bör
uttryckas exekverbart när det går. Kommentaren // age must never be negative kan brytas utan att
något reagerar; en kontroll i setAge som kastar ett RangeError vid negativ ålder går däremot att
verifiera maskinellt – även när en AI-agent refaktorerar koden.
Förklara dig i koden
Section titled “Förklara dig i koden”Kommentarer värderas högre, och är vanligare, i dålig kod – de kompenserar för kod som inte förklarar
sig själv. Städa hellre upp koden. I stället för en kommentar som
// Kontrollera om den anställde har rätt till fulla förmåner ovanför ett villkor med bitflaggor och
åldersjämförelser: höj abstraktionsnivån genom att bryta ut villkoret till
employee.isEligibleForFullBenefits(). Då går både funktionen och anropsstället att förstå utan
kommentar – en repetition av den första föreläsningens budskap om namngivning.
Bra kommentarer
Section titled “Bra kommentarer”- Juridiska kommentarer – copyright och licens. Håll dem korta och hänvisa hellre till en
licensfil (
LICENSE) än att klistra in hela licenstexten i varje källkodsfil. - Informativa kommentarer – tillför information som koden inte ger, till exempel formatet
bakom ett reguljärt uttryck (
// format: "tt:mm:ss EEE, MMM dd, yyyy"). Överväg ändå om informationen kan flyttas in i koden:responderInstance()med kommentaren “returnerar den Responder-instans som testas” kan döpas om tillgetResponderUnderTest(), och formatet kan få en egen klass somGoogleDateTimeStringAdapter. - Förklaring av avsikt – varför koden ser ut som den gör, till exempel
return -1; // vi är "mindre", eftersom innehåll värderas högrei encompareTo. Ett nytt exempel:// Stripe kan skicka samma webhook flera gångerföreawait applyPayment(event)förmedlar ett externt systemkrav, medan// Öka antal försökföreretryCount++bara upprepar koden. Tumregel: skriv det som annars skulle kräva en gissning – särskilt varför, begränsningar och domänkunskap. - Förtydligande av låg abstraktionsnivå –
assertTrue(aa.compareTo(bb) == -1); // aa < bböversätter ett lågnivåuttryck till den betydelse läsaren behöver. - Varningar – metainformation om körtid (“kör inte om du inte har gott om tid”, till exempel en
testsvit som tar flera minuter) och förklaringar som förhindrar “optimeringar” som skulle bli fel
(“
SimpleDateFormatär inte trådsäker, därför skapas varje instans separat”). - TODO – hantera hellre långlivade uppgifter i en issue tracker. En ofärdig metod som returnerar
ett “någonstansvärde” (
return "") under en TODO-kommentar är farlig: glömmer du den slutar applikationen fungera utan att du vet varför. Kasta i stället ett undantag, till exempel ettNotImplementedException(finns inbyggt i C#; i JavaScript får du skapa klassen själv). Med AI-agenter blir en TODO dessutom ytterligare en instruktion som kan påverka agentens beteende. - X-Doc för publika API:er – JSDoc, Javadoc och liknande. Här beskriver du kontrakt och användning för någon som inte ska behöva läsa implementationen, och IDE:n visar dokumentationen när du hovrar över en funktion. I Laboration 2 har du ett publikt API, och där förväntas du tydligt beskriva hur funktionerna används, vilka argument de tar och vad de returnerar. Publika gränssnitt mot andra programmerare är minimistället för den här typen av dokumentation.
Du behöver inte skriva perfekta kommentarer från början. Det viktigaste är att lösa problemet; sedan återvänder du till koden och förbättrar intetsägande kommentarer och namn – precis det som gjordes med Ripe Tomato-koden mellan de två livekodningspassen (se nedan).
Dåliga kommentarer
Section titled “Dåliga kommentarer”- Redundanta kommentarer upprepar typ eller namn utan att tillföra avsikt eller begränsning,
till exempel
private logger = null; // Loggerunder en JSDoc om “Logger-instansen som denna Container är kopplad till”, eller/** @param {number} movieDurationMinutes Filmens längd i minuter */. För en AI-modell kostar de dessutom tokens utan att tillföra något. - Mumlande kommentarer är skrivna till dig själv, inte till läsaren:
// Den är kopplad till en så vi kan inte koppla till andraförutsätter att läsaren redan vet vad “den” och “en” syftar på. Avkoda referenserna:// SQL-anslutningen är redan kopplad till en databas. Vi måste stänga anslutningen innan den kan kopplas till en annan. - Brus –
// Standardkonstruktornovanför en konstruktor, en tom/**/, eller kvarlämnade// console.log(...)från en gammal felsökning. - Kommentarer som beskriver vad koden gör –
// om parametern inte är nullovanförif (param !== null). Kod och kommentar blir två versioner av samma information som måste hållas synkroniserade. Sådana “pedagogiska” kommentarer kan vara rimliga när du lär dig ett nytt språk eller en ny konstruktion, eller när du skriver för en läsare som är ny inom programmering – men i inlämningar i den här kursen vill kursledningen inte se dem. Fundera alltid på vem som ska läsa. - Utkommenterad kod – lämna inte kvar den; den finns kvar i versionshanteringen, och ett bra
commit-meddelande hjälper dig hitta den. Att tillfälligt kommentera ut kod under felsökning är en
sak, men att växla mellan exempelvis test- och serverkonfiguration genom att kommentera in och ut
rader är dålig praxis – använd en flagga i en settings-fil som ligger i
.gitignore, eller en miljövariabel. - HTML i kommentarer – Javadoc-taggar som
<p>gör kommentaren svårläst i editorn. - För mycket information – ingen vill läsa en vägg av text, och långa kommentarer riskerar att inte läsas alls. Behöver du skriva “romanen” hör den hemma i ett Markdown-dokument snarare än i koden. Längre kontextfönster betyder inte heller att all kontext är gratis eller användbar för en AI-modell.
Implicita och tvingande begränsningar
Section titled “Implicita och tvingande begränsningar”En implicit begränsning förväntar sig att programmeraren själv informerar sig tillräckligt för att göra rätt – som lappen “Din förälder diskar inte här!” i ett personalrum. En tvingande begränsning ger återkoppling som förhindrar eller tydligt avslöjar felet – som en tallrik som piper tills den är diskad. Exempel på tvingande begränsningar i kod:
- Trasigt bygge – en medvetet icke-kompilerande rad (“jag var här”) som påminnelse efter ett avbrott, eller att byta namn på något och låta kompilatorn visa alla ställen som måste ändras.
- Typsäkerhet och type hints – en parameter som kräver en instans av en
Password-klass i stället för en sträng. const(C++),final(Java),readonlyoch synlighet (public/private/protected) – ger kompileringsfel, eller körfel i JavaScript, om koden används på ett sätt som inte var avsett.- Asserts och exceptions – ett undantag signalerar ett fel som går att hantera och återhämta sig från (till exempel felaktig användarinmatning), medan en assert är tänkt att avbryta körningen vid ett fel i själva programkoden som inte ska gå att köra vidare från. Om asserts körs i release-läge beror på språk, ramverk och kompilatorinställningar.
- Automatiska tester – ett misslyckat testfall leder till felsökning eller ändrad kod.
Lägg informationen där den hör hemma
Section titled “Lägg informationen där den hör hemma”För AI-assisterad kod beskrevs tre lager av information:
- Exekverbar sanning – kod, typer, scheman, tester, assertions och constraints. Bäst när regeln faktiskt kan verifieras av maskinen.
- Kodkommentarer – lokal avsikt, motivering, domänkunskap, varningar och kontrakt nära den kod de gäller.
- Agentinstruktioner – repository-regler som testkommandon, genererade filer och arkitekturregler. (Under föreläsningen påpekades att mycket av detta lika gärna är utvecklarinstruktioner – det är inte bara agenten som ska arbeta i projektet.)
Kommunicera med avsikt: bli medveten om ditt budskap (vad har koden ännu inte sagt, och kan det uttryckas i koden i stället?) och om mottagaren (vem är det, vilka färdigheter har hen, i vilket syfte läser hen?). Numera har en kommentar ytterligare en mottagare: för kompilatorn ignoreras den, för människan är den dokumentation, men för en LLM eller agent är den input som kan ändra modellens tolkning och nästa kodändring. Därför blir korrekthet viktigare än mängd – en inaktuell kommentar kan lura både nästa programmerare och nästa agent.
AI-genererade och “framtabbade” kommentarer
Section titled “AI-genererade och “framtabbade” kommentarer”En studie från 2026 (ICSE AI-SQE) lät tre LLM:er generera Javadoc för kod skriven efter modellernas träningsdatum: 58,8 % av kommentarerna bedömdes som likvärdiga med originalen och 27,7 % som bättre. Men studien testar dokumentation härledd ur koden – den visar inte att modellen känner till programmerarens ursprungliga motiv. En annan studie (Dhakal et al., 2026) beskriver två sätt att förbättra en kommentar: internalisering (tydligare om hur implementationen fungerar) och externalisering (kontext som varför koden finns och hur den passar in i systemet). Avancerade modeller missar fortfarande ofta just WHY och HOW-TO-USE utan riktad kontext.
En kommentar som tabbats fram i editorn kan alltså vara korrekt men redundant (// Stoppar efter tre försök. om request.retries < 3), eller hitta på ett plausibelt varför som kanske inte stämmer
(// ... för att inte överbelasta API:t.). Det första är en bra kandidat för sammanfattning; det
andra är en svag källa till ny motivering.
Under föreläsningen uppstod en diskussion om beslutsträdet “Finns viktig information som inte syns i koden? Nej → kommentera inte”. En motinvändning var att en kommentar som sammanfattar tio rader kod i en mening är guld värd för den som läser mycket kod skriven av andra: du behöver inte djupläsa koden, bara verifiera att den gör det som beskrivs. Kommentaren blir då en abstraktion av koden – och värdet uppstår när den säger mer än funktionsnamnet redan gör, helst även varför.
Sammanfattning
Section titled “Sammanfattning”Bra kommentarer förklarar kod på låg abstraktionsnivå och varför den ser ut som den gör, dokumenterar publika API:er, innehåller juridisk information, varningar och informativa uppgifter som inte syns i koden (till exempel dynamiskt beteende), kortsiktiga TODO:s och länkar till resurser utanför koden. Den uppdaterade principen för 2026: bra kommentarer förklarar mer – de bevarar information som annars skulle gå förlorad. För både människor och AI gäller samma kärna: korrekt, relevant och på rätt abstraktionsnivå. Och håll kommentaren korrekt över tid – en inaktuell kommentar är teknisk skuld.
All redundans är för övrigt inte dålig för kommunikation: att bli påmind, gärna på lite olika sätt, kan hjälpa – som när en uppsats avslutas med att repetera sina frågeställningar.
Livekodning: Ripe Tomato, pass 2
Section titled “Livekodning: Ripe Tomato, pass 2”Efter pausen fortsatte arbetet med plattformsspelet Ripe Tomato (vanilla JavaScript med p5.js i instansläge), där föregående pass slutade.
Passet inleddes med en genomgång av commits som gjorts efter förra passet – ett medvetet arbetssätt: lös problemet först, återvänd sedan till koden med nya ögon och städa upp kommentarer och namn. Några av ändringarna:
- JSDoc-typer skrivna med gemener (
number,string), en oanvänd egenskap borttagen, ochscaleomdöpt till versaler för att följa konventionen att konstanter skrivs med UPPER_SNAKE_CASE. - Alias-importer (
@/...) konfigurerade så att importvägar utgår från en fast rot i stället för långa relativa sökvägar (../../..) – importerna fortsätter fungera även när filer flyttas. Aliaset pekades senare om tillsrc/js. - Hjälpfunktioner som av misstag hängts på p5-objektet flyttades ut till separata funktioner.
- Inställningar för debuggern i VS Code, så att felsökning kan göras utan kvarglömda
console.log-anrop.
Från Camera till CoordinateConverter
Section titled “Från Camera till CoordinateConverter”I en lokal, ej incheckad .sandbox/-katalog och en spike-gren hade klassen Camera ersatts av
CoordinateConverter. Motiveringen: klassen gjorde inget annat än att konvertera koordinater, och
namnet “kamera” skvallrade om funktionalitet (panorering, zoom) som ännu inte fanns och kanske
aldrig kommer att behövas – premature naming, i linje med principen YAGNI (You Aren’t Gonna Need
It). Förebilden var klassen CDC (device context) i ramverket MFC, som på samma sätt konverterade
mellan koordinatsystem. Samtidigt döptes den allmänna scale om till det mer precisa
pixelsPerTomato, och konverteringsmetoden fick namnet worldToCanvas, med ett exempel i
JSDoc-kommentaren – exempel i kommentarer lyftes fram som särskilt användbara, eftersom de visas när
du hovrar över metoden.
Rita-koden flyttas till en vy
Section titled “Rita-koden flyttas till en vy”Ritfunktionerna i sketchen (index.js) flyttades till en ny klass, GameView. Var
CoordinateConverter skulle placeras ledde till en diskussion om två synsätt på MVC och paket:
- Samla kod med samma ansvar på ett ställe – en vy ska bara innehålla presentationslogik, och koordinatkonvertering hör inte dit.
- Se ett paket som en enhet med ett så litet publikt gränssnitt som möjligt – klasser som
arbetar intimt tillsammans bör ligga tillsammans, och en
utils-katalog på toppnivå skapar ett beroende utåt som bara är motiverat när ett annat paket också använder koden.
Kompromissen blev en utils-katalog inuti views (views/utils/CoordinateConverter.js).
Några andra beslut och begrepp som dök upp:
- Dependency injection kontra testbarhet. Först skickades
CoordinateConverterin viaGameViews konstruktor, så att en mockad variant skulle kunna användas i framtida tester. En TODO lades till om att dokumentera varför – ett exempel på ett beslut som annars lätt går förlorat. Men konverteraren kräver canvasens höjd, och canvasen måste skapas först, så konverteraren skapas nu i stället inuti konstruktorn. Testbarheten gick förlorad, vilket accepterades som ett rimligt pris eftersom inga tester finns ännu. - En varningskommentar som faktiskt behövs. Spelet ritade bara en svart yta tills ordningen
rättades: canvasen skapas i
GameViews konstruktor föreCoordinateConverter, ochGameViewskapas i p5:ssetup(), eftersom p5-objektet inte är färdigt tidigare. Båda platserna fick en kommentar om varför ordningen inte får ändras – precis den typ av varning som föreläsningen tog upp som en bra kommentar. - Feature envy. Fyra anrop i rad till
gameView.drawBackground(),drawTitle()och så vidare från sketchen tydde på att logiken hörde hemma iGameView(information expert). Resultatet blev en enda publikdraw-metod, och de enskilda ritmetoderna kunde göras privata. - Privacy leak. Ett objekt som skickas in via en referens och lagras i ett privat fält kan fortfarande ändras utifrån genom referensen. Att göra defensiva kopior bedömdes inte vara nödvändigt just nu.
- Färre argument. Tomatens x- och y-koordinat ersattes av ett positionsobjekt,
tomatoCenterPosition, som skickas tilldrawtillsammans med diametern.tomatoCenterPosition.x++i p5:sdraw()fick tomaten att röra sig – en hel tomat per bildruta, så den försvann snabbt ur bild.
Början på en modell
Section titled “Början på en modell”Tomatens rörelse är affärslogik och ska inte ligga i vyn, så en modellklass Tomato påbörjades.
Diskussionen gällde vad tomaten ska känna till: startpositionen hör kanske snarare till en bana
(som i Super Mario, där varje bana har sin egen startpunkt), medan diametern hör till den enskilda
tomaten. Passet avslutades med kod som ännu inte var helt färdig (markerad som WIP i
commit-historiken).
Koden finns i det öppna GitHub-repot ripe-tomato. SESSION_2.md i repots rot sammanfattar passet commit för commit, tillsammans med resonemangen bakom varje val. Efter passet lades också en reflektion till, REFLECTION_SESSION_2.md, om hur MVC skiljer sig mellan en request/response-baserad webbapplikation och en spelloop – och om vad som återstår innan modellen, vyn och en kontroller är på plats.