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

Permalänk

Nu blev det ytterligare en uppräkning om att HN är bra utan väldigt lite varför.

Skrivet av klk:

Har du inget likt HN och deklererar med "auto, let, var" så blir koden mycket svårare att läsa.

Ok, det är kan vara en fördel, men en av poängerna med auto är väl just att man kan slippa bry sig om exakt vad det är för typ på variabeln? Någonting kom från ett funktionsanrop och skall skickas vidare till ett annat funktionsanrop och då är det kanske inte så viktigt vad detta objekt har för typ. Är det vitalt att det är en uint64_t då kan man klämma dit det i deklarationen.

Skrivet av klk:

Om du inte väljer HN untyttjar man inte möjligheter att göra koden mer förståelig för utvecklare, exempelvis för domäner som är väldigt svåra. Där kan i princip inte utvecklare jobba med koden utan att gå någon kurs eller liknande för att lära sig vad olika namn är för något, även om de gör det blir det mycket svårt att jobba i koden.

Nu förstår jag inte varför domänen skulle bli lättare för att man dekorerar sina variabler med typprefix. Det kommer väl rimligen vara samma konstiga namn i den flexibla delen. Om det är en komplex domän är väl den i sig magnituder svårare än ha hålla koll på om en variabel är en pekare eller inte? Om inte programmeraren klarar det utan prefix är det nog kört för projektet ändå.

Skrivet av klk:

Se det jag räknade upp men givetvis är det också bra om alla utvecklare kan domänen, problemet är bara att samma sak kommer få så många olika namn så även om de kan domänen blir det slarvigare.

Varför skulle saker och ting få mer varierande namn om man inte kör HN? HN-användaren och icke-HN-användaren drabbas väl av exakt som problem när man skall sätta ett relevant namn på flex-delen av variabeln? Här vill man förmedla saker som användning, innehåll eller roll och namnsättning är svårt, men det är väl lika svårt oavsett om man kör HN eller inte? Varför drabbas inte HN-användaren av olikhet och slarv för flexdelarna av namnen?

Nu vet jag inte hur prefixet skulle se ut för lista av something, men jag måste ju erkänna att en variabel som p_list_something_first kommer vara mer lik p_list_something_last än variabeln first är lik last, så i någon mening får du säkert mer likformiga namn om du använder HN. Men å andra sidan, så drunknar, de i mina ögon mest relevanta delarna av namnen, first och last helt i prefixet. Blir det verkligen lättare att läsa och förstå? Vad har jag missat?

Permalänk
Medlem
Skrivet av Ingetledigtnamn:

Ok, det är kan vara en fördel, men en av poängerna med auto är väl just att man kan slippa bry sig om exakt vad det är för typ på variabeln? Någonting kom från ett funktionsanrop och skall skickas vidare till ett annat funktionsanrop och då är det kanske inte så viktigt vad detta objekt har för typ. Är det vitalt att det är en uint64_t då kan man klämma dit det i deklarationen.

Svarar inte på allt nu skall försöka återkomma men auto är intressant sett till hur man hanterar kod.
Utvecklaren erbjuds ett verktyg men det är sedan upp till utvecklaren och hantera verktyget. Om jag gör en liknelse med hammare, ett verktyg för en snickare. Man kan göra en del med hammare men det viktigt och veta hammarens begränsningar.

Jag har personligen skrivit väldigt mycket serverkod. Det är min "specialitet" om man kan ha någon sådan. Servrar för inte krascha, ofta servar servern en hel hög med användare så man behöver kontrollera mycket mer än i klientkod.

auto kan användas för att typen eller variabeln spelar mindre roll för helheten, typiskt är felinformation

auto result_ = method( bla, bla ); if( !result_ ) return error; result_ = method1( bla, bla ); if( !result_ ) return error; result_ = method2( bla, bla ); if( !result_ ) return error;

Skriver jag HN brukar jag lägga ett _ i slutet och variabeln är mindre viktig, typ spelar mindre roll eller om man måste granska typen för att veta vad det är, att det kan vara vad som helst.

Eftersom serverkod har så mycket sådan här felhantering försöker jag gömma koden, brukar till och med lägga if satsen långt till höger. Det är kod som är oviktig för metodens funktionalitet.

auto är också lite som ett enklare sätt att skriva template metoder, man kan skriva metoder som sväljer lite vad som helst.

Förutom det så tror jag det vanligaste område där auto används är när det annars blir för kladdigt, långa template uttryck. Det är egentligen den viktigaste anledningen till auto.

auto kan användas till massor men den skall INTE användas till massor, vet inte programmeraren om det är ok att använda auto så skall programmeraren inte använda auto. Enligt mig måste det finnas en mycket god anledning till att använda auto.

Typen är jätteviktigt för att förstå kod. Typen beskriver vad det är för data och det är precis det som programmerare hanterar. Programmerare skriver kod för att hantera data och då måste man veta vad det är för data som hanteras.

Programmerare som viftar bort att "typen är inte så viktig" eller något annat dumt har ingen aning om vad programmering är, de håller troligen på med deklarativ programmering som är en annan typ av "programmering". Imperativ programmering är nästan motsatsen till deklarativ programmering.
Imperativ programmering är att försöka lösa något med kod så bra som möjligt
Deklarativ programmering, där är målet att skriva så lite kod som möjligt (helst ingen kod alls)

Permalänk
Medlem
Skrivet av klk:

de håller troligen på med deklarativ programmering som är en annan typ av "programmering". Imperativ programmering är nästan motsatsen till deklarativ programmering.
Imperativ programmering är att försöka lösa något med kod så bra som möjligt
Deklarativ programmering, där är målet att skriva så lite kod som möjligt (helst ingen kod alls)

