Concerning complicated code: we have a guideline that says if one thinks he needs to explain in a code comment what a certain piece of code is doing, he should consider rewriting the respective code to make it more self explanatory. For example, often refactoring a piece of code into its own function and giving that function a suitable name makes a comment obsolete. Obviously, this way functions make a one-liner out of a 20-line piece of code, i.e. it's useful to make a function even if that function is called only once.
While I think/agree that it is usually preferrable to write something 'simpler' (which often results in more lines of code) contrary to more clever (which often results in complicated one line statements) I tend to start making 'exceptions' to that rule myself. The questions that come up are: should one use 'advanced' language features of a programming language? Which features are considered to be advanced: the complicated ones?, or the seldom used ones?, or the new ones?, or even just the non-trivial (but still well-established) ones? How much knowledge about a programming language can you expect your collegues to have? How much can you expect them to learn?
My background is C++ programming. It's certainly not the easiest programming language to use or learn. And it's evolving. In an internal training, I was introducing my collegues to std::tr1::bind and std::tr1::mem_fn which will be part of the new C++0x standard (but are already available to us when using MSVC 2008 SP1 or the boost C++ library).
Let me show you an example to demonstrate my point:
I would expect a novice C++ programmer to understand the following piece of code. Assume _controls to be of type std::vector, which basically abstracts an array and which allows access to the items in the array via array[index].
void Controls::updateBay(IDeskPtr desk, IBayPtr selectedBay, ContainingBayInterface* containingBayInterface)
{
const unsigned long controlCount = _controls.size();
for(unsigned long index = 0; index < controlCount; ++index)
{
Control* control = _controls[index];
control->updateBay(desk, selectedBay, containingBayInterface);
}
}
Now our code usually looks like this:
void Controls::updateBay(IDeskPtr desk, IBayPtr selectedBay, ContainingBayInterface* containingBayInterface)
{
ControlCollection::iterator it = _controls.begin();
const ControlCollection::const_iterator end = _controls.end();
for( ; it != end; ++it)
{
Control* control = *it;
control->updateBay(desk, selectedBay, containingBayInterface);
}
}
This makes the code more general (_controls could be any collection type supporting iterators) and is generally understood by all our engineers, but it already assumes you know what an iterator is.
Now the new std::tr1::bind lets me write this code like this:
void Controls::updateBay(IDeskPtr desk, IBayPtr selectedBay, ContainingBayInterface* containingBayInterface)
{
std::for_each(_controls.begin(), _controls.end(), std::tr1::bind(&EmulationControl::updateBay, _1, desk, selectedBay, containingBayInterface));
}
Knowing about iterators is not enough any more. Now you need to know what for_each does and you need to know what bind does.
Everyone with a bit of programming experience understands what the first code example does. Some people claim the one-line for_each statement to be safer (or more efficient) but I'm not sure this is enough reason to prefer it over one of the hand-written loops. While I today prefer this kind of code, it's hard for me to explain why.
If someone wants to share her/his opinion, I would be very interested!