89

I've noticed a lot of questions lately relating to different abstraction techniques, and answers saying basically that the techniques in question are "too clever." I would think that part of our jobs as programmers is to determine the best solutions to the problems we are given to solve, and cleverness is helpful in doing that.

So my question is: are the people who think certain abstraction techniques are too clever opposed to cleverness per se, or is there some other reason for the objection?

EDIT: This parser combinator is an example of what I would consider to be clever code. I downloaded this and looked it over for about half an hour. Then I stepped through the macro expansion on paper and saw the light. Now that I understand it, it seems much more elegant than the Haskell parser combinator.

Thomas Owens
  • 85,641
  • 18
  • 207
  • 307

28 Answers28

207

Simple solutions are better for long-term maintenance. And it's not always just about language familiarity. A complex line (or lines) takes time to figure out even if you're an expert in the given language. You open up a file and start reading: "ok, simple, simple, got it, yep, WTF?!" Your brain comes to a screeching halt and you now have to stop and decipher a complicated line. Unless there was a measurable, concrete reason for that implementation, it is "too clever".

Figuring out what's going on gets progressively harder as complexity grows from a clever method to a clever class to a clever pattern. Aside from well-known approaches, you have to figure out the thought process that went into creating a "clever" solution, which can be quite difficult.

That said, I hate avoiding a pattern (when its use is justified) just because someone might not understand it. It's up to us as developers to keep learning and if we don't understand something, it's a reason to learn it, not to avoid it.

Adam Lear
  • 32,069
102

KISS Principle

Keep it simple, stupid. Clever solutions are great, but often the simplest straight forward solution is best.

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

Brian Kernighan

haylem
  • 29,005
Josh K
  • 23,029
  • 10
  • 67
  • 100
83

Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it. -- Alan Perlis

30

The best solution is not always the most clever solution. Sometimes simple solutions are equally good.

In Software you always need to think in terms of maintainability. If a piece of code is too clever for someone who is going to maintain it, I would say that cleverness is not worth it.

Geek
  • 3,961
26

To quote Brian Kernighan:

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”

peterchen
  • 1,127
22

cleverness is a tool; by itself it is not harmful. It only becomes harmful in context where it is not necessary.

16

"Clever", when applied to code, is almost always just a euphemism for "needlessly complicated".

Reading good, clear, simple code is hard enough. Reading "clever" code is like studying latin poetry all over again.

The confusion arises because "clever" as an attribute of a person has a completely different meaning. This case can also be seen as an example of why designing software for real people is hard: Because they are ambiguous.

And because some programmers suffer to understand the social protocols most people follow, which forbid them to directly denounce code as "needlessly complicated", they may find it hard to differentiate between the two meanings of the word clever. Contrary to what some may think, I think ultimately better "people persons" (meaning: people who have empathy and introspection and patience) make better developers. Because they know who to write for.

fzwo
  • 631
9

Most folks are focusing on cleverness from an aspect of "The code requires too much deciphering to figure out what it is doing" and all the bad things that go along with that such as

  1. No one else can figure it out, let alone maintain it/debug it.
  2. The person who wrote doesn't even know what it does.
  3. It may actually be not all that brilliant to begin with
  4. etc....

All good points, but there's another negative aspect of cleverness and that is the old ego problem. This causes issues along the lines of

  1. Someone that is too "Smart" to use anyone else's solutions. Why look for what other people have done when you can invent your own way of skinning the same cat?
  2. Someone who thinks they've invented the coolest solution to a problem will often refuse to take any input.
  3. Won't let anyone modify "their" code even when there's obvious issues or a trivial change is needed.
  4. Somewhat conversely, they think they're smart and need to use the "latest" technique to prove how smart they are but fail to get a good handle on it in either personal projects or otherwise non-production code before rolling it into critical parts of the system.

We're all guilty of too much ego sometimes, but when it gets in the way of the team it's a problem.

MIA
  • 5,214
8

Good Clever -- high ratio between clever lines of code vs lines of in a non-clever alternative. 20 lines of code that saves you from writing 20000 is Extremely Good Clever. Good Clever is about saving yourself work.

Bad Clever -- low ratio between lines of code written written vs. lines of code saved. One line of clever code that saves you from writing five lines of code is Bad Clever. Bad clever is about "syntactic masturbation".

Just to note: Bad Clever is almost never called "Bad Clever"; it will often travel under the aliases "beautiful", "elegant", "concise", or "succinct."

user8865
  • 431
7

I have to wonder about everyone's definition of clever.

Personally, I feel like I have been clever when I have taken a hard, complex problem, and implemented it in a very simple and straight forward way, while maintaining an acceptable level of efficiency.

tl;dr i feel clever when, during a code review, my reviewer says "wow, that was easier than i thought it was going to be", as opposed to "wtf is all this.."

6

Aside from the theory answers listed, often this gets used in the context of too clever for everyone else.

Move between a top tier performance intensive team and a medium tier maintenance team sometime to see the real life differences in what is "too clever".

