Är folk dåliga på skriva kod eller är det jag som är dålig på läsa kod?

Är folk dåliga på skriva kod eller är det jag som är dålig på läsa kod?

Idag satte jag mig in i ett C++ bibliotek för Arduino. Jag skulle leda efter vad för funktion retinerar som datatyp.

Hittade den inte i dokumentationen. När jag skulle dyka ned i koden så kände jag att hela C++ koden var ett enda trassel, men hag kände även att skaparen hade stor kunskap om C++ då mystiska funktioner och variabler och datatyper användes. Termer som jag aldtig har läst om förut.

Varför blir det så här? När jag skriver C++ kod så håller jag mig enkel och följer Jan Skansholm C++ Direkt, inte Bjarne Storstrup C++. Jag försöker skriva så pedagogisk och luftig kod dom det bara går. Snygg struktur och symetrisk struktur för alla klasser. Jag blandar inte in _ eller ___ i funktions eller variabelnamn. Istället använder jag this. Jag deklarerar alltid klassnamnet med stor bokstav och objektnamnet med liten boxstav.

Jag undviker till varje pris att lämna övet avancerad kod och jag håller mig alltid enkel. Jag planerar min struktur först som ett verkligt exempel. Är jag behov av arv eller inte, tänker jag. Klarar jag mig med endast grund grund grund OOP, tänker jag. Måste jag ha en headerfil för varje .cpp fil, tänker jag?

Jag kommenterar mycket och förklarar vart man ska börja. Men då är frågan: Är det jag som är dålig eller är det andra som skriver för dåligt?

Kan ju vara så att kodaren skrivit genial kod för sig själv, som samtidigt är hieroglyfer för alla andra. Lite som när en person har riktigt dålig handstil.

Måste något av sätten vara dålig kod? Vad som är dåligt eller bra kanske beror på tidigare erfarenhet? Säger inte att det är så i det här fallet, håller mig väl neutral men skulle personligen följa att koden ska vara lättläslig, brukar exempelvis försöka undvika att förkorta variabelnamn allt för mycket då det i många fall när jag läsar andras kod kan vara helt omöjligt att förstå vad sekvensen av tillsynes slumpmässiga karaktärer ska representera.

Skrivet av heretic16:

Idag satte jag mig in i ett C++ bibliotek för Arduino. Jag skulle leda efter vad för funktion retinerar som datatyp.

Hittade den inte i dokumentationen. När jag skulle dyka ned i koden så kände jag att hela C++ koden var ett enda trassel, men hag kände även att skaparen hade stor kunskap om C++ då mystiska funktioner och variabler och datatyper användes. Termer som jag aldtig har läst om förut.

Varför blir det så här? När jag skriver C++ kod så håller jag mig enkel och följer Jan Skansholm C++ Direkt, inte Bjarne Storstrup C++. Jag försöker skriva så pedagogisk och luftig kod dom det bara går. Snygg struktur och symetrisk struktur för alla klasser. Jag blandar inte in _ eller ___ i funktions eller variabelnamn. Istället använder jag this. Jag deklarerar alltid klassnamnet med stor bokstav och objektnamnet med liten boxstav.

Jag undviker till varje pris att lämna övet avancerad kod och jag håller mig alltid enkel. Jag planerar min struktur först som ett verkligt exempel. Är jag behov av arv eller inte, tänker jag. Klarar jag mig med endast grund grund grund OOP, tänker jag. Måste jag ha en headerfil för varje .cpp fil, tänker jag?

Jag kommenterar mycket och förklarar vart man ska börja. Men då är frågan: Är det jag som är dålig eller är det andra som skriver för dåligt?

Jag tror att folk som tycker att lättläst kod är viktigt brukar hålla sig till andra programspråk. När jag snackat med folk som gillar C++ snackar de mest om oneliners och annat som är svårt att skriva och obegripligt att läsa. Dessutom ska det vara vim som textredigerare och i3 som användargränssnitt i Linux för att vara så hacker som möjligt.

Skrivet av kazen_90:

Jag tror att folk som tycker att lättläst kod är viktigt brukar hålla sig till andra programspråk. När jag snackat med folk som gillar C++ snackar de mest om oneliners och annat som är svårt att skriva och obegripligt att läsa. Dessutom ska det vara vim som textredigerare och i3 som användargränssnitt i Linux för att vara så hacker som möjligt.

