C++ och dess framtid att programmera minnessäkert - Hur går utvecklingen?

Permalänk
Medlem
Skrivet av Dimman:

Jag tror vi behöver vända på steken här; hur gör du för att verifiera att olika scenarion fungerar med dina lösningar?

Om du ger en bra förklaring hur du kan testa den här koden utan att behöva skriva testkod i två veckor så skall jag berätta

#20955298

enhetstester har troligen blivit poppis för det är lätt att förstå för chefer som inte kan programmera

använder tester men inte för att testa kod, de är bra för annat. exempelvis att låsa kod

Permalänk
Medlem
Skrivet av Dimman:

Jag tror vi behöver vända på steken här; hur gör du för att verifiera att olika scenarion fungerar med dina lösningar?

Vi har ställt den frågan och då gick dialogen ungefär så här:
- klk testar genom asserts -> lång diskussion om asserts.
- någon frågade om unit testning -> klk redogör en hel lista med missförstånd om unit testning.
- klk kör HN istället för testning -> lång diskussion om HN och varför HN inte ersätter testning.
- klk slänger ur sig att han återanvänder kod och kör applikationen istället för testning.
- någon frågade om vad klk menar med återanvändbar kod -> klk svara överlagring och lång diskussion om överlagring och klk svara tänk på en telefonbok istället för att svar "ja, det är function overloading jag syftar på".

@klk kör HN, asserts, återanvändbarkod ihop med att testköra det på sin dator, sedan sätter han sin stämpel på det och säger "trust me, bro".

Han har nämn regressionstestning men aldrig redogjort för hur han implementerar eller när han kör sina regressionstester.

Kort och gått så går @klk i cirklar och trollar...

Permalänk
Medlem
Skrivet av orp:

Vi har ställt den frågan och då gick dialogen ungefär så här:
- klk testar genom asserts -> lång diskussion om asserts.
- någon frågade om unit testning -> klk redogör en hel lista med missförstånd om unit testning.
- klk kör HN istället för testning -> lång diskussion om HN och varför HN inte ersätter testning.
- klk slänger ur sig att han återanvänder kod och kör applikationen istället för testning.
- någon frågade om vad klk menar med återanvändbar kod -> klk svara överlagring och lång diskussion om överlagring och klk svara tänk på en telefonbok istället för att svar "ja, det är function overloading jag syftar på".

@klk kör HN, asserts, återanvändbarkod ihop med att testköra det på sin dator, sedan sätter han sin stämpel på det och säger "trust me, bro".

Han har nämn regressionstestning men aldrig redogjort för hur han implementerar eller när han kör sina regressionstester.

Kort och gått så går @klk i cirklar och trollar...

tack för hjälpen

Permalänk
Medlem
Skrivet av klk:

Om du ger en bra förklaring hur du kan testa den här koden utan att behöva skriva testkod i två veckor så skall jag berätta

#20955298
...

Du beskriver att metoden gör följande:

* This method processes a list of regex patterns and applies them to the files stored in the cache. * It generates a list of lines in each file where the patterns are found and stores the results * in the "file-linelist" cache table.

Det låter väl som ett utmärkt tillfälle att plocka fram ett blandat set av input-data tillsammans med förväntad output-data, och sedan köra din metod på alltihop. Diffa output med expected output. Släng in några scenarior där input-data är felformaterad, eller annat som är fel och kolla så att din metod hanterar det som förväntat? Om du inte 100% happy-hackar så testar du ju precis på detta sättet manuellt redan.

Skrivet av klk:

...
enhetstester har troligen blivit poppis för det är lätt att förstå för chefer som inte kan programmera

använder tester men inte för att testa kod, de är bra för annat. exempelvis att låsa kod

Så du använder tester men inte för att testa kod, men för att låsa kod; den där får du nog utveckla för det makes no sense.

Skrivet av klk:

tack för hjälpen

Om du instämmer i beskrivningen av situationen som @orp la fram så finns det nog inte mycket mer att diskutera, i något ämne

Visa signatur

Citera mig för svar.
Arch Linux

Permalänk
Medlem
Skrivet av Dimman:

Du beskriver att metoden gör följande:

* This method processes a list of regex patterns and applies them to the files stored in the cache. * It generates a list of lines in each file where the patterns are found and stores the results * in the "file-linelist" cache table.

Det låter väl som ett utmärkt tillfälle att plocka fram ett blandat set av input-data tillsammans med förväntad output-data, och sedan köra din metod på alltihop. Diffa output med expected output. Släng in några scenarior där input-data är felformaterad, eller annat som är fel och kolla så att din metod hanterar det som förväntat? Om du inte 100% happy-hackar så testar du ju precis på detta sättet manuellt redan.

Om jag skall skriva test för det så är jag uppe i två veckor eller i alla fall väldigt mycket extra tid, metoden tog en kväll och skriva och testa i debug. Föredrar att bli klar någon gång

Min teknik för att testa domänkod är vanligen att skripta upp applikationen, kan lägga in LUA kod men i aktuell kod jag visade har jag funderingar på att använda python, mest för att lära och testa nu när python har möjlighet att köra utan GIL'en.