Härligt, vi är tillbaka på ruta ett

Permalänk
Medlem
Skrivet av pine-orange:

Härligt, vi är tillbaka på ruta ett

Japp, @klk är verkligen immun mot information...

Permalänk
Medlem
Skrivet av orp:

Japp, @klk är verkligen immun mot information...

Ja om den är fel.

Men om du beskriver, vad anser du vara det som skiljer mellan imperativ och deklarativ programmering?

Permalänk
Medlem
Skrivet av klk:

Programmerare som viftar bort att "typen är inte så viktig" eller något annat dumt har ingen aning om vad programmering är, de håller troligen på med deklarativ programmering som är en annan typ av "programmering". Imperativ programmering är nästan motsatsen till deklarativ programmering.
Imperativ programmering är att försöka lösa något med kod så bra som möjligt
Deklarativ programmering, där är målet att skriva så lite kod som möjligt (helst ingen kod alls)

Hmmm...
I korthet kan man säga att man i imperativ programmering talar om vad som ska göras medan man i deklarativ programmering talar om vad man vill komma fram till.
Så, i imperativ programmering säger man med hjälp av imperativer "gör så här så får vi se vad det blir för resultat".
I deklarativ programmering säger man "här är egenskaperna hos det resultat jag letar efter, hitta de data som tillsammans motsvarar de egenskaperna om det finns sådana data".

Permalänk
Medlem
Skrivet av klk:

Ja om den är fel.

Men om du beskriver, vad anser du vara det som skiljer mellan imperativ och deklarativ programmering?

Något förenklat så:
Imperativ kod beskriver hur något skall göras.
Deklarativ kod beskriver vad som skall göras.

Om vi tar ett nästintill trivialt exempel: En funktion fac(n) som skall beräkna fakulteten av ett naturligt tal n.
(Skrivet i pseudokod, men det bör inte vara svårt att översätta till valfritt programmeringsspråk)

// Deklarativ kod fac(0) = 1 fac(n) = n * fac (n-1)

// imperativ kod fac (n) = { res = 1 for i = 1 to n res = res * i endfor return res }

Eller om vi tar ett lite mer avancerat exempel: Hitta poster i en databas. Återigen pseudokod, och långtifrån optimal kod

// Deklarativ kod SELECT name FROM students WHERE age >= 18

// imperativ kod result = [] table = find_table(students) len = get_num_entries(table) for i = 1 to len entry = table[i] if entry.age >= 18 add_to_array(entry, result) endif endfor return result

Som synes så brukar imperativ kod bli mer detaljorienterad och man måste oftast hålla reda på en massa mer tillståndsinformation än i deklarativ kod.

Permalänk
Medlem
Skrivet av Erik_T:

Som synes så brukar imperativ kod bli mer detaljorienterad och man måste oftast hålla reda på en massa mer tillståndsinformation än i deklarativ kod.

Precis, målet med deklarativ är att endast säga vad man vill göra, man behöver inte tänka på hur det skall göras för det är den imperativa kodens uppgift och det är därför de är varandras motsatser.
Desto mindre kod som behövs för att säga till vad man skall göra desto bättre, målet med deklarativ kod är att inte skriva någon kod alls.

Permalänk
Medlem
Skrivet av klk:

Ja om den är fel.

Fast nu är det framförallt du som säger felaktigheter i denna tråden. Alla hjälps ju åt att rätt din konstanta felanvändning av termer.

Skrivet av klk:

Men om du beskriver, vad anser du vara det som skiljer mellan imperativ och deklarativ programmering?

Det enklaste är ju om du bara läser Wikipedia så kommer du ju ha samma definition som alla andra i världen. Något säger mig att det inte kommer fastna denna(typ 8:e gången) gången i heller.

Deklarativ/imperativ är bara paradigm. Paradigm kan enkelt förklaras som en samling karaktärsdrag hos språken.

Imperativt kan enklast beskrivas som att man som utvecklare stegvis säger hur saker ska utföras.
Deklarativt kan enklast beskrivas som att utvecklaren beskriver vad som ska uppnås.

Exempelvis välja jämna tal ur en lista. (Pseudokod så det inte triggar igång dina Python-trauman)
Imperativt:

all_nums = [1,2,3,4,5,6] even = [] for num in all_nums: if (num % 2) == 0 : even.add(num)

Förklaring:
Fokuset ligger på stegvisa instruktioner som följer
1. välj ett tal från listan
2. beräkna modulo
3. om resultat är 0
4. lägg till i resultat lista

Deklarativt:

all_nums = [1,2,3,4,5,6] even = all_nums.map(|x| (x % 2) == 0)

Förklaring:
Genom valet av map()-operationen ihop med villkoret så fokuserar vi framförallt på vad som ska uppnås utan att fokusera på stegen dit.

Notera att detta enbart är olika sätt att programmera, inget är nödvändigtvis bättre eller sämre utan annorlunda. Under deklarativa språk så hittar du alla funktionella språk: haskell, prolog, ocaml, erlang. Ett karaktärsdrag som brukar överraska folk som börjar med funktionell programmering är att dom oftast(säger detta som en reservation för att jag inte har koll på alla funktionella språk) är avsaknad av loopar(for, while, osv) och man löser detta istället med tail-recursion.