Jag brukar inte skriva allt på en rad. Pythonkod är klassisk onelinerkod. Men det ger en väldigt fin kod.

Så du menar att dom som skriver avancerad kod gör det med vilje?

När jag använder OOP så har jag goda skäl till det. Annars är det funktioner som gäller.

Skickades från m.sweclockers.com

Skrivet av heretic16:

Jag brukar inte skriva allt på en rad. Pythonkod är klassisk onelinerkod. Men det ger en väldigt fin kod.

Så du menar att dom som skriver avancerad kod gör det med vilje?

När jag använder OOP så har jag goda skäl till det. Annars är det funktioner som gäller.

Skickades från m.sweclockers.com

Jag misstänker helt enkelt att folk inte väljer att lägga extra tid för att göra koden ännu enklare i C++ - kretsar, eftersom det är så mycket snack om komplexa grejer jämt, men de flesta jag snackat med som gillar C++ är ganska unga så min bild kan vara helt fel.

Folk som skriver Java brukar inte använda objektorientering när man har goda skäl, utan det är en oskriven regel att alltid skriva kod som är anpassad till domänen (med OOP), vilket gör programmet mer lättläst. Sånt gör väl att folk eftersträvar enklare kod.

Men det finns nog många som har olika synpunkter här, jag är själv inte riktigt en erfaren programmerare och har säkert många fel i det jag skriver.

Skrivet av kazen_90:

Jag tror att folk som tycker att lättläst kod är viktigt brukar hålla sig till andra programspråk. När jag snackat med folk som gillar C++ snackar de mest om oneliners och annat som är svårt att skriva och obegripligt att läsa. Dessutom ska det vara vim som textredigerare och i3 som användargränssnitt i Linux för att vara så hacker som möjligt.

Svårläst kod är dålig kod - oavsett programmeringsspråk.
Avancerade one-liners och liknande har sällan någon praktisk användning, utan är mer plojgrejer.

Sen kan det ju vara så att vissa kodkonstruktioner kan se obegripliga ut till en början, medan de är uppenbara för en van programmerare. Det händer dock inte så ofta.

Skrivet av kazen_90:

Folk som skriver Java brukar inte använda objektorientering när man har goda skäl, utan det är en oskriven regel att alltid skriva kod som är anpassad till domänen (med OOP), vilket gör programmet mer lättläst. Sånt gör väl att folk eftersträvar enklare kod.

En skillnad mellan Java och C++ är ett Java är ett objektorienterat språk, medan C++ inte är objektorienterat i sig, även om det stöder objektorienterad programmering.

Med andra ord, i Java måste du nästan använda objektorientering för att det skall bli ett bra program. Så är inte fallet i C++.

Skrivet av Erik_T:

Svårläst kod är dålig kod - oavsett programmeringsspråk.
Avancerade one-liners och liknande har sällan någon praktisk användning, utan är mer plojgrejer.

Sen kan det ju vara så att vissa kodkonstruktioner kan se obegripliga ut till en början, medan de är uppenbara för en van programmerare. Det händer dock inte så ofta.

Du gick in där på att vad som är svårläst för en nybörjare kan vara enkelt för mer avancerade programmerare. Jag tror faktiskt att detta kan vara mer vanligt än du implicerar. Ett språk där detta beteende är vanligt är Haskell. Visst kan det vara jobbigt som ovan att förstå vissa grejer, men när man väl greppar e.g. Monader, point-free, Kinds, etc, så kan man plötsligt uppskatta simpelheten. Jag tror det är underskattat att skriva simpel men svår kod vs komplex men enkel kod.

Drar man "komplex men enkel kod" till det extrema får man istället språk som Go. Jag ser visst värde i Go, men det är inget tvivel om att lösningarna kan bli väldigt långa och kodbasen full av duplicering. Om det är viktigt att många människor ska kunna förstå och bidra till en kodbas, som fallet är på e.g. Google, så är Go ett väldigt bra val. När man dock har råd att utesluta icke-experter, vilket man definitivt kan göra ibland, så är ett språk designat för minsta gemensamma nämnare kanske inte lika lämpligt. Samma resonemang gäller även för olika avancerade kodsätt inom ett språk (C++), precis som för mellan olika avancerade språk.

