DEV Community

Cover image for Go Luddites
David Wickes
David Wickes

Posted on

Go Luddites

The proposal for generics in Go was accepted today. This, and other things,

There's a trend I've noticed in Go community. It's a mindset that emerges at all levels - from junior developers all the way up to the thoughtleader "personalities" of the community, and... I don't like it.

It's a point of view that implies, and occasionally outright states, that "abstraction is wrong", that "being too clever" is "not idiomatic" in Go. That it's bad to be smart.

I'm going to call them Luddites for now, because it's more arresting, but it really represents the encroaching of anti-intellectualism into our work. Let me give a couple of examples.

The Difference Of Squares

I like Exercism, an online platform for learning a language. Solve problems, review your code, compare it to others. Great fun.

Fun problem: find the difference between the square of the sum of the numbers from 1 to n, and the sum of the squares from 1 to n. Sadly, my first take on this problem in Go has been erased by the sands of multiple Exercism platform upgrades, but originally it looked a little something like this:

package diffsquares

func SquareOfSum(num int) int {
    sum := 0
    for i := 0; i <= num; i++ {
        sum += i
    }
    return sum * sum
}

func SumOfSquares(num int) int {
    sum := 0
    for i := 0; i <= num; i++ {
        sum += i * i
    }
    return sum
}

func Difference(num int) int {
    return SquareOfSum(num) - SumOfSquares(num)
}

Enter fullscreen mode Exit fullscreen mode

Shamelessly borrowed from this solution.

Well, I'm a little mathsy in my spare time, so I thought there might be a way to do this without so much looping involved. Sure enough, these two numbers can be reached by using formulae for square pyramidal numbers and triangular numbers. Leading to something like this:

package diffsquares


func SquareOfSum(n int) int {
    x := (n * (n + 1) / 2)
    return x * x
}

func SumOfSquares(n int) int {
    x := (n * n * n) * 2
    y := (n * n) * 3
    return (x + y + n) / 6
}


func Difference(n int) int {
    return SquareOfSum(n) - SumOfSquares(n)
}
Enter fullscreen mode Exit fullscreen mode

