Hacker News new | ask | show | jobs
by edumucelli 1156 days ago
It is laughable talk about "Don't Repeat Yourself principle" on a strongly biased towards Golang article. A language that took 13 years to add a simple method (Index) that helped the programmer to find an element in an array (slice). Before that you had to write a for loop every time you wanted something from an array. Talk about "DRY" ... That is everything but "simple" as described in the article.
5 comments

An amusing aspect of DRY is that the moment you think "great, with that last patch I'm no longer repeating myself," you now have an opportunity to look around and really just take in how much repetition happens everywhere, at multiple levels.

You are still repeating yourself, and will likely continue to repeat yourself, forever.

(Phew, look at that word "everywhere", it should just be "vrywh")

Great example of how refactoring is a neat way to introduce bugs and break features
Huh?

> But there's nothing wrong with repetition in itself. I say again, there's nothing wrong with repetition in itself: a task we do many times is probably an important one. And if we find ourselves creating new abstractions to no purpose other than avoiding repetition, then we've gone wrong somewhere. We're making the program more complex, not more simple.

Literally why I stopped writing Go. I was going crazy repeating myself so much. If err != nil also never felt nice to use.
> Before that you had to write a for loop every time you wanted something from an array.

How often do you do that? I mean, it comes up - but if you're linearly scanning every time you want to select something from a list, that sounds like a surefire way to write slow code to me. Is there a reason you aren't using a map?

Linearly scanning a small array is very likely to be faster than looking up a key in a map. Especially if we factor in memory cost and not just speed.
Maybe. That depends on the map implementation. In javascript I’m pretty sure small maps are implemented as lists anyway. I wouldn’t be surprised if Go is the same.

Searching through a list is definitely more complex to write, and it carries the danger that your list will grow and you wont change your code.

The speed difference will only matter at scale - so if you have a lot of small lists with items you’re searching for. That happens, but it’s uncommon that it’s the best approach. I probably use find() / indexOf() about once every thousand lines or so.

The commenter above implied it’s a very common operation in their code. (So much that they’re angry about Go not having it in the standard library). I don’t know about the commenter above, but I’ve certainly seen a lot of novices at programming massively overuse lists not because they’re performance experts, but because they don’t yet understand when a map might be a better choice.

So I must say I understand Go’s choice here. Go is a paternalistic language where the obvious choice should usually be the right choice. Go is actively against clever optimizations philosophically. I can imagine rob pike being quite pleased that slow, linear scans of lists are awkward in his language. This sort of judgemental paper cut is sort of Go’s whole thing.

If you don’t like being looked down on by the compiler, use a different language. Or use maps in your Go code. Go isn’t designed to be microoptimization friendly.

(Source: I sat about 2m away from Rob Pike for nearly a year while he worked on Go, before it hit 1.0. Go isn’t designed to be a language for people who think about cache lines.)

At sizes/number of items, where this holds true, maybe the choice of data structure is not as important. It becomes important, once the number of items in that collection increases and then always linearly scanning the whole array will become a problem. Just use the appropriate data structure and be safe in the future, taking a negligible hit for small input sizes.
Now I understand why mordern web is slow as hell.
Then you probably misunderstand just how much work a CPU can actually do in the time it takes to read a new cache line from main memory.
Now you miss the point that you need to read that list from RAM in order to do for loop too.
Go does actually embody the DRY principle (Do Repeat Yourself).
I prefer calling it WET (We Enjoy Typing)
These days Copilot tremendously helps me with those kinds of repetitive code.
This is my experience as well. GitHub Copilot has been very efficient at generating variants of boiler plate code. It allows you to efficiently repeat code so you can delay code abstraction or generalisations until you are confident a generalisation makes sense.

Having worked as a developer for many years I now much prefer to repeat code a bit to making the wrong abstractions to early. The tedium of writing out code is now reduced thanks to well performing language models.

reading multiple lines of what would amount to a single scan/find/map/reduce is still a pain in the ass though