Skripta applikationen gör det enklare att skriva test, kan till och med vara helt andra eller om man vill introducera nya utvecklare i något så kan sådant passa bra.

Skrivet av Dimman:

Så du använder tester men inte för att testa kod, men för att låsa kod; den där får du nog utveckla för det makes no sense.

För med enhetstest skapar du teknisk skuld och coupling, det låser kod.

Permalänk
Medlem
Skrivet av klk:

Om jag skall skriva test för det så är jag uppe i två veckar eller i alla fall väldigt mycket extra tid, metoden tog en kväll och skriva och testa i debug. Föredrar att bli klar någon gång

Min teknik för att testa domänkod är vanligen att skripta upp applikationen, kan lägga in LUA kod men i aktuell kod jag visade har jag funderingar på att använda python, mest för att lära och testa nu när python har möjlighet att köra utan GIL'en.

Skripta applikationen gör det enklare att skriva test, kan till och med vara helt andra eller om man vill introducera nya utvecklare i något så kan sådant passa bra.

För med enhetstest skapar du teknisk skuld och coupling, det låser kod.

Jag vet inte varför du maniskt fastnat vid unit-testning och att allt skulle handla om det, men jag har förstått att du alltså testar lite manuellt när du skriver koden och sen är det färdigt där. Det funkar för dig, du är nöjd och du tycker alla borde jobba på det viset. Du anser att allt annat är slöseri med tid. Alla som tänker annorlunda är inte på samma intellektuella nivå som dig och besitter inte din kunskap; man har helt enkelt inte förstått saker på den nivån du förstår. Är det en ungefärligt korrekt sammanfattning?

Visa signatur

Citera mig för svar.
Arch Linux

Permalänk
Medlem
Skrivet av Dimman:

Jag vet inte varför du maniskt fastnat vid unit-testning och att allt skulle handla om det, men jag har förstått att du alltså testar lite manuellt när du skriver koden och sen är det färdigt där. Det funkar för dig, du är nöjd och du tycker alla borde jobba på det viset. Du anser att allt annat är slöseri med tid. Alla som tänker annorlunda är inte på samma intellektuella nivå som dig och besitter inte din kunskap; man har helt enkelt inte förstått saker på den nivån du förstår. Är det en ungefärligt korrekt sammanfattning?

Nej, och enhetstestning använder jag inte för att det är för dåligt. Det existerar inte utvecklare som kan skriva test så att koden är säker och priset för enhetstester är för högt, på tok för högt.

Enhetstester är alltså en dålig metod, spelar ingen roll vad du säger (eller någon annan). Skulle man anse det vara en bra metod beror det oftast på att man inte vet något annat.
Enhetstester är bra för annat men alltså inte för att testa koden.

Beskrev precis en annan metod (skripta) för givetvis testar jag koden.

Permalänk
Medlem
Skrivet av klk:

Om jag skall skriva test för det så är jag uppe i två veckor eller i alla fall väldigt mycket extra tid, metoden tog en kväll och skriva och testa i debug.

Då är du riktigt kass på att koda om det skulle ta 2 veckor. Det är som att säga "det kommer ta mig 2 veckor att skriva en funktion".

Skrivet av klk:

Nej, och enhetstestning använder jag inte för att det är för dåligt.

Låter som att du är för dålig

Skrivet av klk:

Det existerar inte utvecklare som kan skriva test så att koden är säker ...

Det finns. Du fattar verkligen inte att allt >0% är någon form av vinst. Som @Dimman var inne på, kör du bil utan bälte också?
Har du vaccinerat dig själv eller din son?
Tillagar du kyckling till >=72 grader?
Har du försäkrat din bostad?

Skrivet av klk:

... och priset för enhetstester är för högt, på tok för högt.

Du sa precis att det skulle ta dig 2 veckor att skriva test för ditt kodexempel. Om man jobbar på ett riktigt företag så är det inte många fel hos kunden innan man har orsakat skador till ett högre värde. Om man jobbar på ett startup så kanske kunden har överseende med bristande kvalitet

Permalänk
Datavetare
Skrivet av klk:

Tror du att test plockar 100% av alla möjliga fel?

Det är fullt möjligt att skriva test som plockar 100 % av fallen. En hel klass av sådana är alla tester som verifiera alla tänkbara permutationer av funktioner där funktionerna saknar sidoeffekter.

I praktiken är de mer spännande funktionerna inte realistiskt testbara på den nivån. Vissa fuzzers kan dock analysera traces genom koden och lura ut vilka inputs som kommer leda till att man växlar mellan true-branch och false-branch i en funktion. Det kan då ge en uppsättning inputs som ger full eller i alla fall väldigt hög BC/DC (branch coverage / decision coverage).

Att göra sådant "för hand" kommer rätt snabbt bli så komplicerat att det tar till Ragnarök.

Skrivet av klk:

Har diskuterat test tidigare i tråden och kanske låter bli och repetera. Tipsar istället om den här videon https://www.youtube.com/watch?v=wo84LFzx5nI
Och att du läser om det Casey kallar för "discriminated unions" eller "Tagged unions".

