Hacker News new | ask | show | jobs
by iagorodriguez 3623 days ago
I run a small dev company. This is the first lessons we teach our programmers. If your code cant be understood by someone else with minimal efforts it is not good enough.
7 comments

Do you maintain a high-enough level within the team though? Most "clever code" I've seen is called clever by people who are not yet proficient enough in a language to understand it. So with unskilled programmers pretty much anything that isn't straight combination of classes, loops and conditionals will be considered clever. There's a tradeoff here - I get the business reasons why one may want to have the codebase at the "lowest common denominator" level for the team. But then again, programming is a craft, so that person who says lambdas in Java are "clever code" (real example from my work) should IMO suck it up and spend few hours learning; then the code will stop being "clever" to them.
> Most "clever code" I've seen is called clever by people who are not yet proficient enough in a language to understand it.

My interpretation is the opposite. I call code "clever" after I've understood it. I agree its not universal, but in all the cases I've seen it used so far, its been another way to say "This could have been written in a simpler, more readable manner. And it should have been."

Ockham's Law of Programming: the simplest solution which solves the problem is the best solution.
Not every company wants highly skilled programmers. Depending on the complexity of the project, and cost of defects unskilled programmers may be the most cost effective.
I know. Took me a while to realize it and understand why companies think that way, but it boils down to the fact that as programmers, we're not paid to do a good job, we're paid to do a good enough job. Those two goals are very often at odds. It seems to be a typical clash of craftsmanship with market economy.
Another articulation is - we aren't paid to write code, we are paid to build stuff.

Authors get paid to write prose people can read - the readability of our work only 'matters' insofar as good craftsmanship practices help the team maintain velocity over the long haul.

That's a good point. There is also a fine line between craftsmanship and intellectual self-gratification at a customer's expense. Doing a good enough job that solves a customer's problems without gold-plating or unneeded complexity is what professionals in most fields are ethically required to do.

As tired as I am of seeing sloppy code, I also intensely dislike the trend at the other end, of creating a half-dozen RESTful microservices and throwing away the relational DB just because it seems cool, maintainability be damned.

I'm hopeful that software development (especially business software development) will someday escapes it perpetual adolescence, and will develop stronger ethical standards.

Unskilled software developers are never cost effective. Never.
This is a very delicate subject. If the program is using language constructs and can't be understood because the reading programmer doesn't know it, then who's fault is it?

why have multiline if/else when a tenary operator can do?

I rather read a = b ? c : d; than possibly 4 lines of code, p/s ignore the names of the variable.

There are plenty of code out there that are so easy to understand if you read them one line at a time, but very difficult to see the big picture, say there is a method being called as follows foo->dostuff(bar).

The issue is there is so many layers between calling dostuff() and something interesting happening. because dostuff calls nextstuff() and nextstuff() calls stuffafternextstuff(). The code is easy to read but terrible and tough to unravel.

There is only so much anyone can hold in their head at once, a bit complex but 2 layers deep is better than so simple to understand one line at a time but 10 layers deep.

Bertrand Meyer and a few other notables talk about separating decisions (policy) from execution, which happens to address some of those issues, because the decide and act become sibling function calls instead of a deeply nested chain of responsibility arrangement.

It also happens to make testing a lot easier.

It's probably just a crystalization of the old idea of keeping business logic out of your code, but somehow misses the open invitation to create rules engines...

There is a tendency for the discussion of complexity in programming to descend into an obsession with trivial minutiae.
I agree to a huge degree. If your code is obscure and overly complicated then it's probably not a good idea.

To play the devils advocate though and show that sometimes we have to challenge our rule set I'll give an example.

I worked in a C# shop where they were using Webforms for a massive application in 2012. Their developers were old hands at winforms and didn't like to learn new things in the framework. So myself and another developer started introducing things such as Linq, javascript, and other novel concepts.

Because some of the old hands there didn't understand it we weren't supposed to use it...

I also attempted to get people to write more testable code so that when we do make a change it doesn't break something in a different section of the codebase. I got push back on everything.

So I'd amend, "If your code cant be understood by someone else with minimal efforts and/or explanation it is not good enough." Because sometimes people don't understand the code because they don't have an inquisitive nature.

Hell, there were public, senior, MS hires that fundamentally didn't understand "var". Let alone how LINQ worked or anything like that. On HN last month, someone was critising the use of flatmap as being too complicated. Despite the type signature making it clear what it does.

There's probably lots of apps that need real boring code, so you can add yet another case to the data entry app to handle the extra 2% sales tax for a certain county in Wyoming.

I can't imagine that there's any apps anyone wants to work on that have a low bar for "cleverness". And it's mostly a one-off thing. Learning language features should not be the bottleneck on getting someone up to speed on a project. On any system of any fun or size, the domain-specific stuff probably dominates.

(Anecdote: I've had several people come onto projects with F#, fresh, no FP/F# experience. It's been very easy and after a while they wonder how they ever put up with C# in the first place. And the people that aren't able to do this, I wouldn't want to hire to work on C# either.)

This needs to be seen in context though, because it critically depends on who "someone else" is. A category theorist will have a much more abstract view of a Haskell program than your usual developer for instance and something that seems tedious and unnecessarily technical to one can actually be a useful abstraction to someone else if one knows how to use it (e.g. see all the monad submissions).
There's a cost to that too, unfortunately. Longer code may be easier to unserstand line by line, but the sheer volume of lines can make it harder to comprehend. Terseness has its advantages.

Usually, making good developers write code for less experienced developers makes the code quality worse. OTOH, it can then be maintained by entry-level developers.

> Terseness has its advantages.

I'd argue there's a difference between being concise and being terse. I think that's what's at the heart of beautiful code: It expresses its ideas in a very simple, concise manner, without sacrificing readability. ("As simple as possible, but not simpler")

> If your code cant be understood by someone else with minimal efforts it is not good enough.

The article doesn't use "clever" as an antonym for "readable", though. The point is that clever code can be excessively brittle.

"Too clever by half" is one of our code review reject boxes.