5 ms·
I know Go gets a lot of heat for not having generics, but having done a few fairly complex things in Go now, I really haven't missed them, nor have I had to bai
by nicpottier 9y ago
I know Go gets a lot of heat for not having generics, but having done a few fairly complex things in Go now, I really haven't missed them, nor have I had to bail out to interface{} in ways that I wouldn't have had to in other languages.
The main reason for that is that golang lists and maps CAN be typed and while they aren't perfect, they are pretty darn great for most use cases. Certainly I understand some people have the need for specialized data structures, but I wonder how often a project needs that data structure to be totally generic, as opposed to just doing the work to implement it (yes even perhaps copy/pasting some other implementation) and moving on. That's ugly yes, but it just isn't that big a deal in my experience.
In any case, the gains from having a great runtime that compiles to a binary, an excellent standard library and awesome concurrency primitives far outweigh the negatives for me. Really enjoy Go.
- pjmlp 9y agoI can have a great runtime, with static linking support in many other languages. The sync.Map in Go 1.9 is yet another example of the price to pay for lacking generics.
- pdimitar 9y agoWhat price are you talking about? They're adding a map that offers a bit more leeway when working with it from several goroutines, is all I am seeing without thinking extensively about it.
- pjmlp 9y agoAbandoning type safety with interface{} for keys and values. I was doing that with Turbo Pascal 6.0 and Borland C++ 2.x for MS-DOS with Turbo Vision and TObject as interface{} in 1993.
- nicpottier 9y agoSo what's your complaint? That you want a synchronized map? Then write a two line function that wraps your native golang typed mapped with sync.Mutex and be done with it. If you are sharing a map in this way across many goroutines you are probably "doing it wrong" in go anyways.
- pjmlp 9y agoThat is how I used to code in the old days, still on MS-DOS, we are way past those basic type systems.
- pdimitar 9y agoI can see your point but you're generalizing a bit. For many people they work, for many others they don't. The old and the new type systems both have their place and use-cases.
- TheDong 9y agoThe new type system is a superset of the older ones. You can still write your own specialized error-prone repetitive containers for each and every type by hand. Yet, once a language has generics, people don't use the old way even though it's still possible to. Perhaps that's because it has no place when there's a replacement which is less error-prone, less repetitive, more usable, and can be implemented once in a library and used forever.
- pdimitar 9y agoI don't disagree. The risk is there. It's just that for me and others in this thread it's at an acceptable level. Outside of that, agreed.
- ngrilly 9y ago> Then write a two line function that wraps your native golang typed mapped with sync.Mutex and be done with it. Two lines? I think you underestimate what's going on in sync.Map: https://github.com/golang/go/blob/master/src/sync/map.go https://github.com/golang/go/blob/master/src/sync/map.go
- xyzzy_plugh 9y agoI find Go is quite similar to C, and C also lacks all of these features. It's rare to see C code using some library for generic containers. Most developers roll their own, as needed. In practice, bugs and safety aside, this tends to work swimmingly. Look at Redis, or git, or postgresql, or the many other projects getting by just fine without generics. While I agree, and believe generics offer unparalleled power, they often aren't remotely necessary. If anything, their presence creates a tendency to over-use them, resulting in even greater complexity.
- pjmlp 9y agoI was able to write software since 1980's until 1994, without a single line of generics in whatever language I had to use, until I got the first Borland C++ compiler with support for the early templates draft. It is still possible to travel by horse, yet people have moved on to better solutions.
- microtherion 9y agoHaving lived through that time as well, maybe the most painful period of that was toward the end, when we I was trying to use macro-based generic containers from the Rogue Wave Tools.h++ library. Frankly, early templates based C++ code was not all that great either. It was the introduction of the STL that made a huge difference in the usefulness of templates.
- pjmlp 9y agoThat is what go generate reminds me, the macros that Borland had on Borland C++ 2.0 for MS-DOS, on their collection classes (BIDS), before they added templates support with 3.0.
- pcwalton 9y agoNo, it doesn't work swimmingly. All of those projects have ended up either using void∗ or macros, or both, in order to roll their own generic data structures. > Look at Redis, https://github.com/antirez/redis/blob/unstable/src/adlist.h https://github.com/antirez/redis/blob/unstable/src/adlist.h — generic doubly-linked list with void∗ https://github.com/antirez/redis/blob/unstable/src/dict.h https://github.com/antirez/redis/blob/unstable/src/dict.h — generic hash table with void∗ > or git https://github.com/git/git/blob/master/hashmap.h https://github.com/git/git/blob/master/hashmap.h — generic hash table with void∗ https://github.com/git/git/blob/master/list.h https://github.com/git/git/blob/master/list.h — generic doubly linked list implemented with macros > or postgresql https://github.com/postgres/postgres/blob/master/src/include/lib/ilist.h https://github.com/postgres/postgres/blob/master/src/include... — generic doubly linked list implemented with macros https://github.com/postgres/postgres/blob/master/src/include/lib/rbtree.h https://github.com/postgres/postgres/blob/master/src/include... — generic red-black tree with void∗
- omaranto 9y agoOne thing that annoyed me when I looked at Go years ago was that it seemed like strings where basically the only data type of unlimited size that was supported as map keys. I think that only types for which equality is defined in the language could be used as keys. Those types where numbers, characters and all other "small" fixed-size types, structs all of those members had equality defined, arrays of a type with equality, and strings. The size of an array is part of the type, so in that list of types with equality the only source of unlimited sizedness are strings. I guess that cover most cases where you want a type of unknown size as a key, but I found it pretty annoying. If you want to use, say, polynomials with integer coefficients as keys in a map, you'd have to either choose a fixed maximum size (degree, for example, or number of monomials) for the polynomials or convert back and forth between strings. It's not the only language that forces you to convert things to strings and back for use as map keys (AWK and Lua come to mind), but I wish it didn't have that limitation.
- deleted 9y ago[deleted]