Om du nu älskar unioner/variants så mycket, är verkligen C++ (ett rätt starkt typat och statiskt typat språk) rätt val?
Den säkerhet man får med "tagged unions" ger ju noll om man istället skriver sin kod så man redan har rätt statisk typ vid kompilering. Det går inte alltid, men i domäner jag jobbat med har det ändå varit normalfallet att man kan välja en statisk typ som är högst lämplig för uppgiften.

En statiskt typ lär vara minst lika snabb, även om det absolut går att göra "tagged unions" väldigt snabba.

Skrivet av klk:

För med enhetstest skapar du teknisk skuld och coupling, det låser kod.

Tar ett konkret fall som jag jobbat med idag.

Hade något som redan fungerade och där det fanns ett gäng tester. Koden "fungerade" men hade en del brister. Externa APIet (som inte är kundexternt på något sätt) var i stort sätt ok, men kunde göras lite bättre.

Totalt sett var det rätt stora interna förändringar, av de tester som fanns behövde en par stycken småjusteringar p.g.a. förändring av API.

Stora fördelen med unit-tester: efter detta gick alla tester åter igenom.

Hur skulle man få motsvarande kvitto på att nya koden inte hade sönder fall som tidigare fungerade utan testerna?

Går väl att köra manuellt, men givet vad som testades här skulle en manuell körning av allt vara något som tar en mänsklig testare dagar att genomföra (unit-testerna testar samma sak head-less med simulerad wall-clock time så man kan köra så fort CPUn orkar med)?

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Det är fullt möjligt att skriva test som plockar 100 % av fallen. En hel klass av sådana är alla tester som verifiera alla tänkbara permutationer av funktioner där funktionerna saknar sidoeffekter.

Jag pratar inte om "hello world!"-applikationer eller enkelfunktionalitet. Det du beskriver måste vara mycket simpelt, annars är det inte möjligt att täcka 100%, och det vet du. Om en programmerare vore så skicklig (sådan existerar inte) att den klarar av att skriva tester som täcker allt, då skulle den programmeraren inte behöva skriva tester eftersom personen är så pass duktig att programmeraren skriver felfri kod direkt.

Skrivet av Yoshman:

Att göra sådant "för hand" kommer rätt snabbt bli så komplicerat att det tar till Ragnarök.

Enhetstester kommer i nära nog 100% av fallen kosta mycket mer än vad det ger.

Enhetstester har sin plats men då för andra orsaker (som jag nämnt, att låsa koden är ett exempel, man vill inte att den förstörs). Det kan vara att koden är så komplicerad att den inte går att förstå (kan vara trassel, domänen är är svår eller något annat). För att andra skall våga jobba med det kan de ha test så de får en säkerhet att det fortfarande fungerar som tänkt.

Skrivet av Yoshman:

Om du nu älskar unioner/variants så mycket, är verkligen C++ (ett rätt starkt typat och statiskt typat språk) rätt val?

