Skrivet av orp:
Jag tror ingen har så starka känslor kring hungarian notion men att säga saker som att "unit test är värdelöst" eller att "pythonutvecklare inte är riktiga programmerare" osv då förtjänar man att åka ut med huvudet före..
Men python är inte "riktig" imperativ utveckling, det är deklarativ utveckling även om de får ta till imperativa kodavsnitt. Och unit test har stora konsekvenser på koden, för en som lärt sig utveckla (imperativ kod) så medför bara unit test en massa problem. Det kostar mycket mer än vad det smakar och det är inte ens konstigt. Det enda är att tröskeln till att förstå varför är högre än om utvecklare gått en veckas kurs i html.
Om jag läser instruktioner hur man använder hammare och spik, kanske lär mig en del verktyg till. Köper virke och bygger ett hus. Det råkar se ut som en hydda men det är i all fall tak över huvudet. Kan jag då kalla mig snickare?
Gör ett försök att förklara
Tidigare i tråden postade jag en del kod för en metod som heter FILE_UpdatePatternList och nämnde senare att det är skitkod. Orsaken till att jag kallar det för skitkod beror på att det ÄR skitkod.
Skitkod är svårt att undvika helt och hållet men desto mer man lär sig desto mindre skitkod blir det.
Så varför är det skitkod?
Koden hanterar användardomänen (användardomän är ett områden utvecklare måste läsa på för att klara av att jobba i koden). All kod som hanterar användardomän är skitkod.
Metoden FILE_UpdatePatternList gör flera saker, en metod skall inte göra flera saker, den skall göra EN sak.
Metoden har massor av variabler trots att ansträngningarna att minimera antalet så är det ändå många
Metoden är tekniskt svår och mycket svår att debugga.
En riktig utvecklare förstår hur viktigt det är att minimera skitkod, gör man inte det går det inte att utveckla applikationer för att istället för att skapa funktionalitet kommer förstöra. Att en del ändå lyckas beror på att man följer ramverk. Programmeraren skriver inte egen funktionalitet utan använder komponenter och då kan man komma längre men inte hur långt som helst. Hjärnan klarar inte minnas hur mycket som helst.
Mängden kod för de som kan programmera spelar ingen roll, om det är 10 000 rader kod eller 20 miljoner, det är skit samma kodmässigt. Kan man inte programmera spelar mängden stor roll eftersom kod ofta skrivs efter någons huvud. Vad som finns i en programmerares huvud finns inte automatiskt i andra programmerares huvud. Enklare domäner så fungerar det ändå eftersom variabelnamn och andra namn kan tillhöra allmänbildning. Svårare domäner och koden är omöjlig att förstå. Endast den som skrivit koden förstår vad den gör.
Separera systemdomän från användardomän är viktigt. (använder de namn som Casey Maratori beskrev så bra). Det finns en bok som heter "clean code" skriven av Robert C Martin. Sämsta bok som skrivits och förstört massor eftersom den beskriver att bra kod är att skriva kod för användardomän. Att kod är som att läsa en bok.
Att den blev så populär tror jag beror på att många kunde äntligen göra något programmeringsmässigt. Så de trodde "nu är jag programmerare". Försöker då en "riktig" programmerare förklara att man inte gör som de lärt sig så förstår de inte alls.
32 variabler in metoden FILE_UpdatePatternList
Metoden FILE_UpdatePatternList har alltså 32 stycken variabler, vansinne men det fungerar med hungarian notation. Det här är en av de hungarian notation största styrkor, det är så mycket enklare att förstå skitkod. Om programmeraren inte har något system för benämning av variabler kommer programmeraren aldrig att klara av att skriva den typen av kod (även om det är skitkod) och det kommer definitivt inte vara möjligt att läsa koden. Utan tekniker för hur kod hanteras kommer utvecklaren förmodligen inte klara att skriva speciellt avancerad kod alls. Det har alltså inget med skicklighet att göra utan det är en teknik.
Style guide och annat hur kod skrivs anpassas helt efter att klara av att hantera skitkod.
Here are the variables extracted from this method:
## Function Parameters:
- `vectorPattern` (const std::vector<std::string>&) - List of search patterns
- `argumentsList` (const gd::argument::shared::arguments&) - Command line arguments
- `iThreadCount` (int) - Number of threads to use
## Local Variables:
- `patternsFind` (gd::parse::patterns) - Sorted pattern collection
- `ptableFile` (auto*) - Pointer to file cache table
- `ptableLineList` (auto*) - Pointer to line list cache table
- `stringSegment` (std::string_view) - Code segment to search in (code, comment, string)
- `uMax` (uint64_t) - Maximum number of lines to process
- `uFileCount` (auto) - Total number of files to process
## Thread Synchronization Variables:
- `uAtomicFileIndex` (std::atomic<uint64_t>) - Current file being processed
- `uAtomicProcessedCount` (std::atomic<uint64_t>) - Count of processed files
- `uAtomicTotalLines` (std::atomic<uint64_t>) - Total lines found across threads
- `mutexProgress` (std::mutex) - Protects progress updates
- `mutexLineList` (std::mutex) - Protects ptableLineList access
- `vectorError` (std::vector<std::string>) - Collects errors from threads
- `mutexErrors` (std::mutex) - Protects access to vectorError
- `pcolumnsThread` (detail::columns*) - Column structure for line list table
## Lambda Function Variables (process_):
- `iThreadId` (int) - Thread identifier
- `ptableLineListLocal` (std::unique_ptr<table>) - Thread-local results table
- `uRowIndex` (uint64_t) - Current file row index
- `stringFolder` (auto) - File folder path
- `stringFilename` (auto) - File name
- `pathFile` (gd::file::path) - Full file path object
- `stringFile` (std::string) - Full file path string
- `uKey` (auto) - File key identifier
- `arguments_` (gd::argument::shared::arguments) - Arguments for pattern matching command
- `result_` (auto) - Result from pattern matching operation
- `uProcessed` (uint64_t) - Local processed file count
- `uPercent` (uint64_t) - Progress percentage
- `exception_` (const std::exception&) - Exception object
## Thread Management Variables:
- `vectorPatternThread` (std::vector<std::thread>) - Collection of worker threads
- `threadWorker` (auto&) - Reference to worker thread in loop
Dold text
Hur jag vet att exempelvis rust eller andra "förlåtande" språk inte kommer användas till större svårare projekt
Vet man om ovanstående så är det ganska lätt och se hur långt ett projekt kommer. Det beror en del på vilken typ av domän koden hanterar. Är det domäner kända för utvecklare kommer de längre, är det ovanliga så kommer de inte speciellt långt.
Att utveckla en editor, spelmotor eller annat kan komma ganska långt även om det är tekniskt men det beror på att användardomänen också är känd för utvecklare.
Är det annat som vetenskapliga domäner eller liknande, då bli det genast mer problem.
Eftersom jag granskat en del rust projekt så, i princip samtliga rust projekt jag kollat uppträder för mycket "skitkod" och det är enligt mig orsaken till att de inte kommer så långt. Ett allvarligt designfel de har i rust är att språket saknar överlagring och det gör att att de har mycket svårare att skriva kod i mönster. Nästan alla "kända" rust projekt har en eldsjäl och de kan nå närmare 100 000 rader och då är det vad jag sett nästan alltid domäner välkända för utvecklare. Har inte sett rustprojekt med något mer udda domän som är större men tar gärna emot tips på sådant. Att det saknas projekt i domäner okända för utvecklare tror inte jag är en slump.