Om vi tar ditt favoritspråk Python, som du brukar kalla deklarativt, så brukar det skrivas med många if-statements och for-loopar och väldigt lite iterator-funktioner, vilket tyder på att Python framförallt är ett imperativt språk. Sedan kan du skriva till saker som iterator-funktioner och få till en programmeringsstil som efterliknar funktionell-språk men detta kan du i alla imperativa språk även C++.

Nöjd? Kan du absorbera detta nu så vi slipper ha denna diskussionen en 9:e och 10:e gång?

Permalänk
Medlem
Skrivet av klk:

Precis, målet med deklarativ är att endast säga vad man vill göra, man behöver inte tänka på hur det skall göras för det är den imperativa kodens uppgift och det är därför de är varandras motsatser.
Desto mindre kod som behövs för att säga till vad man skall göra desto bättre, målet med deklarativ kod är att inte skriva någon kod alls.

Att skriva ingen kod alls är viss mening optimalt för både deklarativ och imperativ kod - nämligen i de fall när man konstaterar att vissa operationer inte behöver göras och man därför kan optimera bort hela kodavsnitt.

Men är det något som behöver göras så behövs kod, man kan inte göra det med ingen kod alls. Så att säga att målet med deklarativ kod är att inte skriva någon kod alls, det stämmer inte.

Även om deklarativ kod oftast blir kortare och mer koncis än imperativ kod, så har den inte andra mål än imperativ kod.
Att skriva liten mängd kod kan vara bra, men betydligt viktigare är att den kod som skrivs är begriplig. (Koden bör naturligtvis också vara korrekt, effektiv, testbar, m.m. men att den är begriplig är en bra början.) I det avseendet så är det ingen som helst skillnad mellan imperativ och deklarativ kod.

Även när man skriver imperativ kod så är det vanligtvis mängder av detaljer där man inte behöver fundera på exakt hur det görs - man bara litar på att kompilator och hårdvara gör något bra.
Exempelvis en enkel kodrad som a = b * c kan implementeras på många olika sätt. Variablerna kanske ligger i hårdvaruregister, eller på stacken, eller på någon annan plats i minnet. Multiplikationen kanske görs med en enda CPU-instruktion, eller så kanske en biblioteksrutin behöver anropas. Och så vidare.
Så fort man kommer steget ovanför ren hårdvarudesign så innehåller all programmering deklarativa element där man inte tänker på hur något görs.

Permalänk
Medlem
Skrivet av klk:

Precis, målet med deklarativ är att endast säga vad man vill göra, man behöver inte tänka på hur det skall göras för det är den imperativa kodens uppgift och det är därför de är varandras motsatser.
Desto mindre kod som behövs för att säga till vad man skall göra desto bättre, målet med deklarativ kod är att inte skriva någon kod alls.

Det är inte varandras motsatser det är inte jedi vs sith. Många moderna språk implementera funktionella aspekter eftersom många utvecklare uppskattar dessa som iterator-funktioner som map, filter, fold. Detta gör språket mer attraktivt för en bredare massa. Rust och Go har det och jag skulle misstänka att C++ har det in någon utsträckning beroende på hur moderna dom vill uppfattas.

Sedan nu kopierar du och repeterar från @Erik_T men det du skrev ursprungligen var:

Skrivet av klk:

Imperativ programmering är att försöka lösa något med kod så bra som möjligt
Deklarativ programmering, där är målet att skriva så lite kod som möjligt (helst ingen kod alls)

Vilket är en helt annan sak än vad som ska lösas eller hur något ska lösas. Många utvecklare skulle hävda att funktionell(dvs deklarativa) lösningar är bättre än imperativa (har för mig att @Yoshman pratat om optimeringar relaterat till iterator-funktioner i Rust).

Permalänk

FortMajeure: Authentication Bypass in FortiWeb (CVE-2025-52970)

På tal om trådens ämne så är här ytterligare ett "färskt" exempel på vad som kan inträffa när OOB inte hanteras i icke-minnessäkra språk. Här är pseudokod-C-kod från personen (se Källa nedan) som hittade en bugg i FortiWeb-mjukvara:

Källa: https://pwner.gg/blog/2025-08-13-fortiweb-cve-2025-52970

Variabeln Era omfångskontrolleras aldrig så du enkelt kan göra anspråk på indexvärden utanför dess faktiska tänkta omfång (0 eller 1). Hade exempelvis Rust här slagit ifrån att variabeln Era inte omfångskontrollerats innan dess indexåtkomstsförsök gjordes?

EDIT: Enligt denna programmerare hade Rust fixat det där ovannämnda https://youtu.be/JNW5fHJ-Nyo?t=789. Tragedikomiskt nog så kom denna sårbarhet kort efter SQL-injiceringsupptäckt från samma person. Det är alltså en SQL-injiceringssårbarhet i en mjukvara vars syfte är att skydda mot SQL-injiceringar?!🤔

Mvh,
WKF.

Visa signatur

(V)ulnerabilities
(I)n
(B)asically
(E)verything
Programming

Permalänk
Medlem
Skrivet av WebbkodsFrilansaren:

På tal om trådens ämne så är här ytterligare ett "färskt" exempel på vad som kan inträffa när OOB inte hanteras i icke-minnessäkra språk. Här är pseudokod-C-kod från personen (se Källa nedan) som hittade en bugg i FortiWeb-mjukvara:
https://pwner.gg/blog/attachments/forti-oob-ida.png
Källa: https://pwner.gg/blog/2025-08-13-fortiweb-cve-2025-52970

Variabeln Era omfångskontrolleras aldrig så du enkelt kan göra anspråk på indexvärden utanför dess faktiska tänkta omfång (0 eller 1). Hade exempelvis Rust här slagit ifrån att variabeln Era inte omfångskontrollerats innan dess indexåtkomstsförsök gjordes?