Såg du mitt exempel tidigare om en tabell som skrevs ut, det var ingen slump att jag la upp den koden men det verkar inte som någon nappar. Nu med LLMer är det himla smidigt och testa hur funktionalitet skrivs med andra språk, inte alls svårt.
Har inte sett att andra språk gör det enklare. Framförallt ser det "konstigt" ut. För något som C++ verkligen lyckats med är att det går att få ett mer naturligt utseende, det behövs inte lika mycket omskrivningar/anpassningar för att få till funktionaliteten. Och här sticker verkligen RUST ut, språkets tvingar utvecklaren skriva kod annorlunda.
OOP språk (C#, Java) lider också kraftigt av det problemet, att allt skall ligga i objekt är ett allvarligt designfel. Exempelvis svårt att avgöra vad som är bra skrivna objekt och vad som är hack eftersom allt MÅSTE ligga i objekt.

Skrivet av Yoshman:

Den säkerhet man får med "tagged unions" ger ju noll om man istället skriver sin kod så man redan har rätt statisk typ vid kompilering.

Det där är bara okunskap, och det är självklart eftersom den typen av kod är så ovanlig. De som lärt sig, där tror jag många likt mig undrar varför inte fler använder sig av tekniken med tanke på hur mycket det effektiviserar.
Tror det beror på att svårigheterna att diskutera teknik idag, går i princip inte om det blir svårare i allmänna/större grupper.

Skrivet av Yoshman:

Det går inte alltid, men i domäner jag jobbat med har det ändå varit normalfallet att man kan välja en statisk typ som är högst lämplig för uppgiften.

En statiskt typ lär vara minst lika snabb, även om det absolut går att göra "tagged unions" väldigt snabba.

Två helt olika saker, statisk typning är att kompilatorn vet vad det är. Har inget med vad tagged unions försöker lösa. Templates som exempelvis kan upplevas som något som liknar, är bara att kompilatorn klarar generera kod. Är det fel på data i runtime har du inte en kompilator som kan kontrollera.
Tagged unions, då vet koden vad det är (maskinkoden)

Permalänk
Medlem
Skrivet av Yoshman:

Tar ett konkret fall som jag jobbat med idag.

Hade något som redan fungerade och där det fanns ett gäng tester. Koden "fungerade" men hade en del brister. Externa APIet (som inte är kundexternt på något sätt) var i stort sätt ok, men kunde göras lite bättre.

Totalt sett var det rätt stora interna förändringar, av de tester som fanns behövde en par stycken småjusteringar p.g.a. förändring av API.

Stora fördelen med unit-tester: efter detta gick alla tester åter igenom.

Hur skulle man få motsvarande kvitto på att nya koden inte hade sönder fall som tidigare fungerade utan testerna?

Går väl att köra manuellt, men givet vad som testades här skulle en manuell körning av allt vara något som tar en mänsklig testare dagar att genomföra (unit-testerna testar samma sak head-less med simulerad wall-clock time så man kan köra så fort CPUn orkar med)?

Menar alltså inte att man inte skall ha något alls för att verifiera att allt fungerar som det skall.
Kod måste skrivas så den går att verifiera och då är det (alltid) data som verifieras, alltså resultat.

Med tagged unions det normalt enklare, går alltid och granska dataströmmar om man tänkt till och verifiera att de är ok.
Annars så hade nog jag försökt bygga några olika skriptlösningar som körde kod och matcha dem med tidigare resultat.

Repeterar igen:
Problemet med extra kod är att det låser koden. Du nämner själv att det: "behövde en par stycken småjusteringar p.g.a. förändring av API". Det låter på dig som att det där är ett någon enkelt, det är det inte när koden är svårare. Och ibland behövs större refaktoreringar, de kan bli en mardröm eftersom mycket mer kod behöver skrivas om.

Gissar att de flesta utvecklare låtit bli att skriva om kod just på grund av att tester gjort det mer eller mindre omöjligt.

Permalänk
Skrivet av klk:

Gissar att de flesta utvecklare låtit bli att skriva om kod just på grund av att tester gjort det mer eller mindre omöjligt.

Det här har du fått helt om bakfoten.

Just det faktum att du har tester med god täckning gör att du vågar skriva om kod. Passerar det testerna efter din omskrivning så har du inte oavsiktligt förstört något för din användare. Testerna ger dig ett stöd som gör att du inte låter bli att ändra saker för att du är rädd att råka paja något. Med legacy-koden finns det alltid en rädsla, tänk om jag förstör något jag inte tänkt på, men är koden under test kan man göra ändringar utan att tveka. Om du skulle förstöra något hittar du felen med en gång, inte ute hos kund.

Permalänk
Medlem
Skrivet av Ingetledigtnamn:

Just det faktum att du har tester med god täckning gör att du vågar skriva om kod. Passerar det testerna efter din omskrivning så har du inte oavsiktligt förstört något för din användare. Testerna ger dig ett stöd som gör att du inte låter bli att ändra saker för att du är rädd att råka paja något. Med legacy-koden finns det alltid en rädsla, tänk om jag förstör något jag inte tänkt på, men är koden under test kan man göra ändringar utan att tveka. Om du skulle förstöra något hittar du felen med en gång, inte ute hos kund.

En större refaktorering kräver ibland helt omskrivna tester, hur gör du det smidigt

Ett exempel som visserligen är extremt:
Vart bekant med en ganska speciell lösning för flera år sedan. Det var runt 300 000 rader xslt (ja du läste rätt)
xslt använd för att transformera xml från ett format till ett annat.

Fanns flera orsaker till att det valts, framförallt för att klara av annan nödvändig teknik.

För att allt det här skulle fungera fanns det en del tester och ingen vågade röra något, programmerare som gjort lösningen hade slutat och så vidare.
Testerna var alltså byggda kring tekniken (inte runt xml och xslt). Tekniken behövde matas med en speciell form av xml

Enda sättet att få till mer funktionalitet var att lägga till och gräva gropen djupare.

Bättre lösning:
Vad de borde ha testat var resultat och inte byggt in sig i tekniken. Spelar ingen roll hur resultatet skapades bara det blev rätt output.

Enda alternativ lösning möjlig för det här:
Total omskrivning (släng koden, vilket senare gjordes)

Permalänk
Medlem

Jag hävdar fortfarande att alla som svarar på eller kommenterar klk:s inlägg göder trollet. Allt går i cirklar med noll röd tråd och bara nya vinklingar för att kunna omfrasera och säga ungefär samma saker igen.
Lägg ner debatten, ingen utom klk blir nöjd av att fortsätta mala. Ingen kommer att komma fram till något som gör skillnad. Kolla andra liknande debatter i olika ämnen från 2010 och framåt.

Visa signatur

Debian, bara Debian, Debian överallt

Permalänk
Datavetare
Skrivet av klk:

Såg du mitt exempel tidigare om en tabell som skrevs ut, det var ingen slump att jag la upp den koden men det verkar inte som någon nappar. Nu med LLMer är det himla smidigt och testa hur funktionalitet skrivs med andra språk, inte alls svårt.
Har inte sett att andra språk gör det enklare. Framförallt ser det "konstigt" ut. För något som C++ verkligen lyckats med är att det går att få ett mer naturligt utseende, det behövs inte lika mycket omskrivningar/anpassningar för att få till funktionaliteten. Och här sticker verkligen RUST ut, språkets tvingar utvecklaren skriva kod annorlunda.
OOP språk (C#, Java) lider också kraftigt av det problemet, att allt skall ligga i objekt är ett allvarligt designfel. Exempelvis svårt att avgöra vad som är bra skrivna objekt och vad som är hack eftersom allt MÅSTE ligga i objekt.

Ett problem med LLMs är att skit in blir tyvärr skit ut. Det verkar som du har rätt liten kunskap om t.ex. Rust. Blir då väldigt stor risk att det du får från en LLM är rätt exakt vad du frågade efter, men p.g.a. bristande kunskap om Rust ställer du fel fråga!

Vi håller oss till ett av dina favoritämnen, tagged unions. Du är medveten om att Rust har inbyggt stöd för detta i språket, till skillnad från t.ex. C++ som har det via bibliotek (kör du boost:.variant eller std::variant?).

Om vi tar ett superenkelt fall och sedan jämför det med något som gör motsvarande på ett idiomatiskt sätt i Rust och C#. Definiera en "tagged union" som i alla fall kan hålla int, double och sträng. Vi gör sedan en funktion som adderar två sådana.

C++

#include <optional> #include <string> #include <variant> using MyVariant = std::variant<int, double, std::string>; int variant_sum_may_throw(MyVariant a, MyVariant b) { return std::get<int>(a) + std::get<int>(b); } std::optional<int> variant_sum(const MyVariant& a, const MyVariant& b) { if (std::holds_alternative<int>(a) && std::holds_alternative<int>(b)) { return std::get<int>(a) + std::get<int>(b); } return std::nullopt; } int sum(int a, int b) { return a + b; }

Rust

pub enum MyVariant { Int(i32), Double(f64), Text(String), } pub fn variant_sum_may_panic(a: MyVariant, b: MyVariant) -> i32 { match (a, b) { (MyVariant::Int(x), MyVariant::Int(y)) => x + y, _ => panic!("Both arguments must be Int"), } } pub fn variant_sum(a: &MyVariant, b: &MyVariant) -> Option<i32> { if let (MyVariant::Int(x), MyVariant::Int(y)) = (a, b) { Some(x + y) } else { None } } pub fn sum(a: i32, b: i32) -> i32 { a + b }

C# har också inbyggt stöd för "tagged unions" i form av nyckelordet "dynamic" som är som en variant man kan stoppa in alla typer i. Den "vinner" om man räknar "hur lite extra lär man skriva för att använda detta"?

int add(dynamic a, dynamic b) { return a + b; }

Skrivet av klk:

Det där är bara okunskap, och det är självklart eftersom den typen av kod är så ovanlig. De som lärt sig, där tror jag många likt mig undrar varför inte fler använder sig av tekniken med tanke på hur mycket det effektiviserar.
Tror det beror på att svårigheterna att diskutera teknik idag, går i princip inte om det blir svårare i allmänna/större grupper.

Två helt olika saker, statisk typning är att kompilatorn vet vad det är. Har inget med vad tagged unions försöker lösa. Templates som exempelvis kan upplevas som något som liknar, är bara att kompilatorn klarar generera kod. Är det fel på data i runtime har du inte en kompilator som kan kontrollera.
Tagged unions, då vet koden vad det är (maskinkoden)

Har bara använt std::variant<> någon enstaka gång. Har använt enums med associerade värden i Rust oftare, men fortfarande inget som är vanligt förkommande.

För att precisera frågan lite då. Ibland jagar du saker som (du i alla fall hoppas) skalar bort enskilda assemblerinstruktioner. Är inte det en stark orsak att försöka undvika tagged unions om man kan, för kompilatorn kan göra rätt mycket enklare kod när den vet vad typen är compile-time.

Om vi tar fallen

// C++ int sum(int a, int b) { return a + b; } // Rust pub fn sum(a: i32, b: i32) -> i32 { a + b }

så blir det

add w0, w0, w1 ret

Tar vi fallen

// C++ std::optional<int> variant_sum(const MyVariant& a, const MyVariant& b) { if (std::holds_alternative<int>(a) && std::holds_alternative<int>(b)) { return std::get<int>(a) + std::get<int>(b); } return std::nullopt; } // Rust pub fn variant_sum(a: &MyVariant, b: &MyVariant) -> Option<i32> { if let (MyVariant::Int(x), MyVariant::Int(y)) = (a, b) { Some(x + y) } else { None } }

så har det overhead för att kolla taggen värde

// C++ variant_sum(std::variant<int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::variant<int, double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&): ldrb w2, [x0, 32] sub sp, sp, #16 cbnz w2, .L14 ldrb w2, [x1, 32] cbz w2, .L17 .L14: str xzr, [sp, 8] ldr x0, [sp, 8] add sp, sp, 16 ret .L17: ldr w0, [x0] mov w2, 1 ldr w1, [x1] strb w2, [sp, 12] add w0, w0, w1 str w0, [sp, 8] ldr x0, [sp, 8] add sp, sp, 16 ret // Rust variant_sum: ldr x9, [x0] mov x8, #-9223372036854775808 ldr x10, [x1] cmp x9, x8 ldr w9, [x1, #8] ccmp x10, x8, #0, eq ldr w8, [x0, #8] cset w0, eq add w1, w9, w8 ret

Dold text

Helt OK overhead att ta om den behövs, men är det vettigt att köra som nära nog standardval som du verkar göra?

Sen har du och Casey Muratori en sak gemensamt, ni båda beskriver fördelar med DOD från en svunnen tid. Det FINNS fördelar än idag, men de Casey specifikt pratar om i videon du länkar var högst relevanta på de tidiga konsolerna som typiskt hade rätt kraftig HW i förhållande till mängden RAM.

Saker som tagged union var då högst värdefulla för att ha en bra metod att utnyttja det RAM (ibland kunde det vara riktigt lite minne som i PS2 om man ville utnyttja scratchpad på 16 kB) på ett optimalt sätt. Just det är inte längre en flaskhals ens för konsoler och definitivt inte för typiska server-plattformar.

Däremot finns det andra saker med DOD som är värdefullt idag, t.ex. att det kan göra det långt enklare att hantera en minneslayout som lämpar sig väl att processa med SIMD. Fast det använder du ju inte, autovektorisering är tyvärr långt ifrån tillräckligt för att få utväxling på SIMD. I bästa fall finns bra bibliotek, men idag får man tyvärr nog acceptera att skriva intrinsics eller köra t.ex. ISPC (vilket bl.a. Unreal Engine använder).

Så är rätt oklart vilken vinst du uppnår med DOD. Måste fortfarande helt missat något, för fattar inte alls vad storheten är i den kod du visat så här långt. Framförallt inte hur den använder DOD på något vettig sätt.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Datavetare
Skrivet av serafim:

Jag hävdar fortfarande att alla som svarar på eller kommenterar klk:s inlägg göder trollet. Allt går i cirklar med noll röd tråd och bara nya vinklingar för att kunna omfrasera och säga ungefär samma saker igen.
Lägg ner debatten, ingen utom klk blir nöjd av att fortsätta mala. Ingen kommer att komma fram till något som gör skillnad. Kolla andra liknande debatter i olika ämnen från 2010 och framåt.

Jag tror (och hoppas) ingen längre tror att klk lyssnar. Men svaren som kommer från andra har väldigt ofta spännande information och insikter!

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Datavetare
Skrivet av klk:

Menar alltså inte att man inte skall ha något alls för att verifiera att allt fungerar som det skall.
Kod måste skrivas så den går att verifiera och då är det (alltid) data som verifieras, alltså resultat.

Med tagged unions det normalt enklare, går alltid och granska dataströmmar om man tänkt till och verifiera att de är ok.
Annars så hade nog jag försökt bygga några olika skriptlösningar som körde kod och matcha dem med tidigare resultat.

Repeterar igen:
Problemet med extra kod är att det låser koden. Du nämner själv att det: "behövde en par stycken småjusteringar p.g.a. förändring av API". Det låter på dig som att det där är ett någon enkelt, det är det inte när koden är svårare. Och ibland behövs större refaktoreringar, de kan bli en mardröm eftersom mycket mer kod behöver skrivas om.

Gissar att de flesta utvecklare låtit bli att skriva om kod just på grund av att tester gjort det mer eller mindre omöjligt.

Fast om de småjusteringar tar en liten fraktion av tiden det tar att manuellt testa om, är det inte då en gigantisk vinst med unit-tester?

För egen del är ovan det typiska normalfallet.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Vi håller oss till ett av dina favoritämnen, tagged unions. Du är medveten om att Rust har inbyggt stöd för detta i språket, till skillnad från t.ex. C++ som har det via bibliotek (kör du boost:.variant eller std::variant?).

Om vi tar ett superenkelt fall och sedan jämför det med något som gör motsvarande på ett idiomatiskt sätt i Rust och C#. Definiera en "tagged union" som i alla fall kan hålla int, double och sträng. Vi gör sedan en funktion som adderar två sådana.

Kort svar, får läsa sedan men angående tagged unions

Exempe (så poletten trillar ner)l

eTypeUnknown = eTypeNumberUnknown, eTypeBool = eTypeNumberBool | eTypeGroupBoolean | eTypeGroupSize08, eTypeInt8 = eTypeNumberInt8 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize08 | eTypeGroupSigned, eTypeInt16 = eTypeNumberInt16 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize16 | eTypeGroupSigned, eTypeInt32 = eTypeNumberInt32 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize32 | eTypeGroupSigned, eTypeInt64 = eTypeNumberInt64 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize64 | eTypeGroupSigned, eTypeInt128 = eTypeNumberInt128 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize128 | eTypeGroupSigned, eTypeInt256 = eTypeNumberInt256 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize256 | eTypeGroupSigned, eTypeInt512 = eTypeNumberInt512 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize512 | eTypeGroupSigned, eTypeUInt8 = eTypeNumberUInt8 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize08, eTypeUInt16 = eTypeNumberUInt16 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize16, eTypeUInt32 = eTypeNumberUInt32 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize32, eTypeUInt64 = eTypeNumberUInt64 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize64, eTypeUInt128 = eTypeNumberUInt128 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize128, eTypeUInt256 = eTypeNumberUInt256 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize256, eTypeUInt512 = eTypeNumberUInt512 | (eTypeGroupInteger|eTypeGroupNumber) | eTypeGroupSize512, eTypeCFloat = eTypeNumberFloat | (eTypeGroupDecimal|eTypeGroupNumber) | eTypeGroupSize32 | eTypeGroupSigned, eTypeCDouble = eTypeNumberDouble | (eTypeGroupDecimal|eTypeGroupNumber) | eTypeGroupSize64 | eTypeGroupSigned, eTypePointer = eTypeNumberPointer, eTypeGuid = eTypeNumberGuid | eTypeGroupBinary | eTypeGroupSize128, eTypeBinary = eTypeNumberBinary | eTypeGroupBinary, eTypeString = eTypeNumberString | eTypeGroupString, eTypeUtf8String = eTypeNumberUtf8String | eTypeGroupString, eTypeWString = eTypeNumberWString | eTypeGroupString, eTypeUtf32String = eTypeNumberUtf32String | eTypeGroupString, eTypeJson = eTypeNumberJson | eTypeGroupString, eTypeXml = eTypeNumberXml | eTypeGroupString, eTypeVoid = eTypeNumberVoid, eTypeBit = eTypeNumberBit | eTypeGroupBoolean, eTypeRBinary = eTypeNumberBinary | eTypeGroupBinary | eTypeDetailReference, eTypeRString = eTypeNumberString | eTypeGroupString | eTypeDetailReference, eTypeRUtf8String = eTypeNumberUtf8String | eTypeGroupString | eTypeDetailReference, eTypeRWString = eTypeNumberUtf8String | eTypeGroupString | eTypeDetailReference

Dold text

Och alla bättre språk kan hantera det här, inte unikt för C/C++. Det är andra orsaker att jag och många med mig använder C++

Permalänk
Medlem
Skrivet av Yoshman:

Jag tror (och hoppas) ingen längre tror att klk lyssnar. Men svaren som kommer från andra har väldigt ofta spännande information och insikter!

Sant, men ändå tröttsamt

Visa signatur

Debian, bara Debian, Debian överallt

Permalänk
Medlem

Angående exemplet:

int sum(int a, int b) { return a + b; }

Om normal kod såg ut så absolut, finns ingen mening med tagged unions (DOD) med den typen av kod. Men om vi nu skall vara realistiska så ser inte kod ut så, ingen skriver den typen av kod.
DOD är för att hantera verkliga problem.

Skrivet av Yoshman:

Ett problem med LLMs är att skit in blir tyvärr skit ut. Det verkar som du har rätt liten kunskap om t.ex. Rust.

Stämmer
Rust i sig kan säkert fungera men det lockar inte mig. Störst problem med RUST är inte språket utan de som programmerar i språket. Du märker hur otrevlig jag uppfattas här, hur tror du jag skulle klara mig i en sekt som RUST
Det är visserligen lätt och bli poppulär i sekten om man bara säger att RUST är bäst.

Skrivet av Yoshman:

Ett problem med LLMs är att skit in blir tyvärr skit ut. Det verkar som du har rätt liten kunskap om t.ex. Rust.

Håller med, men jag har testat mycket kod (inte min egen alltså). Tycker det är intressant och se hur problem löses med olika språk för jag tror kanske att det ändå märkts att mitt intresse för programmering är extremt (maniskt).

Skrivet av Yoshman:

Helt OK overhead att ta om den behövs, men är det vettigt att köra som nära nog standardval som du verkar göra?

Om man endast använder ett nummer för valfria typer så hade jag nog inte sett speciellt mycket fördelar med DOD, det är trotts allt en tröskel att använda och företag som utvecklar mjukvara där flera utvecklar måste ha något som alla klarar av. Den tröskel blir troligen för hög i förhållande till eventuella vinster.
Sitter jag med egen kod så absolut men inte i team.

I team måste det till smartare lösningar och då att det går att göra dem som en black-box. Andra utvecklare skall inte behöva bry sig och lösningen kommer fungera utan problem +10 år eller mer. Så därav mer trix för att få bättre utväxling

Störst vinst enligt mig är flexibilitet och snabbhet i att ta fram funktionalitet. Du kan ta 5 andra programmerare som väljer att skriva kod efter DDD och tävlar mot en som kör DOD, de kommer inte vinna. DOD är en mycket kraftfull teknik. Att koden blir snabb är något man får på köpet.
Har gjort kod med namgivna argument, alltså man parar namn med värde för det förenklar. Jämför jag det med att anropa en metod med vanliga argument (stacken), så länge det bara är primitiva typer kommer kompilerad kod vara snabbare men petar de bara in något objekt likt en std::string så börjar det jämna ut sig, två std::string och det börjar bli jämnt.
Menar inte att det är normalfall men iblad vet man inte hur logik skall fungera och behöver då något flexibelt och enkellt att förändra, där passar DOD väldigt bra eftersom man så enkellt kan modifiera kod. (ligger data i rad placerad i L1 går det undan)

Permalänk
Skrivet av klk:

En större refaktorering kräver ibland helt omskrivna tester, hur gör du det smidigt

Du måste ha en annan definition av refactoring än vi andra. Vid refactoring strukturerar man om eller skriver om koden men behåller samma externt observerbara beteende. Dvs, du gör ändringar bakom kulisserna, men detta är inget som skall märkas för användaren av APIet. Det är vid dessa tillfällen som enhetstester kan glänsa. De säkerställer att du efter dina ändringar har samma beteende som före dina ändringar. Och det är väl precis vad du vill vid refactoring?

Skrivet av klk:

Bättre lösning:
Vad de borde ha testat var resultat och inte byggt in sig i tekniken. Spelar ingen roll hur resultatet skapades bara det blev rätt output.

Jag kan inte kommentera vad du sett i ditt tidigare liv, men som jag ser enhetstester så gör de precis vad du efterlyser i din bättre lösning. I dina systemtester kör du hela programmet på viss input och verifierar att du får rätt output. Enhetstester anropar de publika funktionerna i ditt API och verifierar att de levererar rätt output. Den stora skillnaden är att din turnaround-time för enhetstesten är mycket kortare och att enhetstesterna kan köras långt innan du ens har ett färdigt program att börja testa.

Permalänk
Medlem
Skrivet av klk:

Tycker det är intressant och se hur problem löses med olika språk för jag tror kanske att det ändå märkts att mitt intresse för programmering är extremt (maniskt).

Det märks inte. Som tidigare nämnt så verkar det som att flera delar bilden av att du en medioker erfarenhet inom C++ för Windows och har dålig koll på terminologi, arkitektur, programmeringsspråk, kvalitetssäkring osv.

Hade ditt intresse varit extremt så hade du plockat upp sådana saker. Min känsla är att du scannar allt du kommer i kontakt med för att bekräfta din redan etablerade världsbild istället för att hämta intryck och vidareutvecklas.

Permalänk
Medlem
Skrivet av orp:

Det märks inte. Som tidigare nämnt så verkar det som att flera delar bilden av att du en medioker erfarenhet inom C++ för Windows och har dålig koll på terminologi, arkitektur, programmeringsspråk, kvalitetssäkring osv.

Hade ditt intresse varit extremt så hade du plockat upp sådana saker. Min känsla är att du scannar allt du kommer i kontakt med för att bekräfta din redan etablerade världsbild istället för att hämta intryck och vidareutvecklas.

väntar fortfarande på att du skall visa expertkod :), det enda du gör är att snacka

Permalänk
Medlem
Skrivet av klk:

väntar fortfarande på att du skall visa expertkod :), det enda du gör är att snacka