Leaving out the theory arguments, too clever is often based on what the least skilled team members can work with reasonably, so it is very relative to the environment.

Bill
  • 8,380
6

Sometimes I've been so clever that I've been wrong.

John
  • 1,027
4

Performant, maintainable, timely and cheap are the ways I measure a solution. I guess clever could also be part of a solution as long as it doesn't negatively affect those qualities.

Heath Lilley
  • 1,280
3

If clever code + the amount of comments required to make it understandable code <= simple code, then I say go for the clever code. Every time.

I think the problem arises when people who write "clever code" deliberately fail to comment it properly, because only by it being initially incomprehensible will future generations who come across it have to spend time "appreciating" how clever it is.

3

I'm reminded of a quote I've seen attributed to many different people, as the good quotes often are.

To paraphrase:

Any intelligent person can make the simple complex, it takes a genius to make the complex simple.

Taking a complex idea and simplifying it so it's understandable shows the cleverness of the constructor but taking a simple idea and making it complex shows the constructor wants to be seen as clever.

2

If the 'clever' solution is difficult to figure out, then it shouldn't be used. For instance, if through side effects you can contract a complex calculation to one line, it's clever. But if it takes an hour for someone else to figure out what in the world you did, it's too clever.

Michael K
  • 15,659
2

In my opinion, cleverness per se isn't a problem. Usually we can make confusions about "clever" (without sarcasm) and "insightfull" code. What I see as a problem, is the fact that usually the "clever" (with sarcasm) code contains implicit not-visible requirements, making it harder to debug and maintain along time.

There are several known algorithms that are clever. Quicksort is one, IMO.

"Clever" (with sarcasm) code usually make assumptions about variables being set and states of the system that are virtually disconnected from the "clever" code (as files opened previously, network connections, databases, etc...).

The amount of data you have to load on your brain to maintain correctly a "clever" code is usually to big to have a good cost-benefit ratio.

Machado
  • 4,130
1

"Clever code" is any code for which the programmer had to think really hard or use some advanced skill to write it. The problem with that it disregards the need for a certain "cleverness margin", best expressed by Brian W. Kernighan:

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."

1

Because what looks like cleverness to a developer in a burst of creativity can simply pass as mess and just be an unreadable, unmaintainable block of obscure riddles for others.

Still, a nice, clever, well-performing block of riddles, but if you have the experience, you'll often realize that it will cost your business (not you, the developer) at lot more to maintain that thing on the medium- or long-term. So you prefer to calm the ardor of your fellow developers when they get carried.

Except, of course, if there's a justification for the cleverness. And if there's a good documentation that comes along with the obfuscated thing you just wrote. You did comment that clever piece of code, right? Explain it's intent, why it needs to be like, and how it behaves?

If there's no justification, then it's probably just either premature optimization, over-engineering, or a YAGNI kind of problem. If it takes 15 levels of indirection to do something simple, then there's a good chance you fall under of the previous categories as well. And if it's not documented, then it's just trouble.

Great code shouldn't require the maintainer to be at 100% all the time to understand it. Good code is clever. Great code can be almost as efficient, but better in many other aspects. Great code shouldn't require an IDE with 15 views to follow your application's design.

Note: hey, I've written a few stuff I thought to be clever but that drew WTF? out of - if not my co-developers' - my manager's mouth. Have to look at it from their perspective.

haylem
  • 29,005
1

I tend to be clever, but I strive to be elegant.

Develop code now that others will not try and avoid later.

kevpie
  • 527
  • 4
  • 7
1

This is my understanding of the issue, based on my experience and the other answers:

  1. Code that took cleverness to write, but comes out readable and maintainable is not considered harmful. However, most developers would not call that kind of code "clever"; they may use a different term like "elegant". There may or may not be some debate about whether such code exists.
  2. Production code that requires significant time and effort to understand even by a seasoned developer familiar with the language is "clever" and considered harmful by everyone.
  3. Production code that requires significant time and effort by inexperienced developers is considered harmful by some. I've seen answers either way, and I've worked with developers who've said explicitly that they would prefer to keep everything "lowest common denominator".
1

I know a guy; he is probably the most brilliant person I have ever met. He is definitely an unbelievable coder, probably better than I will ever be in my entire life in terms of sheer programming chops. He writes code like he's typing a word document and can reverse a linked list like you wouldn't believe. If you want to talk about writing some seriously complex code, he's your man and if I run into an unbelievably hard problem I always turn to him. However, working on a project with him in a team setting is excruciating. He is unable to directly target the business problem and provide a logical, efficient, and concise solution to it. For him, a code listing of 1000 lines would be better than 100. Instead of using the tools provided to him via the IDE or framework, he will roll his own super-optimized tool. This is all well and good except for when other team members are waiting on him to finish something, or we have a deadline.