EDIT: Enligt denna programmerare hade Rust fixat det där ovannämnda https://youtu.be/JNW5fHJ-Nyo?t=789. Tragedikomiskt nog så kom denna sårbarhet kort efter SQL-injiceringsupptäckt från samma person. Det är alltså en SQL-injiceringssårbarhet i en mjukvara vars syfte är att skydda mot SQL-injiceringar?!🤔

Mvh,
WKF.

OK, men på vilket sätt har det att göra med att språket inte är minnessäkert?
Och att "Era" inte omfångskontrolleras har väl inte någon koppling till en eventuell SQL-injicering heller eller är jag helt ute och cyklar?
Förklaring, tack.

Off topic: Förfärlig programkod, flera GOTO, variabler numrerade (v8, v9, v...), mm. Inte en kod man vill underhålla eller debugga. Inga kommentarer som gör att man förstår vad som förväntas hända. Har suttit många gånger med sådan kod att debugga och inte lyckats förrän jag gjorde en förteckning över alla variabler, vad de hade för typ o.s.v. + kommenterat koden utifrån det.
Ren mardröm.

Permalänk
Datavetare
Skrivet av SimpLar:

Det är exakt vad Python-koden i ditt exempel gör, och jag erkänner att jag stirrade mig lite blind på just den delen. Jag medger att det pattern som används härmar interfaces i andra språk, men Python's runtime saknar interfaces och detta är i praktiken överskuggning sett till hur iaf CPython kommer utvärdera anrop till metoden.

Vi kanske talar om varandra. Jag tolkade som att du i ditt inlägg menade att alla exempel demonstrerade överlagring eftersom spoilern löd "trivial exempel med överlagring i C++, Rust, Go och Python", men baserat på detta uttalande kanske du helt enkelt bara demonstrerade polymorfism? Det har jag inga invändningar mot, det är absolut polymorfism alltihop.

Jag är heller inte av uppfattningen att implementering av interfaces/traits är något som generellt definieras som överlagring. Om vi tar Go som exempel har till och med dess FAQ en sektion som talar om varför språket inte stödjer överlagring. Polymorfism? Absolut. Men överlagring? Det har jag svårt att se att många skulle tolka det som, även om jag till viss del håller med om att det skulle kunna passa in rent definitionsmässigt ("kontexten" för överlagringen blir den konkreta typen).

Jag tror att du missade den sista metoden som tar strängar istället för ints. Det går inte generellt att hantera med variadics. Och även om det skulle gå hävdar jag ändå att detta är typexempel på (funktions/metod)överlagring. Att andra tekniker kan uppnå samma sak (generics, till exempel) gör inte att detta blir mindre överlagrat.

Den andra välkända formen av överlagring är operatoröverlagring, som om något är ännu mer omtvistat än funktionsöverlagring. Men principen är exakt densamma.

Innan denna diskussion skulle jag säga att det är fullt tillräckligt! Att bara säga "överlagra" är i min mening starkt indikativt att personen avser funktions- eller operatoröverlagring, givet att denne har ett hyggligt grepp om programmering, och kontexten borde avslöja resten. Men då jag anser att du är en högst påläst och kunnig person så får jag helt enkelt medge att det inte är tillräckligt, denna diskussion är ju inget annat än skriftligt bevis för det. Iallafall inte när kontexten är såpass lösryckt som den är här.

Nu har jag nog gjort mitt i att gå på side quests i denna tråd. Jag tror vi eventuellt får "agree to disagree".