Jag har visat dig kod och jag har visat dig prov på teoretisk kunskap. Det är mer än vad du har gjort.

Permalänk
Medlem
Skrivet av orp:

Jag har visat dig kod och jag har visat dig prov på teoretisk kunskap. Det är mer än vad du har gjort.

det har du inte, det du visade var något eget hack som jag tror mest bara var du som visste vad det var

Permalänk
Skrivet av serafim:

Jag hävdar fortfarande att alla som svarar på eller kommenterar klk:s inlägg göder trollet. Allt går i cirklar med noll röd tråd och bara nya vinklingar för att kunna omfrasera och säga ungefär samma saker igen.
Lägg ner debatten, ingen utom klk blir nöjd av att fortsätta mala. Ingen kommer att komma fram till något som gör skillnad. Kolla andra liknande debatter i olika ämnen från 2010 och framåt.

Du har så rätt. Att klk inte tar emot någonting av det vi skriver visste vi redan i januari, då tråden fortfarande handlade om minnessäkerhet i C++ Att försöka föra någon form av vettig diskussion är helt hopplöst då svaren man får typiskt handlar om något helt annat än det man frågade efter och/eller någon slags anekdotisk bevisföring. Jag ser min roll här som lite mer folkbildande. Jag vet att jag inte kommer få klk att ändra uppfattning i någon fråga, men om det skulle släntra in några nya läsare i tråden så skall de inte se några av hans huvudlösa uttalanden oemotsagda. Ingen skall luras att tro att det han säger stämmer.

