> I thought I adressed that; everything I mentioned - explicit error returns, pure functions, no global state, and no metaprogramming - all show their true worth in large and/or unfamiliar codebases.

I agree with all of those. I try to avoid these things whenever I write code (in rare cases, there are valid reasons for using them, but I agree they are overused).

But that still leaves tons of room for different ways of writing code, and it's very hard to say which one of these is "obvious". Obvious to whom? Some people want to have large methods, so they can see everything at a glance, others prefer to have more smaller function so they can see the high-level picture before they see the details. Which one of them is right? I can't say - it depends on the person, on the problem, and on many other factors.

What is missing from your list is "don't use advanced language features". You can do all the things you mentioned and still use "advanced" language features. And the debate about Go is often about how (presumably) the absence of "complex" features (something which is IMHO a bit subjective) makes code more "obvious".

But you can have generics (or, more broadly, polymorphism), interfaces, higher order functions, proper algebraic data types, etc. and still uphold all the features you've quoted. That's what I meant with the Haskell comment (but supposedly the same would be true for e.g. Lisp).

Since you shared a talk with me (which I intend to watch, but I haven't had time yet), allow me to also share one (with which you may already be familiar): https://www.infoq.com/presentations/Simple-Made-Easy/

Here, Rich Hickey (the creator of Clojure) makes a point that resonates very well with me: namely that simplicity (which is what we desire) is not the same thing as easiness, and that pursuing the latter can often come at the expense of the former. In other words, if you use "advanced" features the right way, it can help create code that may require more concepts, but is still simpler to reason about.

> https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction

I've never taken this blog post to mean that abstractions are wrong. She does say that a bad abstraction is worse than no abstraction - but, IMHO, also that the right abstraction is even better than that. BTW, Sandi Metz is a Rubyist.

> Both suck, but as far as I can tell, erring on the side of underabstracting is better.

Maybe you haven't had the fortune of working with code written by non-developers (e.g. data scientists). But in any case, my most common experience is that most abstractions are simply wrong. Code that belongs together is spread out over 5 files, and these in turn don't have a single purpose, but end up doing too many things at once. Of course, I've also seen overabstracted "every class has an interface" nonsense. And I've seen huge functions that would have benefited from some internal structuring.

> ;) I can either post something quick but smug or spend hours polishing it until it's as bland as can be. I prefer the quick and authentic approach.

Well, this comment that I'm replying to doesn't seem bland to me. You elaborating your point of view makes for more interesting discussion - at least in my view.