The proportionality argument is bunk, straw-man level bunk. Consider what goes on every time go accesses an object, casts to an interface or writes to a channel. Huge, complex code under the covers, way more than the Python examples he's given. What this article really says is "There are abstractions I'm not as comfortable processing as others, therefore those abstractions are bad."
If having code be proportional to complexity was a good idea, we'd all be writing in assembly and subroutines would be frowned on.
I think having code be proportional to 'complexity' is good, but having it be proportional to 'work' makes no sense. Personally I find things 'simple' when they only require one level of abstraction, such as accessing an object, or performing arithmetic operations on algebraic objects (e.g. multiplying matrices). And complex when they require more (e.g. manipulating the coefficients of two matrices to define their matrix product).
Boilerplate is when you requires more code than the complexity requires, usually because the language doesn't provide a sufficient opportunity for abstraction.
Note that, if we define a '->' operator that roughly expands to the following:
(x, err) -> f :
if (err != nil) {
return nil, err
}
return f(x);
Then the entire code he wrote as an example of boilerplate can be written as
DoSomething -> SomethingElse -> MoreWork;
with some minor differences that could be optimized away in the right language.
I have a Lua module I wrote that allow me to do stuff like:
process.limits.soft.cpu = "4m" -- limit to 4 minutes of CPU time
process.limits.soft.core = 0 -- and no core file
Yes, ultimately, it ends up in setrlimit(), but the amount of code that goes into backing this up is a bit daunting. But it more than makes up for in showing the intent (and it's not like this is done in the hot path of a program).
If having code be proportional to complexity was a good idea, we'd all be writing in assembly and subroutines would be frowned on.