> pointers make such a mess, but are neccessary ikr! I've shot myself with pointers and nil interfaces countless times. I try to write in a more pure functional style to be more aware of pointers and mutability but Go is really designed with interfaces in mind. So it's always easier to put state inside a struct and attach methods to it. Makes extending and refactoring very easy, but it also leads to more pointer receivers and heap allocs. Oh yeah the heap! Wish it was easier to deduce if a var will escape to the heap. Just read a good article about it, but it's never straight forward: https://medium.com/eureka-engineering/understanding-allocations-in-go-stack-heap-memory-9a2631b5035d The modules are very powerful if you're the downstream and upstream follows strict SemVer. I understand the need. The things I have headaches around is the change in behavior from v0 to v1 and the change in import path with every major version bump. But I have very few grumps about Go as a whole and continue to love using it day to day. > odin looks interesting but i'm too committed to Go tbh That's why it caught my eye. I've been programming in Go almost exclusively for almost a decade. Odin has taken a lot of the good ideas and lessons of Go and has some really nice ergonomics like the explicit context, or_return operator and really the best error handling I've seen so far. Even the package names they use are sometimes the same as in go's stdlib, so it's very easy for a gopher to read odin once you know the small syntax changes. Look at the hello world: ```odin package main import "core:fmt" main :: proc() { fmt.println("Hellope!") } ```
there was a nice language called V but to be honest it was a bit too close to Rust in it's base principles and syntax i actually proposed an extension of the return syntax to allow it to be used to directly break out in error condition but i forget reasons ian lance taylor said nein i personally have very few problems with managing state and pointers anymore for the type of thing you describe - it just takes a little experience to know - most of the time you want to use a mutex, sometimes an atomic is better when it's just a single value the issue of values escaping to the heap is a pretty pesty one, but only really matters in so much as if your code might suffer from the STW GC pause that happens when it has to be reorganised or allocated in the first place for sure, if at all possible you try to accurately allocate slice capacities when you make new slices, and for those situations when you have a lot of memory being rewritten, new data stored and old data quickly forgotten about yeah, this is the one annoying thing, you really have to do freelists sometimes and you really need to be careful about allocating memory for things in go, it's too easy to just forget and wind up blowing the stack and bloating the heap and having GC pauses and that's just not ok if you are trying to keep latency down honestly, all things considered these are small inconveniences compared to the memory hell of C or the OOP hell and compile time of C++ or the fucking smarmy attitude of "wustatshins" god i hate rust god i hate mozilla *breathe*
ah yeah, also, don't do pure functional... pass by value is ok for small things but it quickly blows out into a data copy problem and when the data contains pointers as well, then you have knotty puzzles for the GC to deal with as well there's a reason why the two languages that are most notorious for blowing up your memory and dying due to OOM are C++ and Haskell, one is nasty OOP/template/variant syntax disambiguation, and haskell is constantly copying memory instead of allowing it to be mutated neither approach are optimal for the hardware, you'll get better at knowing what approach to use with problems as you solve more problems :D don't worry! and do always keep reading those good texts about internals like memory management, that's really important shit, i probably need to do more of this kind of study but i did a lot over the years already