Remix.run Logo
mjevans a day ago

There _are_ two problems with Golang that I _would_ like to wave a magic wand and fix if that was a power I had.

1) Sum types (E.G. C/C++ union types) - Yeah, something similar to that should exist... it's syntax sugar over #2

2) 'casting' / reshaping perspective on data ; as long as something has the same struct size a programmer should be able to tell the compiler 'but this is actually that'. Which also implies a way of fixing the layout of a given data structure. I figure that's why Golang doesn't allow this already.

Yeah, 24 bytes (len, cap, pointer) per slice (dynamic array) has a cost, but if that really gets your goat use a fixed size array, or pointer/reference to such [n]thing.

3) Seriously, for a slice, make it like a map, a pointer/reference to a len,cap,blob - so that when I pass a slice by value I pass the WHOLE slice, not a COPY of len and cap and a reference to the slab. Current golang has the worst of all worlds with passing slices around, in that changes mutate, UNTIL it's resized or manually copied. The current design has the behavior it does to support slices of slices, which requires the pointer to the blob. A more complex scheme of a container behind the slice, and references to that could also work, but would be an entirely different datatype.

CharlieDigital a day ago | parent [-]

I started learning Go and when I got to the chapter on slices is when I dropped it.

I can't put my finger on why it was so off-putting, but it just left a bad taste.

mjevans a day ago | parent [-]

It's exactly what I described in point 3 as 'the problem'.

Maps 'work' because as a programmer you're aware of how expensive it is to copy a whole hash table, and it makes sense that a pointer to the thing is the whole thing. So it's an exception, but one _clean_ exception that just behaves consistently.

Slices are horrid in that they SOMETIMES work the way someone who passes by value expects, and that's the same for both NOT updating AND Updating. This is because the management stage is passed by copy, not reference, but the backing data IS a reference, which initially is copied. That leads to in-place overwrites when no change in size has happened. It leads to appends that do get written but not reflected in other copies of the slice, and then if there's a need to re-allocate it leads to even the updates not updating the other copies of the slice.

Slices are the most beginner un-friendly part of Golang.