Going by their first example, the fact that I couldn't write

   list.delete(value)
without realizing it involves a linear search is considered one of the benefits of Go.

That said, I agree Go could use a bit for ergonomic and handy methods, while still remaining efficient.

The example on Concurrency also has a different answer. Go gives you all the tools, but there are many different ways their problem can be solved. By explicitly avoiding a "join" method and having any default 'channels', Go makes all these possible. What is missing is some of the popular patterns that emerged in the last few years need to make it to into stdlib or some cookbooks.

1. If you want a worker model, I would start n=3 go-routines and they all receive from a single channel. They don't need to much around with a channel of buffer 3, as in the example.

2. If the workers already return data from a compute, the read from driver serves as the wait.

3. In other cases, there is sync.Waitgroup available to synchronize completion status.

4. End of work from the driver can be indicated via a channel close. Closed channels can still be read from until they are empty and the reader can even detect end-of-channel.

Designing concurrent system is a bit complicated. Some tutorials do make it sound like a `go` keyword is all you need. All of these can fixed by improving std-lib or cookbooks.

> without realizing it involves a linear search is considered one of the benefits of Go.

The primary problem that I think the author was trying to get at is that go lacks tools for building abstractions. In a language with generic functions (for instance), it would be possible to implement a delete_at function completely in user code. The fact that you cannot reflects poorly on the language.

Of course it will always be possible to write functions that have arbitrarily slow time complexities. That's something you have to be aware of, with any function; it's not a reason to avoid including a linear-time function to remove an element at a given index of an array.

That’s a deliberate choice in many ways, and it means you don’t end up building castles in the air, or worse, working within someone else’s castle in the air. See the lack of inheritance for a good example of a missing abstraction which improves the language.

Abstractions are pretty and distracting but they are not why we write code and each one has a cost, which is often not apparent when introduced.

That’s not to say Go is perfect, there are a few little abstractions it would IMO be improved by having and the slice handling in particular could be more elegant and based on extending slice types or a slices package rather than built in generic functions.

> and it means you don’t end up building castles in the air, or worse, working within someone else’s castle in the air. See the lack of inheritance for a good example of a missing abstraction which improves the language.

Very well said. If only more developers would understand this.

Yes I know, creating interfaces, inheriting everything from the void, adding as large amount of layers to create the beautifully constructed reusable structure is a nice drive but it might happen no one will reuse it as doesn't want to dive itself trough infinite level lasagna with rolling ravioli around it (and - thanks god, go doesn't have try/catch - throwing exceptions trough all the layers to force you to go down the guts of the construct to figure out what it means). Or, as it often happens, will be forced to reuse it, complicating his life and is code.

I do understand that inheritance, even operator overloading has its meaning and is extremely useful. But it has another side - everybody are overdoing it as "might come handy later" and the code becomes a case for "How to write unmaintainable code"[2].

When I am coding I am not doing it for philosophical reasons and go has until now succeeding being a very helpful tool without much of "meaning of life" complications. And i would love to see it stay that way.

If you are forcing me to read the documentation / code (presumably I know what I am trying to solve) to be able to use the "beautiful oo construct" and forcing you to read your beautiful design, you have failed making it and I have seen it in java everywhere. I just hope the same people making everything complicated more than it need to be wont skip from java[1] train to go train. I really don't want them anywhere close.

[1]https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...

[2]https://github.com/Droogans/unmaintainable-code (and 20 others)