(here's my original)

And in the comments I wrote something to the effect that this was a neat maths hack that simplified the solution.

Then somebody commented. Which is great, and I'm always glad to have people picking apart my shady code. But what they said was not so great. I'm forced to paraphrase as, sadly, that version of the comments system is now long gone. But it went something like this:

This is bad Go code. In Go we favour simplicity and readability, not weird maths hacks. This would be much better written as a pair of for loops.

Eh?????

Alt Text

Go 2.0 Generics

So today the proposal for generics in Go got one step further towards appearing in the language - it was accepted! Sure, some people have some problems with the specifics, but I want to focus on a vocal minority (well, I hope they're a minority) who oppose generics.

There's been some reaction:

And the one that sparked this rant...

Alt Text

(sadly I can't link you to this tweet because, after I told the author it was stupid, they deleted it. And then blocked me. Shrug.)

followed by:

Alt Text

They went on a bit, but they deleted it for a reason so let's not pile on. But it's not the first time I've seen or heard this sort of opinion:

Go is meant to be simple! Generics aren't simple.

Go doesn't need generics, I'm happy writing Go without generics. Why do I need generics now?

Go is meant to be readable! I can't read generics, but I can understand a nice for loop.

I can't understand code written with generics, so I like Go.

Seems familiar? That's why I'm writing this?

Do You Believe In Magic?

The maths I wrote for the Exercism exercise isn't complicated. In fact, I'm pretty sure you can read it out loud and understand it. What you might not understand is why it works. Fine. Maybe it seems like "magic" to you - no, you don't believe in magic. But you do know that "magic" in your code is A BAD THING, or at least that's what someone told you once.

But, to quote Arthur C. Clarke

Any sufficiently advanced technology is indistinguishable from magic.

It's not actually magic, it's not even mathemagic. It's just mathematics. You can go to those Wikipedia pages and read them and - boom! - you now know why it works. It happens to be faster that looping, but more importantly it's correct - it's simplified the looping down to single formula.

Yes, that's right, I'm claiming that it's simpler. Loops are not simple. Loops are, to be frank, a quite hard. To read them you have to move your eyes around a bit, walk the code, jump back to the top again, repeat... Sure, you may be more familiar with loops, but that's because you see them every day in Go.

You wouldn't write a loop to add two numbers together? Or to multiply them? This is no different. Things don't become complicated because you're being clever; things become complicated because you're being dumb.

So Why The Generics Hate?

There's a lot of talk about generics adding complication. No, they add another tool. You don't like it, you don't use it. The problem with this particular tool is that developers are remembering the garbage code they've seen written using generics in all the wrong ways. Prematurely abstracted supertypes that have no basis in reality, increase complexity, introduce incidental coupling where there should be none or decouple things that should be coupled. They remember this code because they wrote it all ten years ago in Java and now they're worried it's going to be all over Go.

Well, it probably will. But I reckon there's just as much garbage Go being written right now by folks who don't know basic arithmetic, how HTTP works, or when you should or shouldn't be using interface{}. They will move on to writing garbage prematurely abstracted Go with generics, never write a test first, change job every year, and get called rockstars or 10x developers. I'd try and avoid them and their codebases.

Or perhaps you're new to programming per se, or Go is the first typed language you've used. You're probably used to the playground fights about "lol no generics" and have grown up defining your language, and yourself, as "anti-generic". A sort of weird parochial view of programming - "we don't need your fancy city generics here in Goville".

Both these views are understandable, but nevertheless pretty dumb.

Consider the parable of the Blub programmer by Paul Graham. Don't consider all of it as parts are dumb and out of date, but ask yourself, do I think that generics are useless and unnecessary because I just don't understand them? All those other languages and programmers using generics - are they just being fancy for no reason? Are they just showing off and making code that nobody can read or test? Apply this thinking to all the features and techniques you can think of - do you think I have a deployment pipeline that runs automated tests at work because I'm showing off? Because I'm brainwashed by the Accelerate people and I should really just be FTPing the code to a server somewhere?

Programming is Abstraction

To finally claim that abstraction is dangerous and wrong... please. Heaven help me please - abstraction is the very soul of programming. If we weren't writing our own abstractions when we write code we'd be sitting there staring at a 10000 line main function wondering what on earth this thing did.

Abstraction is our only tool in fighting complexity. Well, the only one that works as the documentation is out of date. We use it with our training and our intelligence and hope to hell we make something beautiful at the end.

Beauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defense against complexity.

-- Edsger W. Dijkstra

Anything - ANYTHING - that gives us another way to abstract in our software is undeniably a VERY GOOD THING.

And generics are just another tool for abstraction. You might not understand it when you first see it - or second, or third. You might not understand how or when to use it. But that doesn't make it more complicated. It's not less readable. It's just making a demand that you learn something new and - as always - have the good taste and intelligence to use it well.

Read a Damn Book

Here's some takeaways for you to angrily repost on Twitter:

If you don't understand it, then you should try and learn it. You work in a knowledge based industry.

If you don't understand it and don't want to learn, then I'd seriously consider my career options: you work in a knowledge based industry.

If you do understand it, but somehow think that it's bad because other people won't understand it or will use it badly - well, I'm sorry, but that's all of programming. Stupid is as stupid does, and if you're going to use these new tools to make your code unreadable, that's on you - not the tools.

Of course, you don't think that. You think that these features are great but should be reserved for "senior" programmers who "know how to use them". You want a language that your underlings can't make mistakes in? This carries the idea that is still prevalent in a lot of places that Go is a "training wheels" language, designed to prevent you from making mistakes. Which is crap. It's minimal and opinionated, it's not idiot proof.

Conclusion

Programming is best when you use all the tool of abstraction at your disposal - functions, arithmetic, naming, modules and yes generics - to reduce complexity. Making things simple is hard - you need to learn, write and think hard.

Complaining about "clever" language features is like moaning about anonymous functions or irrational numbers. Stop being dumb, and stop promoting dumbness.

P.S. You should also probably do TDD.

Top comments (7)

Collapse
 
jrop profile image
Jonathan Apodaca

Extremely well-put. Bookmarking any post with a quote from Djikstra.

This announcement has honestly gotten me excited to try Go again once support lands for generics in the reference compiler. For now, I'm sticking with Rust (another excellent language).

I will still miss a package manager out-of-the box, though.

Collapse
 
simplegeek profile image
SimpleGeek

Very nice! Just curious, where does one look (what subjects, disciplines) to learn about more math like this that can be used to clean up logic? I'm greatly lacking in that area, but would like to improve.

Collapse
 
hymanzhan profile image
Xucong ZHAN

The code examples are just using two well-known basic math formulas that you can pick up from high school math on the series topic, at least that's the case in my region. For such numerical or mathematical problems, you simply reproduce the formula in code. And just want to add that, it's not only for cleaning up logic; It's much more efficient and performant. (O(1) vs O(n))
For more programming related ones that you are more likely to use in your job, learn the basics of data structure and algorithms. I find this book very helpful and easy to read.

Collapse
 
drbearhands profile image
DrBearhands

I agree on the sentiment, but on the subject of generics I've gone so far off the other end that I'm not so sure anymore. I don't think we have discovered how to do them "correctly" yet, universally quantified rank-1 types possibly being an exception.

I can sort-of empathize with the anti-intellectualism you are referring to. There is so much knowledge available that we have to pick and choose as a self-defence mechanism. I have personally adopted a broad disinterest in frameworks, methodologies and even testing tools for various reasons, but those would give me much better job opportunities than my forays into type-level programming. Unfortunately "programming skill" is probably a normal distribution and it is in a company's best interest to keep the code-base within the densely populated middle.

Collapse
 
_hs_ profile image
HS

This again shows me how toxic software development community is especially FP people. Don't get me wrong I understand OOP did it too (reason why people moved to FP and became religious about hating OO) but I'm in a state where I never recommend people to study anything related to IT i just shut up and look away. This to me is time of since religion where people think they are smart for knowing other peoples opinion and telling others they're stupid for disagreeing. It should be about using your head not using patterns, opinions, maths, magic, people... But hey it's fun right? In lockdown you go on twitter/reddit find FP people say OO is the best and find OO people and claim FP is above all.

Collapse
 
marcello_h profile image
Marcelloh

I don't understand. If you don't like generics, you can avoid them. Hate is so 2020...

Collapse
 
hymanzhan profile image
Xucong ZHAN

Since when is a simple high-school-level math formula considered a harmful math hack? That comment is so... well, though I hate to say this, straight up stupid.