Som en utvecklare av styrsystem till maskiner som ska hålla minst 50 år så är rådet att skriva så enkel kod som möjligt och slösa med kommentarer.

Det som är helt självklart för dig i dag är ren hokus pokus för någon annan om 10 år.

Kompilatorer idag är så duktiga att oavsett om du skriver allt på en rad, använder define till förbannelse eller bara skriver tusen rader if-satser så kommer programmet ändå att snurra på bra.

Skriv enkelt även om du tycker att det är fjantigt.

Och även om alla borde fatta dina genialiska om än lite kryptiska kodsnuttar, så kommentera dem som om resten av världens kodare är idioter. Det kan vara DU som ska rota i det längre fram.

Jag har gjort detta i 25+ år och mina råd är inte tagna ur luften.

Skrivet av Erik_T:

Svårläst kod är dålig kod - oavsett programmeringsspråk.
Avancerade one-liners och liknande har sällan någon praktisk användning, utan är mer plojgrejer.

Sen kan det ju vara så att vissa kodkonstruktioner kan se obegripliga ut till en början, medan de är uppenbara för en van programmerare. Det händer dock inte så ofta.

Här är koden jag talar om.

Jag kunde inte hitta vad metoden buffer retunerar för datatyp.

https://github.com/adafruit/Adafruit_BluefruitLE_nRF51

Fån denna klass
https://github.com/adafruit/Adafruit_BluefruitLE_nRF51/blob/m...

Skickades från m.sweclockers.com

Senast redigerat 2019-04-08 19:47

@heretic16: Jag kanske är blind men ser ingen buffer metod? Det jag dock ser är att Adafruit_BluefruitLE_UART ärver från Adafruit_BLE som ärver från Adafruit_ATParser som har den publika variabeln "char buffer[BLE_BUFSIZE+1];" ... Jag kanske misstolkade vad som menas med buffer dock?

Embeddedkod som dessutom är abstraherad för att funka på olika hårdvara är inte alltid enkel att läsa. Det mesta inom embedded, eller egentligen ju närmre hårdvaran man kommer blir per automatik svårare just för att det de facto blir mer avancerat.

Jag ser ingen metod kallad buffer? Arduino är också gravt abstraherat, om du försöker sätta dig in i alla lager där så kommer du bli förvirrad. Vinsten av abstraktion är ju dock att i din kontext kan du använda dig av samma kod på olika hårdvara. Någonstans måste ju koden mot hårdvaran finnas..

Jag personligen tycker exempelvis att Winapi är ett totalt clusterfuck i regel. Motsatt gäller för OpenBSD/Linux där de flesta APIer bara makes sense. Det kan handla om ren kod som är svårläst, men jag skulle säga att logiken bakom är viktigare än ”snygg kod”. Prova enumrera usb-enheter på windows (och hämta samtidigt ut enheternas serienummer exempelvis) så förstår du vad jag menar

Sen kan väl tilläggas att just Arduinolibbar är väl inte rätta stället att leta efter bra kod. Det finns nog mer skräp i den sfären än vad det finns bra grejer. Det är mycket happy hacking just för att ”det är så enkelt” (vips jag ändrade från en etta till en nolla här och titta det funkar, ship it!)

Senast redigerat 2019-04-08 20:16
Skrivet av kazen_90:

Jag tror att folk som tycker att lättläst kod är viktigt brukar hålla sig till andra programspråk. När jag snackat med folk som gillar C++ snackar de mest om oneliners och annat som är svårt att skriva och obegripligt att läsa. Dessutom ska det vara vim som textredigerare och i3 som användargränssnitt i Linux för att vara så hacker som möjligt.

Hahaha, jag känner igen mig... även om jag inte på något sätt är grym på C++ så älskar jag både vim och i3!

Men till topic. När jag läser ditt inlägg, TS, så känner jag igen mig något grymt. Och min mycket bestämda uppfattning är att just många Arduino-libbar är sjukt dåligt skrivna. Jag har sett det många gånger. Spagettikod hit och dit, och onödiga och fula lösningar. Kort sagt tror jag att det har att göra med att många av de som var tidiga ute med att skriva libbar till Arduino helt enkelt inte var så duktiga programmerare. Detta var innan Arduino hade slagit igenom och därför var det en ganska liten klick som höll på med det. Och många utav de som syssslade med det var mycket bättre hårdvaru- och elektroingenjörer än de var utvecklare Men, jag spekulerar mest.

