Skrivet av orp:
Om jag förstått det rätt så erbjuder Rust enbart språkkoncepten för lättviktiga processer men vill inte påtvinga utvecklare en runtime, därför har man valt att lägga det utanför. Det är väl därför implementationer som tokio används flitigt.
Jag kom från Erlang när jag började med Go och jag blev ganska besviken med concurrency-implementationen. Jag tycker att den påminner alldeles för mycket om pthreads med channels (spawn, join(mha waitgroup), select).
Jag råkade göra ett misstag tidigt där jag satt fel riktning på en channel som resulterade i att applikationen frös. Kompilatorn klagade inte och jag kunde inte hitta felet med varken race detection eller debuggern. Jag tycka att man borde fått en kompilator varning eller något.
I övrigt så är Go väldigt lätt att komma igång med och jag upplever mig själv som väldigt produktiv. Jag tycker att Go utmanar Python en del. Jag har för vana att skriva funktionstester i Python med pytest men jag upplever att dom skalar dåligt(lång exekveringstid). Min plan framöver är att växla till Go's testing.
Har förstått det på samma sätt . Vet hur mycket man planerar lägga in i språket kring async, finns ju fördelar med att hålla saker som bibliotek.
Tokio gör väl ungefär ett så bra jobb man kan göra givet förutsättningarna, d.v.s. att man i grunden har just OS-level trådar man jobbar med (så samma som async i C++, C# etc). Det fungerar inte att ha massiv mängd OS-trådar, varken schemaläggningen eller mängden minnen gör det realistiskt att hantera 10-tusen och än mindre 100-tusentals trådar.
Problemet med async/await modellen är att den leder till system som är exceptionellt svåra att förstå (d.v.s. förstå runtime beteendet) och därmed debugga. Rent prestandamässigt fungerar tekniken, den är bara väldigt svårt att debugga. Använde just Tokio i det lite större Rust projekt jag jobbat med, det var väl den mindre trevliga upplevelsen av Rust (fanns andra delar / processer i det projektet som tack och lov inte körde async).
Det som är unikt med Go (och som jag förstår det även Erlang, har bara gjort småsaker i Erlang + läst en del om implementation) är att stacken kan växa dynamiskt (vilket inte är möjligt i C, C++, C#, Java, Python, Rust, etc). De flesta tasks (Go-rutiner / Erlang processer) kommer klara sig med en stack på bara några 100-tals bytes, så är minnesmässigt inga problem att ha 100-tusentals sådana!
Kan inte detaljerna kring hur Erlang schemalägger sina processer (i alla fall inte på den nivå jag satt mig in i Go:s modell). Go har även här en modell som utan problem hantera 100-tusentals "go-rutiner". Något som är helt orealistiskt med pthreads (även om man hade tillräckligt med RAM skulle prestanda bli horribel).
Dessa två saker sammantaget: man slipper hålla på med "asyn/overlapped I/O" som gör det svårt att riktigt se vad som händer. Istället kan man köra helt vanlig blockade I/O i dessa taskar (vilket i debuggern också gör saken enkel då varje go-routine/erlang-process har en egen call-stack, inte en kompilatorgenererad tillståndsmaskin som är fallet för async/await).
Det är en (av flera) killer-app för Go/Erlang.
Killer-app för C och C++ är idag mängden programvara/bibliotek som redan finns och är skrivet i dessa språk. C har också att det är "standarden" för egentligen allt annat när man kommunicerar mellan olika språk/ramverk. Sen är ju C och C++ möjliga att skriva riktigt snabba program i, dock inte fundamental snabbare än t.ex. Rust och Fortran (och inte långt efter kommer Swift, Go, Java, m.fl).
Skrivet av kaimor:
Tänk Fortran då som har funnits i över 60 år. Det har förenklats och ändrats en hel del genom åren men används fortfarande. Snacka om seglivat.
Har bara läst Fortran-kod, aldrig skrivit något. Men även här finns ju en "killer-app". Semantiken hos Fortran gör det långt enklare/effektivare att utnyttja SIMD-instruktioner för saker som matris-operationer jämfört med C/C++.
Så Fortran kan vara klart snabbare än C/C++ för vissa områden, områden som är tillräckligt viktiga/vanliga för att Fortran ska kunna leva vidare. Finns ju lite varianter av C/C++ som kommer runt problemet, Nvidias CUDA är en, Intels ISPC är en annan. Dessa är ändå inte C eller C++, de är bara "C/C++-like".
Varken CUDA eller ISPC ersätter C eller C++, det är inte alls tanken. Utan de hanterar bara en rätt specifik nisch, det långt bättre/mer effektivt än vad som är möjligt i C eller C++.
Någon som har lite insikt i hur pass väl "ren" Fortran fungerar för att ge riktigt bra SIMD-kod via en kompilator? Vet egentligen inte mer än att Fortran hanterar just detta klart bättre än C och C++.