Earlier quoted context omitted.
> isn't generic Sets easily implemented with map being already generic? Since Go has neither generic functions nor generic typedefs you can't implement a Set with a generic key type on top of map, you have to reimplement all the set operations for each key type you use.
I think map[T]bool is already a pretty good set; the only things you can do with sets are insertion, deletion, iteration and checking for existence and they're all well-supported. Of course, if you need a concurrent set you're right back in type system hell.
A Proposal for Adding Generics to Go
221–230 of 273 posts
Re: A Proposal for Adding Generics to Go
#222Earlier quoted context omitted.
I remember thinking something similar about my Java 1.4 codebase back in the early 2000s. It's fine, right? What could I be missing? The answer is: A lot.
Yeah that's ok until you have 20 million lines of generic ridden crapola pumped out by the lowest bidder. That's the hell I spent a good chunk of the last few years untangling on the C# front. Let's model this correctly! Oh no someone said fuck it, lets just use a bunch of generic data types! Dictionary >>, SortedSet >>> Several thousand out of bounds, missing keys, null reference exceptions, hash collisions and the…
Re: A Proposal for Adding Generics to Go
#223Earlier quoted context omitted.
I think the idea is that these fundamentals could/should be supplied by the standard library Ironically, despite all their differences, Rust actually has a similar situation: it's really hard to write the fundamental data-structures in Rust, so they've put a focus on having really good standard-library implementations and people are generally content using those (in Rust's case it's because the borrow-checker makes p…
They kind of did this with maps and slices except that they baked them right into the language instead of the standard library. Like, map is a keyword. The standard library doesn't have many data structures at all because, well, without generics they're not very useful. There's a few things like a linked list and a thread-safe map that accept interface{} types but then you're basically throwing the type system out th…
Re: A Proposal for Adding Generics to Go
#224Earlier quoted context omitted.
A successor to C with mandatory garbage collection? Sorry, it's a wrong ballpark.
Once upon a time, C was a general purpose programming language--it wasn't always exclusively performance critical systems programming. Anyway, in practice you can use arenas or other techniques to alleviate GC pressure. In my experience, the GC isn't a big performance issue; rather, the Go compiler doesn't optimize as aggressively as the C compiler.
Re: A Proposal for Adding Generics to Go
#225Earlier quoted context omitted.
Shallow wrappers that don't wrap much (now) but convey intent better are valuable if you buy into the idea of modularity and encapsulation in general. Some reasons (probably more out there): 1. The now-provided interface can more clearly express what the code is intending to do (better names for the operations you're providing than the underlying system has, remove_from_end to pop or dequeue ) 2. Hide methods of inte…
Wrapping to hide is valuable, but wrapping has a cost which is generally underrated. Every wrapper is a thing itself which must also be understood when trying to understand how things work. And every wrapper is a division between blocks of code, meaning if you have changes which impact multiple layers of wrap, its harder to determine what to change, and to maintain the understandability of each layer. For this reason…
I'd offer a different view. Wrapping/abstracting like this should reduce the amount of things a user of the abstraction needs to know. I don't care how Java's BigInteger class works under the hood, only that it does what I need it to do. If I did have to know how it worked to use it, this suggests a failure on the part of whoever created it.
It does increase what the maintainer of the underlying system (including the abstraction) needs to know, but if done in a sane manner this should not be a burden. So we're making a tradeoff. The user gets something simpler, the underlying system maintainer gets something a bit more complex. Or the user gets something more complex and with more boilerplate but the underlying system maintainer gets something simpler (though will be pestered with, "Why don't you offer a generic set yet?" asked for years to come).
> meaning if you have changes which impact multiple layers of wrap, its harder to determine what to change, and to maintain the understandability of each layer.
When this happens, in my experience, it has meant one or more of:
1. The choice of how to wrap/abstract was poorly chosen
2. The choice was made too early (before the problem was properly understood)
3. A major change was made that would've been hard to identify/plan for earlier
I ignore (3) when writing code beyond what's reasonable to plan for. (1) and (2) though mean I mostly agree with this:
> Create an abstraction at the last moment
But rephrased, borrowing the phrase I first saw in some Lean Software book, "last responsible moment." It's not sensible, for instance, to use a map to booleans as a set throughout the project's life and only wrap it at the last moment. If you know it's going to be a set, wrap it early because this offers clarity to your code and reduces boilerplate/noise. If you know you need a stack, and have a vector available, wrap it and hide the random access option. If it later turns out that you also want random access, you can offer it, but if it's been available from the start then users will have abused that and you won't be able to rein it in later (without a lot of effort and heartache).
Re: A Proposal for Adding Generics to Go
#226Earlier quoted context omitted.
It seems to me like generics are extremely important for "library code", and not super important for "application code" (and in fact they can sometimes create more confusion than they're worth in the latter context). Go also seems like a language that thrives in smaller-scale, application-focused contexts (microservices being the obvious example). So in this light, and with the basic generic data structures supplied…
> It seems to me like generics are extremely important for "library code", and not super important for "application code" I find that it really depends a lot on the language you're working in, and how well it does generics. In Java, I don't use generics much beyond collections, streams, stuff like that. Whenever I try, I tend to trip over its relatively limited implementation of the concept. In a language like F#, on…
I've gotten use out of generics in "application code", but I've also been bewildered by overly-complex generics-within-generics-within-generics written by other people in application code. It's hard to be conclusive, but I wouldn't be surprised if they've done more harm than good across application contexts.
Re: A Proposal for Adding Generics to Go
#227Earlier quoted context omitted.
Wrapping to hide is valuable, but wrapping has a cost which is generally underrated. Every wrapper is a thing itself which must also be understood when trying to understand how things work. And every wrapper is a division between blocks of code, meaning if you have changes which impact multiple layers of wrap, its harder to determine what to change, and to maintain the understandability of each layer. For this reason…
> Every wrapper is a thing itself which must also be understood when trying to understand how things work. I'd offer a different view. Wrapping/abstracting like this should reduce the amount of things a user of the abstraction needs to know. I don't care how Java's BigInteger class works under the hood, only that it does what I need it to do. If I did have to know how it worked to use it, this suggests a failure on t…
Re: A Proposal for Adding Generics to Go
#228Earlier quoted context omitted.
> It seems to me like generics are extremely important for "library code", and not super important for "application code" I find that it really depends a lot on the language you're working in, and how well it does generics. In Java, I don't use generics much beyond collections, streams, stuff like that. Whenever I try, I tend to trip over its relatively limited implementation of the concept. In a language like F#, on…
Whether you find yourself using them and whether they're actually necessary are two different things :) I've gotten use out of generics in "application code", but I've also been bewildered by overly-complex generics-within-generics-within-generics written by other people in application code. It's hard to be conclusive, but I wouldn't be surprised if they've done more harm than good across application contexts.
To me, that's a shining example of the problems I've run myself into when trying to squeeze much power out of Java-style generics. I never seem to encounter similar problems in F#. Scala, it depends on how successful I am at not losing a boot in the mud.
Generic programming was born in a language whose other pioneering features were algebraic data types and an HM type system. I've never really seen a first-rate example of one that didn't come paired with at least passable examples of the others.
Re: A Proposal for Adding Generics to Go
#229Finally. Hope it gets approved. It's strange that they don't consider Print[T](x T) instead of Print[T any](t T). The "any" could just be omitted without loss of anything. Especially since repeated types with the same constraints indeed DO omit it! Print2[T1, T2 any]
The question of what the syntax should look like has been beaten to death.
Re: A Proposal for Adding Generics to Go
#230Earlier quoted context omitted.
I was exaggerating there I admit, mostly because I can't post some of the hell I've seen without breaking contracts. The worst example I've seen was a completely generic data type specified abstract syntax tree. I spent a couple of weeks rewriting that using concrete types and managed to find and fix tens of trivial bugs caused entirely by the design. The point is really that it's hard to reason about such things and…
The sufficiently stupid-but-hard-working programmer can write crap code in any language. The actually-useful question is whether the language gives competent programmers enough rope to build whatever they're trying to build.