Jag tycker den koden ser helt OK ut. Man måste dock antagligen veta hur protokollet ser ut för att förstå vad den gör, men strukturmässigt ser jag inga direkta konstigheter. Jag har iofs knappt kodat C++ sedan före sekelskiftet, så det må vara gammal kod.

Den klass som du länkar till verkar, som tidigare sagt, inte ha någon buffer-metod. Är det utility/Adafruit_FIFOs buffer som du har problem med? void*? I så fall är svaret att den kan peka på vad som helst.

Skrivet av Erik_T:

En skillnad mellan Java och C++ är ett Java är ett objektorienterat språk, medan C++ inte är objektorienterat i sig, även om det stöder objektorienterad programmering.

Med andra ord, i Java måste du nästan använda objektorientering för att det skall bli ett bra program. Så är inte fallet i C++.

Nej både C++ och Java sköter objekt på ungefär samma sätt, när man inte räknar dem som OO är pga att primitiva är inte objekt.

Skickades från m.sweclockers.com

Skrivet av heretic16:

Här är koden jag talar om.

Jag kunde inte hitta vad metoden buffer retunerar för datatyp.

https://github.com/adafruit/Adafruit_BluefruitLE_nRF51

Fån denna klass
https://github.com/adafruit/Adafruit_BluefruitLE_nRF51/blob/m...

Skickades från m.sweclockers.com

