views:

1658

answers:

24

If there's one thing I've learned from programming is that there are clever solutions to problems, and then there are "clever" solutions to problems. One is an intelligent solution to a difficult problem that results in improved efficiency and a better way to to do something and the other will wind up on The Daily WTF, and result in headaches and pain for anyone else involved.

My question is how do you distinguish between one and the other? How do you figure out if you've over thought the solution? How do you stop yourself from throwing away truly clever solutions, thinking they were "clever"?

+1  A: 

You ask people smarter than you.

Matthew Jones
No, exactly the other way round. Incidentally, there’s no one cleverer than me around … ;-)
Konrad Rudolph
+3  A: 

If you're feeling a solution is "clever" it probably is.

The best strategy is to engineer minimalistically. Don't add stuff which is not really necessary. Don't try to accommodate in your solution for all possible scenarios that you may encounter in the next 50 years. Just for today and for tomorrow, that's enough.

Developer Art
+28  A: 

to be truly clever it must also be simple. Ask people dumber than you, if they do not understand it'll probably be a problem later (that does not exclude also asking people smarter than you or reading reference material on the subject, etc.)

There are many ways to be clever.

  • If it's about coding tricks, my rule of thumb is to avoid them they are mostly obfuscation.

  • If it's about using good algorithms and good data structures big O is here to help you decide if you are really clever (do not forget to check what kind of performance is needed in that part of code).

  • be very cautious of premature optimizations. Even simple tricks like doing two things at once in a loop is often a way to make program more complex, hard to maintain and make evolve, and slower in the end.

  • in my experience there is really very few cases where cleverness is needed. The KISS principle (Keep It Stupid and Simple) was of much more help to me. Use the most simple solution that could possibly work is one of the TDD principles.

kriss
Some good thoughts here. Great developers make code that *lesser* developers can easily handle and don't have to come ask the "guru" how it works.
Patrick Karcher
I always thought that KISS stood for `Keep It Simple Stupid`
Nate Bross
Reminds me of an insane move made by Mikhail Tal (former chess world champion), to which one commenter said *"A move so crazy and brilliant that only a beginner or a master could have made it."*The same goes for coding: [only beginners and masters write dumb-looking code](http://stackoverflow.com/questions/2101875/what-are-some-programming-questions-or-mistakes-you-get-wrong-only-as-you-get-b/2151844#2151844).
BlueRaja - Danny Pflughoeft
@Nate Some prefer `Keep It Simple Sexy`
Pascal Thivent
@Nate: Indeed *Keep It Simple Stupid* (or even *Keep it Simple, Stupid!*) is more usual, I prefer my variant because I see 'stupidity' here as a quality of code, and calling programmer names give me nothing.
kriss
**Keep It Severely Simple** adds meaning and avoids insulting yourself. I've seen *Sufficiently Simple* used, but, while that alludes to "as simple as possible, but no simpler", it stops short of the desired meaning for me.
Roger Pate
+2  A: 

You just have to learn from your mistakes, and learn from others mistakes. This is about balance. Every time you seem something hacked out, or overly clever, ask yourself, put yourself in that developer's situation, and think about their thought processes.

This is about balance, and applying what we've learned to new situations. You have to be going after Wisdom, not just Knowledge. That fact that you're asking this question shows you're on the right path. It's just that there's no easy answer.

Some things to particularly keep in mind:

  • what makes it simple.
  • what is the return-on-investment for making it clever.
  • what will be more discoverable for future programmers.
Patrick Karcher
+4  A: 

Well:

"One is an intelligent solution to a difficult problem that results in improved efficiency and a better way to to do something and the other will wind up on The Daily WTF, and result in headaches and pain for anyone else involved."

-Covar

Luiscencio
+3  A: 

Ask a more experienced programmer. Better yet, ask thousands of them on Stack Overflow.

Jonathan Sampson
+4  A: 

Post answers to the questions here at SO and let us decide (and decide for yourself) how clever you are :)

Sarfraz
Who will be deciding on that? What would be the metric?
Developer Art
@Developer Art: Anyone visiting his profile and looking at the quality of his answers and others' answers for a particular questions. Don't we know why the Jon Skeet is renowned for, not reputation but quality of his answers :)
Sarfraz
The questioner, like the rest of us, has to decide 5-10 times a day how *clever* to be. He can't post every situation on stackoverflow.
Patrick Karcher
@Patrick Karcher: This is not the only possibility :)
Sarfraz
+6  A: 

For clever solutions there is a problem. For "clever" solutions there is often no real problem - just the solution.

tanascius
+2  A: 

You have to decide if the additional benefit in being clever offsets the difficulty of the programmer coming after you understanding what you did.

Robert Harvey
+33  A: 

"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 W. Kernighan

