9 ms·
I'm glad I'm not the only one sad to see generics invading a perfectly good language. Programmers love generics because they enable higher-order abstractions,
by nemo1618 8y ago
I'm glad I'm not the only one sad to see generics invading a perfectly good language.
Programmers love generics because they enable higher-order abstractions, and programmers love abstractions -- code that isn't DRY is like an itch we need to scratch. Programmers also hate special cases, because they feel restrictive and inconsistent: I recall quite a few people protesting that Go's 'range' keyword shouldn't be restricted to a handful of built-in types, but rather should support any type implementing an Iterator interface.
But Go was not designed to be perfectly consistent or to enable high-order abstractions. It just aims to be productive at scale, and that often means restricting the programmer. Go tries to be non-magical, and sadly that can take much of the whimsy out of programming. You can't chain together operators in point-free style, or add a property to every 'Object', or directly increment a string, or anything like that. In other words, it's a terrible language for code golfing. But that sort of code has no place in a production environment anyway. It's "clever" code that gives the programmer a little dopamine hit when he writes it, and his co-workers a headache three months later. Those are misaligned incentives.
So I worry about generics because they let you abstract with wild abandon. They let you inject a little magic. And I fear that programmers will be seduced by their love of magic, and I'll be the one who ends up paying the price.
- hyeomans 8y agoThis. Worked with large C# code bases that were full of leaky abstractions using generics. Programmers thought of ever edge case, until you found that edge case that wasn’t covered in the long chain of inheritance of generics. Point being, I agree with you, I know Go doesn’t have inheritance like C# but I’m pretty sure we, as a community, we’ll find a way to complicate everything Go related.
- hcs 8y agoConcur, I scratch the golfing itch with Zachtronics games.
- glangdale 8y agoI think this argument needs to be treated with caution. I think it's possible to write bad code on top of almost any mechanism. Certainly I've seen my share of bizarre C++ template shenanigans (bad) but I've also been able to reuse other people's really well written container classes rather than roll my own, all with strong type safety (good). Everyone will make their own decisions about generics. Personally I find the risk of "bad generics magic" to be more tolerable than "endless shitty workarounds for not having generics".
- civility 8y agoWriting the exact same code for float and double (and possibly complex float and/or complex double) sucks. You've created some straw man about dopamine junky programmers because you don't need generics for whatever it is you do. If you wrote numerical algorithms you'd be annoyed at any language which lacks generics.
- zimbatm 8y agoMaybe that's the issue. From what I have seen, the lack of generics mainly becomes painful when working in the numerical space. If I work on mapping JSON, doing APIs and CLIs I don't really need generics. If I work on algorithms and data bags then it starts to be annoying re-implementing the same thing over and over again. So in these discussion you have devops-type people mainly dealing with APIs that are perfectly content. And the ones that work with algorithms are talking past them because they don't experience the same pain. Instead of changing the language to enable generics everywhere, maybe there is a lighter version that exists that only applies to numerical problems. Is it possible that a boxed "Number" type would solve most of the problems?
- phamilton 8y ago> mapping JSON I find that an ideal set of tools allow us to describe our task and write our code using the same idioms. The fact that "mapping JSON" doesn't actually involve calling "map" on JSON data is a great example of why not having generics in golang is frustrating for me.
- zimbatm 8y agoI forgot the 3rd category, those who see the world exclusively through the functional programmer lens :-D Mapping functionally it worth it if the transformation between A and B is regular enough. But things are dirty. Some irregularities appear and now the perfect higher-order function doesn't work nicely anymore. With the imperative approach it just means adding 1 -3 more lines.
- civility 8y ago
- dragonwriter 8y ago> Programmers love generics because they enable higher-order abstractions, and programmers love abstractions Right, because the alternative to higher-order abstractions is spending much of your time completing MadLibs-style implementation templates for solutions to solved problems instead of just including the library that contains the (higher-order) solution and focussing on solving the new part of the your problem.
- jules 8y agoThis is the same argument that gets brought up for every language feature. I remember the days when lambdas were controversial. Lambdas used to be seen as crazy complicated magic that normal programmers wouldn't be able to understand, or would abuse to make code unreadable, or would make a language unnecessarily complicated. This side of the argument eventually loses. People get used to new language features and as it turns out they are not as complicated as people initially think. At the end of the day it's nice to be able to write a generic collection.
- baby 8y agoSame here, as a security consultant reading Golang is always a pleasure. I'm pretty sure that the strongest codebases I've seen were in Golang just because of how easy it is for everyone to read the code and actually spend time looking for logic bugs instead of trying to understand what is happening. Developers love to be able to write their magical code and their clever abstractions and often forget that their code is paying the price by becoming less clear and less readable. From a security perspective that's a huge loss. I know that people with the right security mindset will do the right thing, and have more code where it improves clarity, or have slower code when it makes it easier to understand what is being done. But unfortunately that's a tiny minority of developers.
- zoul 8y agoDevelopers love to be able to write their magical code and their clever abstractions and often forget that their code is paying the price by becoming less clear and less readable. Are you saying that it has to be that way with generics? Because I would disagree with that. Cautiously applied, generics can make your code more clear, more readable and, most importantly, more type safe – and not just because of containers, see Swift’s key paths for an example.
- baby 8y agoYes it will be this way for MOST usages with a minor subsets of codebases which will benefit from them.
- vmchale 8y ago> Developers love to be able to write their magical code and their clever abstractions and often forget that their code is paying the price by becoming less clear and less readable. Clearly, that justifies the fact that you can't sort an array of doubles and an array of floats with the same function.
- baby 8y agoDoes it not? That’s the entire point of my comment. Some stuff are going to be painful but overall the lack of generics is a blessing.
- mort96 8y agoI'm curious, what's a better solution for generics if you want some kind of container which doesn't need to care what type it contains? Is the better solution to just use the current C-style void* s everywhere and manually cast your objects to and from void* (or in Go's case, interface{}), leaving type safety to the programmer? Or is the argument that people shouldn't need to write containers, and all necessary container types should be a part of the standard library and impossible to re-implement using regular Go code? Or is code generation a good enough solution? Or are there other, nicer solutions to enable generic container types which can't be abused like Java-style generics can be? I don't particularly care which direction Go goes in, and don't write a lot of it myself, but I'm very curious what the alternative is.
- everybodyknows 8y agoCode generation by means of Go's standard template library has worked nicely for me. Best of all, gdb sees the concrete type, so value inspection stays easy. Only snag, minor enough, is that emacs auto-indent becomes confused by the double braces, as in "{{.templateVar}}".
- everybodyknows 8y agoI've learned to be wary of the interface type. Although the run-time overhead is negligible anywhere outside tight loops, induced debugger overhead can become a misery.
- nemo1618 8y agoI've been writing Go for five years and I've never had a pressing need to create my own generic container type. The built-in types -- arrays, slices, maps, and channels, or some composition of them -- have proved sufficient. When I do need a new type of container, it either ends up being specialized for a specific type, or it accepts generic types via interface. Like, I need a red-black tree for this one algorithm, but do I really need a generic red-black tree that can handle any type? The answer is almost always no. I'm fine with Go having a handful of built-in generic containers+functions. In fact, I think most people asking for "generics" would have their true needs met by adding a few more built-ins to the language. I pursued that idea here: https://github.com/lukechampine/ply https://github.com/lukechampine/ply I sympathize with the programmers who really do need generics and would like to program in Go, because I love the language. But the way I see it, 95%+ of programs don't truly need generics. I like the trade-off Go makes by omitting generics, and it makes me sad that the language could change in such a radical way to meet the needs of that <5%. A language doesn't need to be perfect (or even usable) for everyone! Throwing in feature after feature to satisfy everyone just creates a culture of compromise and destroys a language's character. I want a set of narrow tools that I can master. No one ever complained that a hammer makes a terrible paintbrush. So in a broader sense I think this whole discussion reflects a wider need for good languages. We need ten languages of Go's caliber! I know the "just use a different language" argument is kinda callous, but the alternative feels worse.
- int_19h 8y agoI don't get this idea why generics are perceived as some kind of a fad that's opposite to pragmatic coding practices. I mean, they were in the original (1983) Ada - hardly a language known for its cowboy attitude, general laxity, or "clever code".
- vmchale 8y ago> I worry about generics because they let you abstract with wild abandon. They let you inject a little magic. Not really. > You can't chain together operators in point-free style, or add a property to every 'Object', or directly increment a string, or anything like that. In other words, it's a terrible language for code golfing. But that sort of code has no place in a production environment anyway. Complete straw man.
- piano 8y ago> Go tries to be non-magical, and sadly that can take much of the whimsy out of programming. That's a weird thing to say seeing that Go very much is magical... Slices/arrays are magical and so are maps, channels and channel operators, the make() function and a whole bunch of other features. I think your understanding is filpped. Generics are not a way to add magic, they remove magic. That's the whole point. Unfortunatelly, that which one doesn't understand may seem like magic to them even though it's not. For example, compare a channel implementation in Go and Rust. In Go, the whole thing is pretty much magic. In Rust, it's just another struct that the compiler treats in no special way. Getting familiar with the magic of Go channels is only good for working with Go channels, the knowledge is not applicable for any other part of the language nor other languages. Learning generics on the other hand gives you better understanding of numerous features in multiple languages.