Permalänk
Medlem
Skrivet av klk:

det har du inte, det du visade var något eget hack som jag tror mest bara var du som visste vad det var

Det jag visade dig var serialisering och deserialisering av bittorrents peer-protokoll. Det kvalificeras inte som ett hack bara för att du inte begriper det.

Permalänk
Medlem
Skrivet av klk:

det har du inte, det du visade var något eget hack som jag tror mest bara var du som visste vad det var

Koden hade ju allt du gillar function overloading, mönster, pattern matching(istället för regex), unit tester, parsning, stora mängder data, deklarativ kod osv.

Permalänk
Skrivet av klk:

det har du inte, det du visade var något eget hack som jag tror mest bara var du som visste vad det var

Nämner inga namn, men det kanske är läge att ta ett steg tillbaka och fundera på vem som postar vad i den här tråden...

Permalänk
Medlem
Skrivet av Ingetledigtnamn:

Nämner inga namn, men det kanske är läge att ta ett steg tillbaka och fundera på vem som postar vad i den här tråden...

Det är väl ingen hemlighet att det är mest jag och Yoshman som postar kod? Annars är det tunt

Och om du tror (vilket jag inte tror att du tror) att det är första gången jag åker på kritik så har du fel.
Min bakgrund eller de miljöer jag jobbat i skiljer sig dock ganska kraftigt från vad som är normalt. Har i princip alltid jobbat med extrem tidspress för att få fram produkter snabbt. Då går det inte att använda sig av standardlösningar

Få är vana vid det