While I admire his ability to do these complex things, what I need is someone that can solve the problem and move on. Its not great to say, or admit, but sometimes in a business setting time is everything and you have to just solve the problem and get on with your life, you can always come back to it later and refactor the hell out of it to improve your code. There is a fine line between being clever and also being a pain in the butt. My motto for my team is always, what is the simplest possible thing that will work in this situation and then go from there. Sometimes simpler isn't always the answer but its a damn good place to start.

1

"Clever" in this context means "too clever for its own good", i.e. something that works now but will be a nightmare to understand and change later on.

Especially if it's a trick that exploits an obscure feature of the programming language, or makes use of weird side-effects, or is a really bizarre way of solving the problem in the target language.

Andres F.
  • 5,159
0

Re-quoting for context and and easier comprehension:

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."

What Brian Kernighan wrote here obviously refers to convolution, and he mistakenly used the word clever.

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as [convoluted] as possible, you are, by definition, not smart enough to debug it."

Convolution:

A thing that is complex and difficult to follow.

Clever:

Showing intelligence or skill; ingenious

Educated programmers know that simple code is ingenious. Code that is as clever as possible should be simple by definition. Educated programmers will also avoid working with and writing convoluted code like the plague. They will also turn convoluted code into clever code whenever they have the chance. Code usually starts out convoluted and approaches cleverness as knowledge about the domain and understanding of human cognitive ability in programming is better understood through experience and shared knowledge.

Because of the popularity of this quote and Brian Kernighan being quite popular in the industry this misuse of the word has a negative social impact and I'd honestly like to see that addressed by the man himself. Before writing this article I tried to see if I could simply e-mail him, but, I was unable to find any email contact information that I understood :(.

The negative social impact I have seen is other programmers ostracizing their more clever peers, because they now see cleverness as a problem. The real problem is the stupid peers who think they are being clever by doing things in a new unidiomatic way, and constantly inventing new things when there is no advantage instead of gaining and understanding of the greater community and reusing clever ideas as much as possible.

I do need to clarify though that often gaining an understanding is more difficult than inventing your own. Because of the common problem in industry for unrealistic deadlines inventing your own for your smaller niche problem will be used to save time. This is based on the observation that useful, reusable things usually target a larger niche, or provide a useful abstraction for invention. It is also based on the fact that people target large niches to make more money, when often this makes the tool extremely hard to use because of the complexity involved in making something usable for a wide area of applications.

The other negative social impact is this prevents progress and the desire to comprehend because in our egocentric world we will immediately be in denial of our own lack of understanding and write off the code of as being convoluted even if, once understood, the idea is actually quite clever.

TODO I'd like to cite some references but I'd also like the lack of references to not impede my ability to share information so I will quickly cite what I remember as the sources of my information and maybe I will find the actual info some day (or you can find it for me! :)

  • Guido Van Rossum's talk about event loops and how he came to understand them
  • A GitHub employee who stated that they avoid hiring clever people on Y-Combinator
  • Much of the discussion and learning that goes on in the Python community. The Python community is especially critical of new ideas, but does not dismiss new ideas they do not understand out of hand, and you can typically see features that were at first seen as convoluted see the light of day as a core language feature/package.
  • My own experience and professional opinion based on my 10000 foot observations. I can't really see the specifics to enlighten from all the way up there though :( Hopefully your experience and observation will tell you the same thing and someone else can comment below to give this answer some merit.

Feel free to add your own citations! Also, feel free to add commas to my text. I have not refreshed my knowledge of comma usage in English in quite some time...

0

I prefer Simple solutions, I really like the ruby way. When you want to for example sum first 2 elements on the list. first you cut the list to make it have size=2 and then you sum it.

I remember that once I used 1 list instead of 3 and create one big function that was very hard to maintain/change.

in todays world we don't have to sacrifice code clearness for performance(except c++, they don't have to, but they will).

IAdapter
  • 1,345
0

Usually when you need to be 'clever' its to workaround a problem in code. Ifs a workaround and not very straightforward then you'll get a lot of confused faces or othertimes weird side effects when assuming certain conditions (which may be 100% correct at the time of writing the code)

Thus clever == confusing == bad :( But its also awesome as i used them for practical solutions to limited problems.

-1

I couldn't find the word discipline mentioned anywhere around here, so I'll chip in. I do not want to post the answer, but to share a different insight on the matter, maybe one that the original question did not have in mind.

A clever developer is a good thing.

However, before cleverness come other traits. As you might have realized I will talk about discipline. A clever and undisciplined developer can be very bad for the long term maintainability of the system.

Suppose that a bug arises or a new requirement comes in. A clever developer might soon realize that a couple local fixes will get the job done in 2 minutes. If that developer is disciplined he will restrain from applying those fixes to the source code and will, instead, find a meaningful way to compose the desired behavior to the system. This way, the next time the need will arise to modify the particular pieces of code the maintainer will have an easy time to understand the code and implement the new changes without breaking anything. If not, well you get the picture.

dkateros
  • 101
-1

Because often people don't know a language, idioms and patterns. They could take a book and learn it, but they don't. And because of those people you should write simple code.

It's not a cleverness. It's a knowledge.

Abyx
  • 1,445