Earlier quoted context omitted.
This is misleading enough it's a lie; to do this you need to use a function named `unsafe.Pointer` with a type named `reflect.StringHeader`, not just `[]byte` and `string`.
It means there is special protection for string-data that is not available to anything else, and that library-authors get panic reports about immutable byte slices. To that degree, it's something that the specialized type exposes you to but the type system does not adequately protect or signal. But yes, AFAIK this requires use of `unsafe`. Which does change things, and puts the blame for misuse squarely on the immuta…
a[low:high:max] in Golang – A Rare Slice Trick
71–80 of 131 posts
Re: a[low:high:max] in Golang – A Rare Slice Trick
#72Earlier quoted context omitted.
This is a pretty good vignette of how Go is designed. "Users don't need this feature (immutability, polymorphism, etc.), let's not include it. Ah crap, turns out we actually need it for a core language feature. Is there a lesson we can take away here? Nah, just make an ad-hoc implementation of the functionality in this one place."
For what it’s worth it sounds no worse than Java: you have immutable strings but you have no way to enforce that you can’t modify something that you have recieved, which is why the underlying char array for a string has to be defensively copied if the user asks for `asArray()` or whatever it is. Strings being immutable doesn’t seem like a special case, though. The underlying mutable array is just encapsulated, which…
Re: a[low:high:max] in Golang – A Rare Slice Trick
#73Re: a[low:high:max] in Golang – A Rare Slice Trick
#74Earlier quoted context omitted.
But also strings are actually immutable sometimes (at the very least when hardcoded), and they can be converted to a `[]byte` slice that looks mutable, but panics when modified. AFAIK no other slice-like data in Go behaves like this. Fun!
This is a pretty good vignette of how Go is designed. "Users don't need this feature (immutability, polymorphism, etc.), let's not include it. Ah crap, turns out we actually need it for a core language feature. Is there a lesson we can take away here? Nah, just make an ad-hoc implementation of the functionality in this one place."
[^1]: Someone is going to come in with some rant about how big a “hello world” binary is compared to C, as if this is emblematic of some real-world use case.
Re: a[low:high:max] in Golang – A Rare Slice Trick
#75Earlier quoted context omitted.
I don’t think you can fairly call go’s generics an “ad-hoc” implementation. They added syntax for it.
I think in this context "ad hoc" refers to the context in which that syntax was added. IIRC the original creators were against generics ever being added to Golang, so they wouldn't have thought about their eventual introduction when choosing Go's initial syntax. The result is that the generics that eventually were added feel awkward and "bolted on" to many people. (I don't have any strong opinions on it personally, b…
Go generics are exceptionally well designed.
The reason it took so long for Go to get generics is because Go designers took their time to arrive at a design that fits with the rest of Go.
It's not rushed, it's not "bolted on".
They did several designs that they rejected before they accepted the design that got implemented.
Re: a[low:high:max] in Golang – A Rare Slice Trick
#76Earlier quoted context omitted.
I don’t think you can fairly call go’s generics an “ad-hoc” implementation. They added syntax for it.
I think in this context "ad hoc" refers to the context in which that syntax was added. IIRC the original creators were against generics ever being added to Golang, so they wouldn't have thought about their eventual introduction when choosing Go's initial syntax. The result is that the generics that eventually were added feel awkward and "bolted on" to many people. (I don't have any strong opinions on it personally, b…
Re: a[low:high:max] in Golang – A Rare Slice Trick
#77Earlier quoted context omitted.
I coincidentally was just looking at some docs, and I think I have a handle on it (to it?:) now. The specific strange design decision in Go is that you can create a child slice that has its own starting offset and length, but may or may not inherit its parent’s capacity. Just because it’s well-defined doesn’t mean it isn’t tricky. Even if you kept the semantics the same but made cap=len for subslices by default, sure…
cap==len is effectively the default - most slicing is done with [start:end], not [start:end:additional-cap]
After slicing the array a
a := [5]int{1, 2, 3, 4, 5}
s := a[1:4]
the slice s has type []int, length 3, capacity 4
Many of us here are arguing that the default should be cap==len==3, but it’s not, it’s 4.
Re: a[low:high:max] in Golang – A Rare Slice Trick
#78why do people write articles about go features? when PHP was in its prime, almost nobody wrote blogs explaining how they found some philosophy in PHP. there's a reason for that. when you see someone open their article explaining a language feature by talking of the implementation details or specific use cases, that's a language smell (of course all industrial PLs stink). ironically go is the only post 80s language th…
Concurrent access does let you hit some 'fun' behavior, but you have to be doing pretty dumb things to hit them. And while the implementation may be able to save you from something like that, such things would likely bubble up elsewhere(disk i/o, network i/o, etc) if doing that kind of thing.
Re: a[low:high:max] in Golang – A Rare Slice Trick
#79why do people write articles about go features? when PHP was in its prime, almost nobody wrote blogs explaining how they found some philosophy in PHP. there's a reason for that. when you see someone open their article explaining a language feature by talking of the implementation details or specific use cases, that's a language smell (of course all industrial PLs stink). ironically go is the only post 80s language th…
The best part of Go is that there is very little magic in Go. If you understand that slices are just fat pointers implemented as a built-in, there is nothing confusing about them. I can understand every part of a Go program, all the way down to the language syntax that generate assembly. I don't have to be afraid of or be mystified by any language feature, because 1) there are few, 2) they are just programs implementable in Go. This does not happen with many languages.
Longer version:
Go didn't need to add slices as a language feature (it could have been a library function of containers, as fat pointers are not a new thing), but having it in the language makes using them easy. And not having generics at the start sort of forced their hand.
And as slices are just fat pointers to an underlying array, obviously it's not multi-thread safe.
So if you understand that slices are just C-style structs with pointer to data, a length counter and a capacity counter, then nothing in your example code is surprising. There is no hidden memory copy, no hidden synchronization lock to make it thread safe. And Go's a = append(a, item) now makes sense, because if 'a' grew in size, append would have to create a new underlying array, and a new slice struct with a pointer to new data. To me, it's much easier to reason about what the code is doing than other languages with Array types.
> nobody would ever design something like this without massive cognitive dissonance
Somebody did, without any cognitive dissonance. And I like it :)
> just copy and modify the previous industrial PL, C in this case
Go really wanted to be "A Better C". The language is not much larger than C, removed a bunch of C foot-guns, and it's as capable as Java, if not a bit more. I think the compromises Go made were well considered compared to other C family of languages.
Re: a[low:high:max] in Golang – A Rare Slice Trick
#80Earlier quoted context omitted.
I think in this context "ad hoc" refers to the context in which that syntax was added. IIRC the original creators were against generics ever being added to Golang, so they wouldn't have thought about their eventual introduction when choosing Go's initial syntax. The result is that the generics that eventually were added feel awkward and "bolted on" to many people. (I don't have any strong opinions on it personally, b…
Maybe you shouldn't play game of telephone like that. Go generics are exceptionally well designed. The reason it took so long for Go to get generics is because Go designers took their time to arrive at a design that fits with the rest of Go. It's not rushed, it's not "bolted on". They did several designs that they rejected before they accepted the design that got implemented.
Go's maintainers had to be beaten into bolting on a poorly-done implementation of polymorphism over like a decade. I can't imagine anyone who's used any language with polymorphism baked in to the design describing Go's implementation as "exceptionally well designed". If this is a Poe's law thing and you're just joking, then you got me.