Brian Kernighans råd om "god smak" visar hur läsbar kod sparar tid, minskar buggar och hjälper verkliga team att arbeta snabbare än med kluriga knep.

Namnet Brian Kernighan dyker upp i sammanhang som många utvecklare använder utan att tänka: klassiska Unix-verktyg, C-ekosystemet och decennier av texter som lärde folk att förklara program tydligt. Oavsett om du minns The C Programming Language (med Dennis Ritchie), The Unix Programming Environment eller hans essäer och föredrag, är den röda tråden en envishet för enkla idéer uttryckta rent.
Kernighans bästa råd hänger inte på C-syntax eller Unix-konventioner. Det handlar om hur människor läser: vi skannar efter struktur, förlitar oss på namn, sluter oss till avsikt och blir förvirrade när koden gömmer mening bakom knep. Därför spelar "smak" i läsbarhet fortfarande roll när du skriver TypeScript, Python, Go, Java eller Rust.
Språk förändras. Verktyg förbättras. Team levererar fortfarande funktioner under tidspress, och de flesta kodstycken underhålls av någon annan än den ursprungliga författaren (ofta framtida du). Tydlighet är multiplikatorn som får allt detta att överleva.
Det här är ingen hyllning till "hero coding" eller ett rop att memorera gamla regler. Det är en praktisk guide till vanor som gör vardagskod enklare att arbeta med:
Kernighans inflytande är viktigt eftersom det pekar mot ett enkelt, teamvänligt mål: skriv kod som kommunicerar. När kod läser som en klar förklaring, spenderar du mindre tid på att avkoda den och mer tid på att förbättra den.
"God smak" i läsbar kod handlar inte om personlig stil, flashiga mönster eller att pressa ihop en lösning till minst antal rader. Det är vanan att välja det enklaste tydliga alternativet som pålitligt förmedlar avsikten.
En lösning med god smak svarar på en grundläggande fråga för nästa läsare: Vad försöker den här koden göra, och varför gör den det på det här sättet? Om svaret kräver mentala gymnastikövningar, dolda antaganden eller att avkoda kluriga trick, kostar koden teamet tid.
Det mesta kod skrivs inte bara — den läses långt oftare. "God smak" behandlar läsning som huvudaktiviteten:
Därför handlar läsbarhet inte bara om estetik (indentering, radlängd eller om du föredrar snake_case). De är hjälpsamma, men "god smak" handlar främst om att göra resonemang enkelt: klara namn, uppenbart kontrollflöde och förutsägbar struktur.
Ett vanligt misstag är att optimera för korthet istället för tydlighet. Ibland är den tydligaste koden lite längre eftersom den gör stegen explicita.
Till exempel, jämför:
Den andra versionen kan lägga till rader, men reducerar den kognitiva belastningen som krävs för att verifiera korrekthet. Den gör också buggar enklare att isolera och ändringar säkrare att tillämpa.
God smak är att veta när man ska sluta "förbättra" en lösning med listigheter och istället göra avsikten tydlig. Om en kollega kan förstå koden utan att be om en rundvisning har du valt rätt.
Kluftig kod känns ofta som en vinst i stunden: färre rader, ett snyggt trick, en "wow"-faktor i diffen. I ett riktigt team blir den klokheten en återkommande nota—betald i onboarding-tid, granskningstid och tvekan varje gång någon måste röra koden igen.
Onboarding bromsas. Nya kollegor måste inte bara lära sig produkten; de måste också förstå ditt privata dialekt av genvägar. Om en funktions förståelse kräver att man avkodar kluriga operatorer eller implicita konventioner, undviker folk att ändra den—eller ändrar den med rädsla.
Granskningar blir längre och mindre pålitliga. Granskare lägger energi på att bevisa att trikset är korrekt snarare än att bedöma om beteendet matchar avsikten. Värre, klurig kod är svårare att mentalt simulera, så granskare missar kantfall som de skulle ha fångat i en rak version.
Kluftighet hopar sig under:
Några återkommande bovar:
17, 0.618, -1) som kodar regler ingen kommer ihåg.&& / ||) som förutsätter att läsaren kan subtila utvärderingsregler.Kernighans poäng om "smak" syns här: tydlighet handlar inte om att skriva mer; det handlar om att göra avsikten uppenbar. Om en "smart" version sparar 20 sekunder idag men kostar 20 minuter för varje framtida läsare är den inte smart—den är dyr.
Kernighans "smak" visar sig ofta i små, upprepbara beslut. Du behöver ingen omfattande omskrivning för att göra koden lättare att leva med—små tydlighetsvinster lägger sig varje gång någon skummar en fil, söker efter beteende eller fixar en bugg under tidspress.
Ett bra namn minskar behovet av kommentarer och gör misstag svårare att dölja.
Sträva efter intention-avslöjande namn som matchar hur teamet pratar:
invoiceTotalCents framför sum.Om ett namn tvingar dig att avkoda det gör det motsatsen till sitt jobb.
Det mesta läsande är skanning. Konsekvent vittutrymme och struktur hjälper ögat hitta det viktiga: funktionsgränser, villkor och "happy path".
Några praktiska vanor:
När logiken blir svår är läsbarheten ofta bättre om beslut görs explicita.
Jämför dessa två stilar:
// Harder to scan
if (user && user.active && !user.isBanned && (role === 'admin' || role === 'owner')) {
allow();
}
// Clearer
if (!user) return deny('missing user');
if (!user.active) return deny('inactive');
if (user.isBanned) return deny('banned');
if (role !== 'admin' && role !== 'owner') return deny('insufficient role');
allow();
Den andra versionen är längre, men den läser som en checklista—och är enklare att utöka utan att bryta.
Det här är "små" val, men de är det dagliga hantverket i underhållbar kod: namn som håller sig ärliga, formatering som guidar läsaren och kontrollflöde som aldrig tvingar dig till mental gymnastik.
Kernighans klarhetsstil syns tydligast i hur du delar upp arbete i funktioner och moduler. En läsare ska kunna skumma strukturen, gissa vad varje del gör och ha rätt innan hen läser detaljerna.
Sikta på funktioner som gör exakt en sak på en "zoomnivå". När en funktion blandar validering, affärsregler, formatering och I/O måste läsaren hålla flera trådar i huvudet.
Ett snabbt test: om du skriver kommentarer som "// nu gör vi X" inne i en funktion är X ofta en bra kandidat för en separat funktion med ett tydligt namn.
Långa parameterlistor är en dold komplexitetsskatt: varje anropsställe blir som en mini-konfigurationsfil.
Om flera parametrar alltid reser tillsammans, gruppera dem genomtänkt. Options-objekt (eller små datastrukturer) kan göra anropsställen självförklarande—om du håller gruppen sammanhängande och undviker att tömma allt i en "misc"-påse.
Föredra också att skicka domänkoncept istället för primitiva typer. UserId slår string, och DateRange slår (start, end) när dessa värden har regler.
Moduler är löften: "Allt du behöver för detta koncept finns här, resten finns någon annanstans." Håll moduler små nog att du kan hålla deras syfte i huvudet, och designa gränser som minimerar sidoeffekter.
Praktiska vanor som hjälper:
När du behöver delat tillstånd, namnge det ärligt och dokumentera invarians. Klarhet handlar inte om att undvika komplexitet—det handlar om att placera den där läsaren förväntar sig den. För mer om att behålla dessa gränser under ändringar, se /blog/refactoring-as-a-habit.
Kernighans "smak" visar sig i hur du kommenterar: målet är inte att annotera varje rad, utan att minska framtida förvirring. Den bästa kommentaren är den som förhindrar en felaktig antagelse—särskilt när koden är korrekt men överraskande.
En kommentar som upprepar koden ("increment i") lägger till brus och lär läsare att ignorera kommentarer. Användbara kommentarer förklarar avsikt, avvägningar eller begränsningar som inte är uppenbara från syntaxen.
# Bad: says what the code already says
retry_count += 1
# Good: explains why the retry is bounded
retry_count += 1 # Avoids throttling bans on repeated failures
Om du frestas att skriva "vad"-kommentarer är det ofta ett tecken på att koden borde vara tydligare (bättre namn, mindre funktion, enklare kontrollflöde). Låt koden bära fakta; låt kommentarer bära resonemanget.
Inget skadar förtroendet snabbare än en föråldrad kommentar. Om en kommentar är valfri glider den med tiden; om den är felaktig blir den en aktiv källa till buggar.
En praktisk vana: behandla kommentaruppdateringar som en del av förändringen, inte som "trevligt att ha". Under granskningar är det rimligt att fråga: Stämmer den här kommentaren fortfarande med beteendet? Om inte, uppdatera den eller ta bort den. "Ingen kommentar" är bättre än "fel kommentar".
Inline-kommentarer är för lokala överraskningar. Bredare vägledning hör hemma i docstrings, README-filer eller utvecklarnoteringar—särskilt för:
En bra docstring berättar hur man använder funktionen korrekt och vilka fel som kan uppstå, utan att återge implementationen. En kort /docs eller /README-notis kan fånga "varför vi gjorde så här"-historien så den överlever refaktorer.
Det tysta vinsten: färre kommentarer, men var och en tjänar sin plats.
Det mesta kod ser "fint" ut på happy path. Den verkliga smaken testas när indata saknas, tjänster time-out:ar eller en användare gör något oväntat. Under stress tenderar klurig kod att dölja sanningen. Tydlig kod gör fel uppenbara—och återställbara.
Felmeddelanden är en del av din produkt och din felsökningsworkflow. Skriv dem som om nästa person som läser är trött och på jour.
Inkludera:
Om du har loggning, lägg till strukturerad kontext (som requestId, userId eller invoiceId) så meddelandet är handlingsbart utan att gräva i orelaterade data.
Frestandet finns att "hantera allt" med en klurig enradare eller en generisk catch-all. God smak är att välja de få kantfall som betyder något och göra dem synliga.
Till exempel läser en explicit gren för "tomt indata" eller "inte hittad" ofta bättre än en kedja av transformationer som implicit kan producera null någonstans i mitten. När ett specialfall är viktigt, namnge det och sätt det i förgrunden.
Att blanda returformer (ibland ett objekt, ibland en sträng, ibland false) tvingar läsare att hålla en mental beslutsträd. Föredra mönster som förblir konsekventa:
Tydlig felhantering minskar överraskningar—och överraskningar är där buggar och nattliga sidor trivs.
Tydlighet handlar inte bara om vad du menade när du skrev koden. Det handlar om vad nästa person förväntar sig se när hen öppnar en fil kl. 16:55. Konsekvens gör "att läsa kod" till mönsterigenkänning—färre överraskningar, färre missförstånd, färre debatter som upprepas varje sprint.
En bra team-stilguide är kort, specifik och pragmatisk. Den försöker inte koda in varje preferens; den avgör återkommande frågor: namngivningskonventioner, filstruktur, felhanteringsmönster och vad "klart" betyder för tester.
Det verkliga värdet är socialt: det förhindrar att samma diskussion börjar om vid varje ny pull request. När något är nedskrivet flyttas granskningarna från "jag föredrar X" till "vi kom överens om X (och här är varför)". Håll den levande och lätt att hitta—många team placerar den i repot (till exempel /docs/style-guide.md) så den är nära koden.
Använd formaterare och linters för allt som är mätbart och tråkigt:
Detta frigör människor att fokusera på mening: namn, API-form, kantfall och om koden matchar avsikten.
Manuella regler behövs fortfarande när de beskriver designval—till exempel "Föredra tidiga returns för att minska inbäddning" eller "En publik ingångspunkt per modul." Verktyg kan inte fullt ut döma sådant.
Ibland är komplexitet motiverad: tajta prestandakrav, inbäddade begränsningar, knepig samtidighet eller plattformsspecifikt beteende. Överenskommelsen bör vara: undantag är tillåtna, men de måste vara explicita.
En enkel standard hjälper: dokumentera avvägningen i en kort kommentar, lägg till ett mikrobenchmark eller mätning när prestanda anges, och isolera den komplexa koden bakom ett tydligt gränssnitt så större delen av kodbasen förblir läsbar.
En bra kodgranskning ska kännas mindre som en inspektion och mer som en kort, fokuserad lektion i "god smak". Kernighans poäng är inte att klurig kod är ond—det är att klurighet är dyrt när andra måste leva med den. Granskningar är där team kan synliggöra den avvägningen och välja tydlighet medvetet.
Börja med att fråga: "Kan en kollega förstå detta i en genomläsning?" Det betyder vanligtvis att titta på namn, struktur, tester och beteende innan du dyker ner i mikrooptimeringar.
Om koden är korrekt men svår att läsa, behandla läsbarhet som ett riktigt fel. Föreslå omnamngivning för att reflektera avsikt, dela upp långa funktioner, förenkla kontrollflödet eller lägg till ett litet test som demonstrerar förväntat beteende. En granskning som fångar "det här funkar, men jag kan inte se varför" förhindrar veckors framtida förvirring.
En praktisk ordning som fungerar bra:
Granskningar går fel när feedback formuleras som poängräkning. Istället för "Varför gjorde du så här?" prova:
Frågor inbjuder till samarbete och lyfter ofta begränsningar du inte visste om. Förslag kommunicerar riktning utan att antyda inkompetens. Denna ton är hur "smak" sprids i ett team.
Om du vill ha konsekvent läsbarhet, förlita dig inte på granskarens humör. Lägg till några "tydlighetskontroller" i din granskningsmall och definition of done. Håll dem korta och specifika:
Med tiden gör detta granskningar till undervisning i omdöme—precis den dagliga disciplin Kernighan förespråkade.
LLM-verktyg kan producera fungerande kod snabbt, men "fungerar" är inte den ribba Kernighan pekade på—kommunicerar är det. Om ditt team använder en vibe-coding workflow (t.ex. bygga funktioner via chatt och iterera på genererad kod) är det värt att behandla läsbarhet som ett förstaklassigt acceptanskriterium.
På plattformar som Koder.ai, där du kan generera React-frontends, Go-backends och Flutter-mobila appar från en chattprompt (och exportera källkoden efteråt), gäller samma smakdrivna vanor:
Hastighet är mest värdefull när output fortfarande är lätt för människor att granska, underhålla och bygga vidare på.
Tydlighet är inte något du "uppnår" en gång. Koden förblir läsbar bara om du fortsätter att putsa den mot klart språk när krav ändras. Kernighans anda passar här: föredra stadiga, begripliga förbättringar framför heroisk omskrivning eller "smarta" enradare som imponerar idag och förvirrar nästa månad.
Den säkraste refaktoriseringen är tråkig: pyttesmå ändringar som behåller beteendet identiskt. Om du har tester, kör dem efter varje steg. Om du inte har det, lägg till några fokuserade kontroller kring området du rör—tänk på dem som temporära säkerhetsräcken så du kan förbättra struktur utan rädsla.
En praktisk rytm:
Små commits gör också kodgranskning enklare: kollegor kan bedöma avsikten istället för att leta efter sidoeffekter.
Du behöver inte rensa ut varje "klurig" konstruktion på en gång. När du rör kod för en funktion eller bugg, byt ut kluriga genvägar mot raka motsvarigheter:
Detta är hur tydlighet vinner i verkliga team: en förbättrad hotspot i taget, precis där folk redan arbetar.
Inte all städning är brådskande. En användbar regel: refaktorera nu när koden aktivt förändras, ofta missförstås eller sannolikt orsakar buggar. Schemalägg senare när den är stabil och isolerad.
Gör refaktoreringsskulden synlig: lämna en kort TODO med kontext, eller skapa en ticket som beskriver problemet ("svårt att lägga till nya betalningsmetoder; funktionen gör 5 jobb"). Då kan ni besluta medvetet—snarare än att låta förvirrande kod tyst bli teamets permanenta skatt.
Om du vill att "god smak" ska visa sig konsekvent, gör det enkelt att praktisera. Här är en lättviktig checklista du kan återanvända i planering, kodning och granskning—kort nog att minnas, specifik nog att agera på.
Före: process(data) gör validering, parsing, sparande och loggning på ett ställe.
Efter: Dela upp i validateInput, parseOrder, saveOrder, logResult. Huvudfunktionen blir en läsbar disposition.
Före: if not valid then return false upprepas fem gånger.
Efter: En upfront-guard eller en valideringsfunktion som returnerar en tydlig lista med problem.
Före: x, tmp, flag2, doThing().
Efter: retryCount, draftInvoice, isEligibleForRefund, sendReminderEmail().
Före: En loop med tre specialfall gömda i mitten.
Efter: Hantera specialfall först (eller extrahera hjälpare), och kör sedan den raka loopen.
Välj en förbättring att anta den här veckan: "inga nya förkortningar", "happy path först", "extrahera en hjälpare per PR" eller "varje felmeddelande inkluderar nästa steg." Följ det i sju dagar och behåll det som faktiskt gjorde läsande enklare.
Kernighans inflytande handlar mindre om C och mer om en hållbar princip: kod är ett kommunikationsmedel.
Språk och ramverk förändras, men team behöver fortfarande kod som är lätt att skanna, resonera kring, granska och felsöka — särskilt månader senare och under tidspress.
"God smak" betyder konsekvent att välja det enklaste klara alternativet som förmedlar avsikten.
Ett användbart test är: kan en kollega svara på "vad gör detta och varför görs det så?" utan att behöva avkoda knep eller förlita sig på dolda antaganden?
Eftersom majoriteten av kod läses mycket oftare än den skrivs.
Att optimera för läsare minskar onboarding-tid, friktion i granskningar och risken för felaktiga ändringar — särskilt när den som ska underhålla är "framtida du" med mindre kontext.
Skatten visar sig som:
Om den kluriga versionen sparar sekunder nu men kostar minuter varje gång den ändras är det ett nettotapp.
Vanliga syndare:
Dessa mönster gömmer mellanliggande tillstånd och gör att granskningar missar kantfall.
När det minskar kognitiv belastning.
Att göra steg explicita med namngivna variabler (t.ex. validate → normalize → compute) kan göra korrekthet enklare att verifiera, förenkla felsökning och göra framtida ändringar säkrare — även om det lägger till några rader.
Sikta på:
invoiceTotalCents istället för sum)Om du måste avkoda ett namn gör det sitt jobb dåligt; namnet ska minska behovet av kommentarer.
Föredra enkel, explicit branching och håll "happy path" synlig.
Taktiker som brukar hjälpa:
Kommentera varför, inte vad.
Bra kommentarer fångar avsikt, avvägningar, begränsningar eller icke-uppenbara invarianta. Undvik att berätta vad koden redan säger, och behandla kommentaruppdateringar som en del av ändringen — felaktiga kommentarer är värre än inga kommentarer.
Använd verktyg för mekaniska regler (formatering, imports, uppenbara footguns) och reservera mänsklig granskning för mening.
En lättviktig stilguide hjälper genom att avgöra återkommande beslut (namngivning, struktur, felhantering) så att granskningar handlar om tydlighet och beteende, inte personliga preferenser.
När du gör undantag för prestanda eller plattformsbegränsningar, dokumentera avvägningen och isolera komplexiteten bakom ett rent gränssnitt.