Jag tror vi är helt överens och är helt med på "override" betydelsen (i C# är det ju bokstavligen nyckelordet för att kunna ändra en metod i en subtyp). Angående variadic saken, miss av mig då jag tendera scanna saker väldigt fort på dagtid arbete har prio.

Men i detta kontext (denna tråd) känner i alla fall jag att "överlagring" är långt mer luddigt och eventuellt nog mer refererade till polymorfism.

Klart man kan läsa på, är ju skolad på Sveriges bästa lärosäte: KTH

Visa signatur

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

Permalänk
Skrivet av serafim:

OK, men på vilket sätt har det att göra med att språket inte är minnessäkert?
Och att "Era" inte omfångskontrolleras har väl inte någon koppling till en eventuell SQL-injicering heller eller är jag helt ute och cyklar?
Förklaring, tack.

Off topic: Förfärlig programkod, flera GOTO, variabler numrerade (v8, v9, v...), mm. Inte en kod man vill underhålla eller debugga. Inga kommentarer som gör att man förstår vad som förväntas hända. Har suttit många gånger med sådan kod att debugga och inte lyckats förrän jag gjorde en förteckning över alla variabler, vad de hade för typ o.s.v. + kommenterat koden utifrån det.
Ren mardröm.

Tjo!

Jag tror det är någon form av "pseudokod" reverse-engineered av personen ifråga? Eller är det där riktig C-kod trots allt? Jag tänkte att det var resultatet av någon kodkonvertering eller -transpilering?

Sorry om SQL-grejen, det är bara att inlägget jag hämtade från sa själva att det var som en "uppföljare" då det rörde kod från ett och samma företag som erbjuder WAF-produkten/tjänsten! (=kanske samma utvecklare med samma brister?)

Mvh,
WKF.

Visa signatur

(V)ulnerabilities
(I)n
(B)asically
(E)verything
Programming

Permalänk
Datavetare
Skrivet av serafim:

OK, men på vilket sätt har det att göra med att språket inte är minnessäkert?
Och att "Era" inte omfångskontrolleras har väl inte någon koppling till en eventuell SQL-injicering heller eller är jag helt ute och cyklar?
Förklaring, tack.

Off topic: Förfärlig programkod, flera GOTO, variabler numrerade (v8, v9, v...), mm. Inte en kod man vill underhålla eller debugga. Inga kommentarer som gör att man förstår vad som förväntas hända. Har suttit många gånger med sådan kod att debugga och inte lyckats förrän jag gjorde en förteckning över alla variabler, vad de hade för typ o.s.v. + kommenterat koden utifrån det.
Ren mardröm.

Ingen lär ha skrivit den koden, gissat att det är en C de-compiler. Som i min mening gör ett fantastiskt jobb om den bara hade assembler att utgå från.

Rätt säker att de använder retdec-decompiler (https://github.com/avast/retdec)

Ursprunglig kod

#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { if (argc < 2) { printf("Usage: %s <int1> <int2> [int3 ...]\n", argv[0]); return 1; } int sum = 0; for (int i = 1; i < argc; i++) { int value = atoi(argv[i]); sum += value; printf("%s", argv[i]); if (i < argc - 1) { printf(" + "); } } printf(" = %d\n", sum); return 0; }

Kompilerar det med -O2 i GCC, kör sedan de-compile och får detta (är mer output, tog ut det centrala)

// Address range: 0x1080 - 0x1141 int main(int argc, char ** argv) { if ((int32_t)argc < 2) { // 0x1124 __printf_chk(2, "Usage: %s <int1> <int2> [int3 ...]\n", argv)\ ; // 0x1115 return 1; } int32_t v1 = 0; // 0x10b4 int64_t v2 = 1; // 0x10b4 int64_t * str = (int64_t *)(8 * v2 + (int64_t)argv); // 0x10b8 int32_t str_as_l = strtol((char *)*str, NULL, 10); // 0x10c3 __printf_chk(2, "%s", (char *)*str); if ((argc + 0xffffffff & 0xffffffff) > v2) { // 0x10e2 __printf_chk(2, " + "); } // 0x10f5 v1 += str_as_l; v2++; while (v2 != (argc & 0xffffffff)) { // 0x10b8 str = (int64_t *)(8 * v2 + (int64_t)argv); str_as_l = strtol((char *)*str, NULL, 10); __printf_chk(2, "%s", (char *)*str); if ((argc + 0xffffffff & 0xffffffff) > v2) { // 0x10e2 __printf_chk(2, " + "); } // 0x10f5 v1 += str_as_l; v2++; } // 0x10fe __printf_chk(2, " = %d\n", (int64_t)v1); // 0x1115 return 0; }

Exempel
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 serafim:

OK, men på vilket sätt har det att göra med att språket inte är minnessäkert?

Om du kan läsa utanför ditt tilldelade minnesområde är det inte minnessäkert.

Permalänk
Medlem
Skrivet av Yoshman:

Jag tror vi är helt överens och är helt med på "override" betydelsen (i C# är det ju bokstavligen nyckelordet för att kunna ändra en metod i en subtyp). Angående variadic saken, miss av mig då jag tendera scanna saker väldigt fort på dagtid arbete har prio.

Men i detta kontext (denna tråd) känner i alla fall jag att "överlagring" är långt mer luddigt och eventuellt nog mer refererade till polymorfism.

Vi är absolut överens om override.

Vad överlagring faktiskt refererade till i det ursprungliga sammanhanget här i tråden måste jag erkänna att jag inte har den minsta uppfattning om. Jag tappade spåret någonstans vid en telefonbok. Jag var helt inne på vad termerna betyder rent generellt, därmed brasklappen att jag knappast tillförde något vettigt till tråden.

Jag måste erkänna att jag med facit i hand bara skulle ha fortsatt äta popcorn och titta på spektaklet som är denna tråd istället för att bli en del av det själv. Lätt att vara efterklok!

Skrivet av Yoshman:

Klart man kan läsa på, är ju skolad på Sveriges bästa lärosäte: KTH

Jag hoppas att du förstod att jag menade att du i min uppfattning är påläst (i mångt och mycket långt över min egen kunskapsnivå). Inte att du behövde läsa på ytterligare. Jag försökte alltså säga att jag respekterade din åsikt även om den inte stämde överens med min.

Förtydligande
Permalänk
Medlem
Skrivet av Erik_T:

Att skriva ingen kod alls är viss mening optimalt för både deklarativ och imperativ kod - nämligen i de fall när man konstaterar att vissa operationer inte behöver göras och man därför kan optimera bort hela kodavsnitt.

Inser att min tidigare liknelse om ”att inte skriva någon kod alls” kan uppfattas som kryptisk. Självklart går det inte att abstrahera bort all kod – i så fall skulle vi inte behöva några programmerare. Men att ha det målet även om det inte går att nå hjälper i alla fall till och tänka mer rätt.

Tycker kanske att begreppen imperativ och deklarativ ofta förvirrar mer än de hjälper. Istället föredrar jag att tänka i termer av Producent och Konsument. Det tycker jag ger en bättre modell för hur man kan strukturera kod.

Programmering handlar inte om en enda stor producent (utvecklaren) och en enda konsument (användaren). Snarare är kod en komplex kedja av transformationer där data flödar genom olika steg – och vid varje steg finns det både producenter och konsumenter.

Ta till exempel en webbapplikation:

  • - Användaren matar in data i en webbsida.

  • - JavaScript samlar in och validerar datan, och skickar den till servern.

  • - Servern tar emot datan och dirigerar den till rätt hanterare.

  • - Affärslogiken kontrollerar och bearbetar datan ytterligare.

  • - Datat transformeras och förbereds för lagring.

  • - Datat sparas i en databas.

Varje steg i denna kedja innebär ett producent-konsument-förhållande. De flesta komponenter är både konsumenter (av data från föregående steg) och producenter (av data till nästa steg).

Genom att tänka på detta sätt blir det enklare att placera olika typer av logik på rätt ställe. Utan den här förståelsen lär det snabbt bli rörigt och svårhanterligt.

Förstå förloppet hur data transporteras i "vanliga" websystem är inte så svårt, det blir ofta mycket svårare i andra typer av system. Spel, Cad, Ordbehandlare, Beräkningsrogram och så vidare. Om systemet inte har en mycket väldefinierad arkitektur hur data bearbetas kommer de inte lyckas ta fram systemet, det är för svårt eftersom det blir rörigt

Permalänk
Medlem
Skrivet av SimpLar:

Jag tappade spåret någonstans vid en telefonbok.

Telefonboken är ett bra exempel på hur man kan hantera stora datamängder effektivt utan att behöva memorera all information. Istället räcker det att förstå det underliggande mönstret: informationen är alltid strukturerad på samma sätt på varje sida (namn, telefonnummer, adress). Detta gör att man snabbt kan hitta vad man söker efter, oavsett hur stor telefonboken är.

På samma sätt kan bra kodstrukturer hantera stora kodmängder utan att utvecklares prestanda i att hantera koden försämras. Systemet "skalar" alltså bra - det går att lägga till mer logik utan att hastigheten eller svårigheten att hantera koden påverkas nämnvärt.

För att det här skall fungera behövs språk som är flexibla nog för att kunna hitta mönster som är enkla men som också klarar att producera den logik som önskas för aktuell mjukvara. Där är överlagring mycket viktigt eftersom det går att skapa enklare kodstrukturer men som ändå har önskad logik

Givetvis är sådana här kodstrukturer mycket mer komplexa än telefonbokens struktur. Och kan man inte strukturen blir koden oläsbar, samma som en som inte lärt sig hur en telefonboks struktur fungerar även om den är lätt att lära

Telefonboksexemplet är också bra för att förstå hur lätt det är att förstöra data/kod. Att hacka in några telefonnummer i telefonboken som inte följer mönstret, hur svårt blir det inte att hitta dem?
Samma sak med kod för förstår man telfonboken så blir det lättare och förklara hur viktigt det är med att inte frångå fasta kodstrukturer.

Permalänk
Medlem
Skrivet av klk:

Inser att min tidigare liknelse om ”att inte skriva någon kod alls” kan uppfattas som kryptisk. Självklart går det inte att abstrahera bort all kod – i så fall skulle vi inte behöva några programmerare. Men att ha det målet även om det inte går att nå hjälper i alla fall till och tänka mer rätt.

Att minska mängden kod som behöver skrivas är precis lika viktigt eller oviktigt när man skriver imperativ kod som när man skriver deklarativ kod. Och är sällan ett primärt mål i endera fallet. Så har man det målet, tänker man oftast fel.

Citat:

Tycker kanske att begreppen imperativ och deklarativ ofta förvirrar mer än de hjälper. Istället föredrar jag att tänka i termer av Producent och Konsument. Det tycker jag ger en bättre modell för hur man kan strukturera kod.

Nu håller du nog på och försöker jämföra äpplen med päron motorcyklar.
Imperativ kontra deklarativ programmering har lite eller inget att göra med hur kod är strukturerad. De är snarare två olika sätt att tänka när man skriver kod.

Producent och Konsument är lite olyckligt valda termer för att diskutera kodstruktur, eftersom Producent-Konsument redan har en väletablerad betydelse i programmering, nämligen att beskriva ett visst mönster i multi-process kommunikation.

Permalänk
Medlem
Skrivet av klk:

Telefonboken är ett bra exempel på hur man kan hantera stora datamängder effektivt utan att behöva memorera all information. Istället räcker det att förstå det underliggande mönstret: informationen är alltid strukturerad på samma sätt på varje sida (namn, telefonnummer, adress). Detta gör att man snabbt kan hitta vad man söker efter, oavsett hur stor telefonboken är.

Anledningen till att man snabbt kan hitta vad man söker efter i en telefonkatalog är inte primärt på grund av hur informationen på en sida är strukturerad, utan det är på grund av att informationen är sorterad så att man kan göra en snabb binärsökning på namn för att hitta rätt telefonnummer, iställer för att behöva läsa igenom hela katalogen från början.

Skulle man istället ha ett telefonnummer och försöka hitta vem som har det, så går det inte snabbt att hitta det i en telefonkatalog trots att informationen finns där, då den inte är sorterad efter nummer.

Så länge telefonkatalogen är sorterad efter namn, så spelar det inte så stor roll om enskilda poster är strukturerade som (namn, telefonnummer, address) eller (telefonnummer, namn) eller (address, namn, telefonnummer).
Det går ändå snabbt att slå upp ett telefonnummer baserat på namn, och att ha alla poster strukturerade likadant skulle bara hjälpa marginellt.

Permalänk
Medlem
Skrivet av Erik_T:

Anledningen till att man snabbt kan hitta vad man söker efter i en telefonkatalog är inte primärt på grund av hur informationen på en sida är strukturerad, utan det är på grund av att informationen är sorterad så att man kan göra en snabb binärsökning på namn för att hitta rätt telefonnummer, iställer för att behöva läsa igenom hela katalogen från början.

Hmmm. Ok
Mitt exempel var inte skrivet för att vara något vetenskapligt korrekt utan för att få fram en poäng Typ mer att man skulle förstå intentionen och då är en telefonbok något många känner igen.

Problemet med en telefonbok är kanske annars att den är på papper, svårt att sortera om. Hade det varit elektroniskt hade det säkert sorterats på olika kolumner.

När du skriver kod, vad tänker du på? Har du något du försöker tänka på för att koden skall se bra ut och fungera bra i resten av projektet?

Permalänk
Medlem
Skrivet av Erik_T:

Producent och Konsument är lite olyckligt valda termer för att diskutera kodstruktur, eftersom Producent-Konsument redan har en väletablerad betydelse i programmering, nämligen att beskriva ett visst mönster i multi-process kommunikation.

Om man jobbat i den här branschen ett tag (typ väldigt länge) så har man varit med i en resa där massor av saker har bytt namn flera gånger. Och enligt mig så går det inte att diskutera kod om personer endast vet namnet men inte förstår koden, alltså vad som menas.

Förstår de vad som menas går det lättare.

Permalänk
Medlem
Skrivet av klk:

Om man jobbat i den här branschen ett tag (typ väldigt länge) så har man varit med i en resa där massor av saker har bytt namn flera gånger. Och enligt mig så går det inte att diskutera kod om personer endast vet namnet men inte förstår koden, alltså vad som menas.

Förstår de vad som menas går det lättare.

Ja exakt. Du använder ord som redan har väldefinierade betydelser. När du istället borde förklara vad du menar (utan omdefinierade termer). Du får leva som du lär helt enkelt.

Permalänk
Datavetare
Skrivet av SimpLar:

Jag hoppas att du förstod att jag menade att du i min uppfattning är påläst (i mångt och mycket långt över min egen kunskapsnivå). Inte att du behövde läsa på ytterligare. Jag försökte alltså säga att jag respekterade din åsikt även om den inte stämde överens med min.

Jag menade bara: vi har ju gått på samma skola, om något fick man där lära sig att lära sig. Du lyfte faktiskt en sak jag aldrig reflekterat över innan: vad är ett vettigt namn för "overload" på svenska.

Vi har ju en annan favorit som brukar ställa till problem på svenska, "säkerhet". Är det eng. "safety" (som tråden handlar om) eller "security"? Precis som "strålspårning" nog är mer förvirrande än bra, ray-tracing fattar de iblandade, kanske man ändå bör använda "overload" och "override" även på svenska.

Sen tror jag ändå det relevanta i slutändan bara är att alla är variationer på polymorfism, vilket i sig är superanvändbart.

Så "absolutely no offence taken", det är ju en diskussion och den är klar när man nått konsensus (vilket aldrig lär hända i en tråd på Internet...)

Skrivet av klk:

Telefonboken är ett bra exempel på hur man kan hantera stora datamängder effektivt utan att behöva memorera all information. Istället räcker det att förstå det underliggande mönstret: informationen är alltid strukturerad på samma sätt på varje sida (namn, telefonnummer, adress). Detta gör att man snabbt kan hitta vad man söker efter, oavsett hur stor telefonboken är.

På samma sätt kan bra kodstrukturer hantera stora kodmängder utan att utvecklares prestanda i att hantera koden försämras. Systemet "skalar" alltså bra - det går att lägga till mer logik utan att hastigheten eller svårigheten att hantera koden påverkas nämnvärt.

För att det här skall fungera behövs språk som är flexibla nog för att kunna hitta mönster som är enkla men som också klarar att producera den logik som önskas för aktuell mjukvara. Där är överlagring mycket viktigt eftersom det går att skapa enklare kodstrukturer men som ändå har önskad logik

Givetvis är sådana här kodstrukturer mycket mer komplexa än telefonbokens struktur. Och kan man inte strukturen blir koden oläsbar, samma som en som inte lärt sig hur en telefonboks struktur fungerar även om den är lätt att lära

Telefonboksexemplet är också bra för att förstå hur lätt det är att förstöra data/kod. Att hacka in några telefonnummer i telefonboken som inte följer mönstret, hur svårt blir det inte att hitta dem?
Samma sak med kod för förstår man telfonboken så blir det lättare och förklara hur viktigt det är med att inte frångå fasta kodstrukturer.

Inser hur träffsäker "telefonkatalog" ändå blir över hur jag, efter många försök att faktiskt förstå, känner kring saker som HN och andra saker kring "strukturering av kod" du nämt.

Sedan ~2000 är "telefonkatalog" en benämning på en samling information, som inte sällan ny-publiceras med jämna mellanrum, en benämning på information som är i praktiken 100 % redundant och som nära nog ingen längre bryr sig i. Men det är ändå en källa som historiskt hade ett värde.

Skrivet av klk:

Om man jobbat i den här branschen ett tag (typ väldigt länge) så har man varit med i en resa där massor av saker har bytt namn flera gånger. Och enligt mig så går det inte att diskutera kod om personer endast vet namnet men inte förstår koden, alltså vad som menas.

Förstår de vad som menas går det lättare.

Nu har väl ändå "producent" och "konsument" inom "concurrent programming" varit rätt vedertaget i alla fall sedan 1978 när Tony Hoare presenterade sitt CSP (Communicating Sequential Processes) paper?

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:

Inser hur träffsäker "telefonkatalog" ändå blir över hur jag, efter många försök att faktiskt förstå, känner kring saker som HN och andra saker kring "strukturering av kod" du nämt.

Att det är svårt och förstå stämmer absolut, det tar tid och ofta behöver utvecklare verkligen fått sitta med skitkod för att överhuvudtaget kunna förstå

Skrivet av Yoshman:

Nu har väl ändå "producent" och "konsument" inom "concurrent programming" varit rätt vedertaget i alla fall sedan 1978 när Tony Hoare presenterade sitt CSP (Communicating Sequential Processes) paper?

Det är ett förhållande man kan använda på flera områden, därav jämförelsen. Förstå vilket fokus producenten bör ha och vilket fokus konsumenten vill ha. Konsumenten vill bli serverad och det skall vara lätt, Producenten måste anstränga sig för att servera så bra som möjligt.
Måste konsumenten efterarbeta vad producenten producerat så fungerar det sämre

Permalänk
Medlem
Skrivet av klk:

Telefonboken är ett bra exempel på hur man kan hantera stora datamängder effektivt utan att behöva memorera all information. Istället räcker det att förstå det underliggande mönstret: informationen är alltid strukturerad på samma sätt på varje sida (namn, telefonnummer, adress). Detta gör att man snabbt kan hitta vad man söker efter, oavsett hur stor telefonboken är.

På samma sätt kan bra kodstrukturer hantera stora kodmängder utan att utvecklares prestanda i att hantera koden försämras. Systemet "skalar" alltså bra - det går att lägga till mer logik utan att hastigheten eller svårigheten att hantera koden påverkas nämnvärt.

För att det här skall fungera behövs språk som är flexibla nog för att kunna hitta mönster som är enkla men som också klarar att producera den logik som önskas för aktuell mjukvara. Där är överlagring mycket viktigt eftersom det går att skapa enklare kodstrukturer men som ändå har önskad logik

Givetvis är sådana här kodstrukturer mycket mer komplexa än telefonbokens struktur. Och kan man inte strukturen blir koden oläsbar, samma som en som inte lärt sig hur en telefonboks struktur fungerar även om den är lätt att lära

Telefonboksexemplet är också bra för att förstå hur lätt det är att förstöra data/kod. Att hacka in några telefonnummer i telefonboken som inte följer mönstret, hur svårt blir det inte att hitta dem?
Samma sak med kod för förstår man telfonboken så blir det lättare och förklara hur viktigt det är med att inte frångå fasta kodstrukturer.

När det gäller telefonboksexemplet kan man istället titta på hur man hittar i vilken typisk katalog som helst. I ett av mina projekt handlade det om att hålla reda på folk och vad de åstadkom, alla små detaljer som leder fram till att en arbetsuppgift i sin helhet var klar. I Systemet lagrades även en hel del annat av intresse för verksamheten.
Det väsentliga i de strukturerna var inte själva lagringen utan att "ovanpå" lagringstrukturen lades index i form av B+-träd, en indexeringsstruktur som växer och krymper med insättning och borttagning och som hela tiden hålls balanserad.
Vi använde oss av de B+-träd som fanns i Postgres, den databahanterare vi valt. Mer om B+-träd kan man läsa om på Wikipedia eller som vi gjorde, i volym 3 av "The art of Computer Programming" av Donald Knuth. För de som gillar hans böcker rekommenderas även hans bok "Concrete Mathematics: A Foundation for Computer Science" som noggrannare går igenom matematiken som används i "The art of Computer Programming".
Detta skrivet av en "Matematiker som halkat ner i dataträsket" (enligt min äldste son).
Det finns även en ganska ny sida på internet med mer lättillgänglig framställning av B-träd på: https://www.geeksforgeeks.org/dsa/introduction-of-b-tree-2/
Vi valde just B+-träd för att inte ha poster i själva trädet utan bara pekare till poster. Vi valde bort B*- och B*+-träd eftersom vi inte ville ha en extra balansering av träden för att jämna ut mellan trädets noder under pågående sökning. Vårt val kom av att vi visste att det inte skulle bli mer än c:a 20 000 personer (inklusive historiska data) och att med allt de höll på med inte skulle bli mer än några miljoner poster i databasen, kanske upp mot 15 000 000 (också inklusive historiska data).
Det viktiga var att de som använde systemet skulle ha så korta väntetider som möjligt (så snabb respons som möjligt) och att systemet skulle vara tillgängligt 24/7 och det lyckades vi med.

Permalänk
Medlem
Skrivet av serafim:

När det gäller telefonboksexemplet kan man istället titta på hur man hittar i vilken typisk katalog som helst. I ett av mina projekt handlade det om att hålla reda på folk och vad de åstadkom, alla små detaljer som leder fram till att en arbetsuppgift i sin helhet var klar. I Systemet lagrades även en hel del annat av intresse för verksamheten.

Precis och mönster kan ha många olika former eller användas vid olika typer av situationer, som du beskriver när ni skulle lagra information

Och jag tror de flesta utvecklare känner till sådant här:

Permalänk
Medlem
Skrivet av klk:

Precis och mönster kan ha många olika former eller användas vid olika typer av situationer, som du beskriver när ni skulle lagra information

Och jag tror de flesta utvecklare känner till sådant här:
<Uppladdad bildlänk>

?? Sambandet med det jag skrev ??

Vitsen i det jag skrev är att det inte är lagringen som är problemet utan indexeringen av det som finns lagrat.

Sen har jag hittat i geeksforgeeks-sidan jag refererade att man såg en nackdel i att det blir mycket läsning från disk men med de B+-träd vi använde fanns inte det problemet eftersom vi bara lagrade nyckelvärden i träden och att träden hölls i primärminne hela tiden (enstaka index kunde vid hög belastning tillfälligt hamna i virtuellt minne). Responstiderna hölls på millisek-nivå.