If you want all features of language X (I doubt we will stop at generics) use language X. Stop trying to make all languages the same. I work with programmers from OO background (java) and they can't even grasp the utility of functions as value or closures. Every damn "service" has an interface/generated mock and anemic model. They're desperate waiting for generics for go to "complete". I fear the influx of OO program…
Generics enabled by default in Go tip
211–220 of 378 posts
Re: Generics enabled by default in Go tip
#212Earlier quoted context omitted.
so as an example, I've used priority queues a lot. you need them for Dijkstra.. apparently golang has a heap package which lets you push and pop `interface{}`. sure you can cast, and I guess people have to, but why couldn't Go just call `interface{}` object or any? the awkwardness of the convention suggests an unwillingness to accept failure.
Parametric polymorphism is a better fit for container types IMHO. There are some interesting notes here… In Go prior to generics, interface{} is an escape hatch less frequently needed but not necessarily much safer than void*. Post generics, interface{} is suddenly more useful and will be aliased by ‘any’. The way the std lib heap works in Go, an implementation doesn’t have to mention interface{}. Using the Go std li…
You can cast void* to anything you want. With interface{} you get a type check, either through an assertion or a panic. That is a big difference in safety.
Re: Generics enabled by default in Go tip
#213Earlier quoted context omitted.
Ok, so you like that. I myself really hated when I used float32 and had to do this when I was doing calculations: result = (float32)Max((float64)a, (float64)b) I ended up switching the type to float64, and wonder why they even offer float32 if it's practically unusable. I had similar experience when I needed to use int8 or int16 etc. An alternative was to make own version of Max/Min and other math functions, but this…
I'm not sure I follow, because Rust is also (thankfully) fussy about integer types.
Re: Generics enabled by default in Go tip
#214Not to be contrary for its sake, but I'll say this is one change I'm really not happy about. I feel like it's a change to placate many, while driving a lesser amount away. Which is fine, but still feels like the end of something, as I am one of the aforementioned 'lesser.' As for why...I love above most the simplicity and readability of Go. Any change which encroaches that, which this does, is a net negative to me.
Back when generics were introduced to Java I felt the same thing. I had been doing Java for years at that time. I had also been working for Sun, so of course I was exposed to it. I was very negative towards generics and had similar arguments as you. It didn't take long before I changed my mind. I'd never want to write Java without generics again. I'm not saying you're going to have the same experience, but I would su…
Re: Generics enabled by default in Go tip
#215Earlier quoted context omitted.
They’re the easiest stack structure to implement. All your operations are against the head of the list and you either have a thing, don’t have a thing, or add a thing. I’d like to be able to maintain a stack of things whose types I don’t have to manually reify and erase. That’s not a tall order, and it’s certainly not “complexity”. It’s markedly weird that I can’t have that same structure and associated operations be…
If you want a stack you'll just use a growable array (in Go, a slice). A linked list is suboptimal. Linked lists serve a real purpose in some situations where you really do want O(1) behavior. One example is when you are performing the operation while holding a mutex. But it's never the sort of thing where the right tool is a linked list generic container.
You can have O(1) stack with both implementations. Slice-based will be easier to follow, and will bust the cache less often (less pointer jumps).
Re: Generics enabled by default in Go tip
#216Earlier quoted context omitted.
It's not as if it's a niche problem requiring a niche solution though. The problem is "how do I write my own data structures" and to the best of my knowledge Go's answer is: copy-paste everything and edit for each concrete type, use code gen, or pay runtime cost for interfaces. All of those solutions seem more complex than just having a type parameter.
They seem more complex compared to a type parameter when you are only thinking about this narrow situation. However, generics are not limited to this narrow situation and will cause complexity far beyond what you are imagining. Having said that, I honestly don’t know if generics are a net positive or not. What I can say is that go is one of the few languages where I can jump into an arbitrary go code base and make se…
Re: Generics enabled by default in Go tip
#217Re: Generics enabled by default in Go tip
#218Earlier quoted context omitted.
No, they don't have type erasure.
Go is getting monomorphization, separate machine code for each type specialization of a generic function. I assume reflection will choose the one for the args you want to pass, or make you do that.
According to the spec:
> It's impossible for non-generic code to refer to generic code without instantiating it, so there is no reflection information for uninstantiated generic types or functions.
You won't be able to reflect a generic List or List[T] at all which… makes sense, I think? `reflect` works on values at runtime, so it necessarily works with instantiated types as you can't have a value of an un-instantiated (generic) type: what would you give to `reflect.TypeOf` which could return an uninstantiated generic type?
Re: Generics enabled by default in Go tip
#219Every HN thread about go: go is useless because it lacks generics. Go adds generics. HN thread: I don't want this. Good case study about the people drawn to comment on a topic.
If generics are a good idea for a language, then it's better to add them in version 0.01 of the language and build up from there with generics as an intrinsic part of the language and standard libraries.
No, I don't want _tacked on_ generics.
Generics are not in 2021 a "bleeding edge" feature, that _might_ be useful later. They are established and proven in ways that they were not when Java v1 or C# v1 shipped - both added generics in later releases, with associated compromises. Now, you can and should choose upfront if your language needs them, or to choose a different route. There's no need to repeat that history.
YMMV, people have different preferences in programming languages, I have always preferred strongly typed languages. Generics suit me, but pick your lane.
And if you're at version 0.01 of a language, while you're at it, look at being immutable by default, not null by default. Those things can be opt-in for when you need them.
Re: Generics enabled by default in Go tip
#220Earlier quoted context omitted.
You would use a slice as your non-associative container, and you would write a loop over it. You just wouldn't use a linked list.
And honestly, 9 times out of 10, I'm better off rebuilding the list because vectors have lower memory overhead and the memory is contiguous. But that one time... I've also been spoiled by Java's very rich set of collections.
- Option, Result, and other stuff from the standard library.
- My own B-Tree implementation w/ domain specific enhancements, in about 4 different contexts
- A heap based priority queue
- A custom 2 level vec, to support arbitrary insert & delete without shuffling elements around. (This turned out to be faster than my b-tree but less memory efficient.)
- Several different custom iterators, and iterator combinators. Eg, I have an iterator over some data which gets computed on demand. I have an iterator which consumes and run-length encodes each item in another iterator. And so on.
All of this stuff has generic type parameters everywhere. The b-tree is generic not just over the stored data, but also over the way its index works. I can specialize it to do a bunch of different tricks by just changing a type parameter.
All of this code is fancy and hence difficult to read for the uninitiated. And that isn't the Go way. But there's a big, valuable middle ground here. I'm glad Go is adding some options to let people lean a little bit into cleverer code when it becomes appropriate for the problem domain. Emulating generics with interface{} seems worse than just adding generics into the language.