Paul R
I like the quote, but I mostly upvoted so I could watch your rep roll over to 10k
Michael Mrozek
@Michael: sweet ! ;-)
Paul R
@Downvoter: why ???
Paul R
He downvoted so he could watch your rep roll under 10k ;) (wasn't me, btw.). But also, your answer doesn't really answer the question.
tstenner
@Paul R: I didnt downvote, but it seems like a quite common attitude here; "I disagree with that persons upvote so Im now going to balance it out".
mizipzor
@Paul R: This quote doesn't attempt to answer the question, which is about how to decide how clever to be, how to achieve simplicity. Sometimes it's by thinking hard and being very clever, sometimes it's not. The quote could be helpful with some context; on it's own, it's not helpful.
Patrick Karcher
@Patrick: How does it not answer the question? Shall I explain? If you make your code too clever: 1) you will not remember what you did, and 2) you make it harder for the next person reading your code. The quote summarizes that to a tee.
Robert Harvey
"Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday's code" (hint, hint)
nuqqsa
@Robert: Yes, explain. LINQ is clever. The Spark view engine is clever. Ruby is clever. And they are (arguably) **good**. We often apply the word *clever* to things that simplify, that encapsulate, and save us time. The questioner is curious about the subtle distinction between bad clever and good clever, always easy to see in hindsight, but difficult to achieve **at the right time**. You quote tells the questioner what he already knows, that *bad* clever is bad.
Patrick Karcher
@Patrick: You make some good points.
Robert Harvey
@Robert. It is a great quote though, great for people who don't get that it's not about showing off. And there are too many of those people. I *try* to not be one of them, and often succeed.
Patrick Karcher
Do not be clever ,always be clear.
Suresh S
+12  A: 

A clever solution makes the code simple. A "Clever" solution makes the code short.

rwmnau
+14  A: 

Quoting from Einstein:

Make it as simple as possible, not simpler.

Truly clever is the solution that describes the problem in the simplest and therefore most straightforward way. The more you see what is done, the clever is your solution - there more it's about how, it's "clever" (or just weird :-)).

Dario
I guess bagels *are* pretty simple.
MusiGenesis
Bagels are clever too
Dario
@MusiGenesis: @Dario: No. *Simple*, *clever* bagels have no holes in the middle.
Konrad Rudolph
@Konrad: In this case *not simpler* would apply. Otherwise you'd just end up with bread ;-)
Dario
@Dario: I was about to make the exact same comment after reading Konrad's comment. By the way, my bagel comment probably didn't make any sense to you guys, being from Germany. Here in the U.S, there's a chain of bagel shops named "Einstein Brothers Bagels".
MusiGenesis
@MusiGenesis: You mean "here on the east coast of the U.S", I think. Actually, I've been on the east coast quite a bit and have never run across one, so perhaps "here in Philadelphia"?
Michael Myers
@mmyers: bagel much? see: http://www.einsteinbros.com/locations.pdf
MusiGenesis
@Musi: Apparently not... Although it looks like half of their locations are in universities, hospitals, or military installations. Maybe that's why I've missed them.
Michael Myers
@mmyers: perhaps you should go to college, get sick, and then kill a bunch of people. :)
MusiGenesis
+3  A: 

I always start by "Doing the simplest thing that could possibly work." Then I test if the solution is correct, robust, and performant. Often, at that point I am done. I consider this to be one form of cleverness.

shadit
+2  A: 

If your functions do too many things and have too many side-effects, then it is far too clever by half. If it is really nice and easy to read and is elegant yet efficient, then it is you who is clever!

Robert
+2  A: 

The "cleverness" that Alex Papadimoulis refers to is best understood in the context of his Programming Sucks philosophy.

Basically, his argument is that programming is not the creative art form that we all like to think of it as. It's about simply getting the job done in a simple, maintainable and human-readable manner. What you refer to as clever without quotes doesn't quite fit into Papadimoulis' view at all.

The argument is that there are good, tested, established patterns for how to solve problems in programming, and that you should stick to them. That you can't be clever - you can only work hard to learn the patterns that already exist.

The opposite of "clever" is not clever without quotes, it's not conjuring your own awesome ideas - it's reading Code Complete and Refactoring, and just sticking to the if-you-will boring fundaments of programming.

Disclaimer I'm not writing this down to advocate it, I'm just trying to explain the concept of WTF-"clever" the way I've understood it.

David Hedlund
+12  A: 

The goal I always strive for is simpler and easier to understood. My idea of a clever solution is one that introduces a major simplification. For example, if you can say, "Hey, wait a minute, we have to do all the same processing for take-out orders that we do for eat-in orders, except for this one little part about recording the tip to the waiter for tax purposes. Why is all the code written twice? Let's just write it once and call it twice." That simplifies the code and is clever. Or, "Hey, we're following the textbook formula that says to compare the cosines of the angles. But our angles are and must always be less than 90 degrees, so if cos A < cos B then B must be > A. Why don't we just compare A and B and skip the whole cosine calculation?" Etc.

"Too clever" is when you make the code harder to understand. Like when you say, "Hey, instead of this couple of IF statements that make completely clear to the reader what I am doing and why, I could just write 'x=x&0x374 + (y==1 ? 32 : 89) ^ (z-x)'. That's cool because not only is it one line instead of 4, but it looks really neat and no one will understand what it means except me!"

In real life, there are lot's of hazy cases. Well, here's one I just wrote myself recently. We had a block of code that was comparing two Java strings, but it had to consider the case where either or both were null. So the original code said this: (Apologies to those not familiar with Java. Hopefully the gist of the idea will be comprehensible).