Finns väl ingen metod "buffer" i den filen du länkar? Annars är väl just den detaljen identisk för alla "C" språk (C, C++, Java, C#)?

Koden som länkas är hyfsat enkel, men den innehåller några grodor. Det som kan potentiellt ställa till det är att man använder symboler vars namn börjar på '_'. Symboler som börjar med ett eller två '_' är reserverade för kompilator-, standardbibliotek- och system-konstruktörerna.

Hyfsat vanligt i C++ världen att medlemsvariabler har ett '_' på slutet. Det så man direkt ser när något är en medlemsvariabel utan att behöva slänga på this-> överallt.

Inte något direkt fel, men att kombinera '_' som avgränsare med "camel case" känns lite oortodoxt, typ Adafruit_BluefruitLE_UART. De flesta väljer en av metoderna, även om det kan kombineras för olika typer. T.ex. rätt vanligt att konstanter är FOO_BAR medan en typ är FooBar och funktion/metod fooBar alt. foo_bar.

Skrivet av ZecretW:

Som en utvecklare av styrsystem till maskiner som ska hålla minst 50 år så är rådet att skriva så enkel kod som möjligt och slösa med kommentarer.

Det som är helt självklart för dig i dag är ren hokus pokus för någon annan om 10 år.

Kompilatorer idag är så duktiga att oavsett om du skriver allt på en rad, använder define till förbannelse eller bara skriver tusen rader if-satser så kommer programmet ändå att snurra på bra.

Skriv enkelt även om du tycker att det är fjantigt.

Och även om alla borde fatta dina genialiska om än lite kryptiska kodsnuttar, så kommentera dem som om resten av världens kodare är idioter. Det kan vara DU som ska rota i det längre fram.

Jag har gjort detta i 25+ år och mina råd är inte tagna ur luften.

Kan inte hålla med tillräckligt nog! För bara några veckor sedan behövde jag gräva i min egen C-kod för en viss typ av styrning och det är ca 5 år sedan jag var i den delen och kollade sist men tack store hade jag kommenterat hyfsat OK så det gick relativt smärtfritt att navigera bland funktionerna.

Förra året däremot...inte mycket kod, några tusen rader bara, såg snyggt skrivet ut och vissa delar var fiffiga men hårdkodade tröskelvärden lite var stans och ca 2 rader med kommentarer. Även fast koden var korrekt och snygg så var det ett helvete att leta upp alla jämförelser och trösklar som skulle justeras. Ett tiotal define's hade samlat alla dessa på ett ställe och besparat en veckas jobb.
Anekdot: Kunden säger: "Vi behöver ändra några GPIO och lägga till en mjukvaru-funktion, klart till imorgon Ok?". Kritiska styrsystem, till en skygg bransch, som önskar hårdvara samt mjukvara ändras, godkännas, certifieras till dagen därpå... Fungerar icke i den underbara embedded-världen.

Skrivet av Yoshman:

Koden som länkas är hyfsat enkel, men den innehåller några grodor. Det som kan potentiellt ställa till det är att man använder symboler vars namn börjar på '_'. Symboler som börjar med ett eller två '_' är reserverade för kompilator-, standardbibliotek- och system-konstruktörerna.

Inte riktigt, namn som börjar med '_' är reserverade i det globala namespacet. I andra namnspaces så är däremot endast namn som börjar med två '_' eller '_' följt av en stor bokstav reserverade. Att använda '_' som prefix för klassmedlemmar är alltså ok så länge som '_' följs en av liten bokstav.

Skrivet av heretic16:

Idag satte jag mig in i ett C++ bibliotek för Arduino. Jag skulle leda efter vad för funktion retinerar som datatyp.

Hittade den inte i dokumentationen. När jag skulle dyka ned i koden så kände jag att hela C++ koden var ett enda trassel, men hag kände även att skaparen hade stor kunskap om C++ då mystiska funktioner och variabler och datatyper användes. Termer som jag aldtig har läst om förut.

Varför blir det så här? När jag skriver C++ kod så håller jag mig enkel och följer Jan Skansholm C++ Direkt, inte Bjarne Storstrup C++. Jag försöker skriva så pedagogisk och luftig kod dom det bara går. Snygg struktur och symetrisk struktur för alla klasser. Jag blandar inte in _ eller ___ i funktions eller variabelnamn. Istället använder jag this. Jag deklarerar alltid klassnamnet med stor bokstav och objektnamnet med liten boxstav.

Jag undviker till varje pris att lämna övet avancerad kod och jag håller mig alltid enkel. Jag planerar min struktur först som ett verkligt exempel. Är jag behov av arv eller inte, tänker jag. Klarar jag mig med endast grund grund grund OOP, tänker jag. Måste jag ha en headerfil för varje .cpp fil, tänker jag?

Jag kommenterar mycket och förklarar vart man ska börja. Men då är frågan: Är det jag som är dålig eller är det andra som skriver för dåligt?

Det kan finnas många anledningar. Biblioteket kanske började som ett personligt projekt han inte hade tänkt dela men gjorde ändå. Han hade kanske lite erfarenhet, ont om tid, tight budget etc.

Skrivet av perost:

Inte riktigt, namn som börjar med '_' är reserverade i det globala namespacet. I andra namnspaces så är däremot endast namn som börjar med två '_' eller '_' följt av en stor bokstav reserverade. Att använda '_' som prefix för klassmedlemmar är alltså ok så länge som '_' följs en av liten bokstav.

Känns det som en rimligt regel att berätta för folk? Gäller även "tag namespace", d.v.s. namnet på sammansatta typer (både för C och C++).

Den i praktiken användbara minnesregeln är: använd inte '_' i början av namn på något. (Är inte helt lätt att komma ihåg i sina egna applikationer när man jobbat ett tag med att skriva standardbibliotek och jobbat med kompilatorer...)

Modellen med ett '_' följt av en stor bokstav alt. ett till '_' går under öknamnet "ugly mode". Försöker man läsa de delar av C++ standardbibliotek, som normalt använder sig av denna modell, förstår man väldigt snabbt varför

Bra kod är lättläst. Förutsatt att man har kunskap för att förstå vad den gör då.
Kod som inte följer best-practise och konventioner för aktuellt språk är inte bra kod, oavsett om den fungerar felfritt eller ej.

Kanske lite off-topic, men jag kan rekommendera er att köra med SonarLint eller liknande verktyg som hjälper till med kodkvalitet om er utvecklingsmiljö och språk har stöd för det. Med en mer organiserad byggprocess kan även analysverktyg som SonarQube vara riktigt bra att ha till hands. SonarQube har en gratis Community-edition man kan ladda hem och SonarLint är gratis.

Med assistans från verktyg av denna sort kanske man inte får det lättare att läsa andras kod, men man kan i många fall undvika att bidra med dålig kod och får hjälp att städa upp i befintlig kod.

Länkar:

Som en del redan har sagt: Det finns ingen metod som kallas buffer i koden.

Lätt att konstatera med:

grep -r "buffer\s*(" *

Så det är nog du som är dålig på läsa kod.