if (s1==null && s2==null)
  return true;
else if (s1==null && s2!=null)
  return false;
else if (s1!=null && s2==null)
  return false;
else if (s1!=null && s2!=null && s1.equals(s2))
  return true;
else if (s1!=null && s2!=null && !s1.equals(s2))
  return false;
else
  return false;

There were some unnecessary tests in there that could certainly be eliminated. I simplfied it down to:

return s1==s2 || s1!=null && s1.equals(s2);

My version was certainly shorter and more efficient. Was it simpler or too clever? I think it's debatable. But I did it, which I guess says that I thought it was better.

Final comment: A solution that is just marginally "too clever" can be made "clever" by adding a comment that explains it.

To take a trivial example, I once worked on a program that performed a series of transformations on a matrix. It would start with matrix[0] and build matrix[1], then it would do its next transform reading matrix[1] and writing to matrix[0], etc, back and forth. So I had a couple of lines of code that said:

old=new;
new=1-old;

That could certainly be cryptic. So I included a comment that explained that this toggled us between 0 and 1. In that case, I thought a one-line comment adequate to explain to any competent programmer what I was up to.

Jay
Your last line says it all. A lot of times "clever" code can be turned into clever code, with a few comments.
Beska
+1. I strive to write self-documenting code where possible as well (extract well-named methods, use good variable names, introduce explanatory variables).
TrueWill
Most good compilers would have taken the final version written as a set of nested if-then-else statements and produced the same code. The first solution was definitely too much. The final posted solution requires a bit more thinking than I'd prefer the next developer to touch the code to have to deal with. As for the "old = new" example -- think "Exclusive OR" or "a = ! a" when toggling. Making "old" a boolean (if possible) and recoding as "old = ! old" would be transparent. If it has to be an integer, "old ^= 1" works.
Julie in Austin
+3  A: 

When I look at code that I have written shortly after writing it and think I was clever, I have learned that I was more likely "clever" and try again.

I aim for boring and uninteresting working code.

Sparky
+1  A: 

It's a "good clever" solution if you are clever enough to deal with the side effects of your cleverness, and "bad clever" otherwise.

quillbreaker
+1  A: 

A clever solution can become a great solutions if it's well tested, well documentedand well explained

Mel Gerats
+3  A: 
  • If it takes more comments than lines of code to explain what's going on 3 months later...
  • If you are abusing some deep magic of the language that is hardly ever referenced anywhere...
  • If it has a high number of control paths...
  • If it has a magic number that controls it ala the "Carmack" inverse square root...
Paul Nathan
I disagree with the comments remark. I had a 10 line function that required about 50 lines of commentary to explain because it was in a very time-critical region of an operating system and I had to explain every single last statement and what the statement had to deal with. Some code is just plain =hard= to get right or is doing something that is so bizarre (and has to be written that way). Knowing when that's the case is an important skill.
Julie in Austin
@Julie: "you know it when you see it". :)
Paul Nathan
@Paul: Well, yeah, but if you're going to write a giant blob of comments, you had better write clear comments and they'd better be useful. In the code in question, there were several possible states for EACH GENERATED INSTRUCTION depending on what the other processors in the system may have been trying to do to the operands at the EXACT SAME TIME. So, I had to explain how the memory hardware worked and what that particular line of code was trying to accomplish. FWIW, I was implementation a solution using patent 5,873,116. Very trick patent, just hard to deal with all the memory issues.
Julie in Austin
+1  A: 

You are truly clever When others call you smart or clever it does not get to your head and you are still grounded a ever.

CodeToGlory
+3  A: 

If your solution can be described as elegant instead of clever, then you're using the "right" kind of clever.

Edwin Buck
+4  A: 

This will get you started on the road to programming (and general problem-solving) excellence:

http://en.wikipedia.org/wiki/Occam%27s_razor

code4life
+1  A: 

The "Elegant" distinction is the right one, but elegance has its own problems -- some solutions aren't at all obvious because the thinking that went into the solution isn't obvious in the code or commentary. As another respondent put it, if you have to explain the code to someone else, you're being "clever".

The other thing that can blow up in your face is where you do something so elegantly that the solution can't be generalized. I had a co-worker in the late '80s, early '90s, who wrote a run-time library so that all the behaviors were driven by tables. Giant arrays of structures with fields all indicating what was supposed to be done. And when the updates to the code no longer fit that paradigm, the library was hacked to pieces. We were all very impressed when it was first written, except the code didn't last but about 8 years before it was all dumped. As an aside, the developer who did the re-write tried to be even more elegant. I re-wrote his code less than 8 years later because it was "Clever++". If you get my meaning.

Truly good code is extensible and designed to be maintained and modified, because all of those things will happen. It should read well by people who aren't intimately familiar with what you wrote. Profile your code. The 90/10 rule really does work -- 90% of execution time is spent in 10% of the code. Focus your skills making that code work properly. And remember that code lives on, long after you've completed the project -- make sure the next person can understand what you've written, can debug the problems they find, and not make a mess in the process.

Julie in Austin