Re: Variables in for loop (style issue)
{Moderator, Please watch the heat. Were I not certain that neither party
would take offense I might have rejected this for a little too much.
-mod/fwg}
kanze wrote:
Still, I agree with what I
think was your import: that we should write code with regards to
making it easy to rework or to modify, and that such issues are
rarely present when writing normal English text. Note however
that in order to modify code, we must first understand it --
which brings us back to "good writing". This aspect of code may
introduce additional constraints, but it doesn't remove any that
are present in writing.
Ehm. Yah, that was my "import". The discussion could become quite long,
and you'll beat me to it as usual because I lack the resources to reply
to your posts :o). But IMHO code writing must fulfill two important
requirements that literature doesn't have to: (1) precision; (2) ease of
modification. One kind of literature also striving for precision is
legal text, and to the joy of lawyers, there's never a way to write
something precise enough in human language so as to leave no room for
interpretation. I don't know of literature that must satisfy (2).
I don't think (1) and (2) above are "additional constraints", they are
organic constraints that interplay with the others. For example, "good
writing" becomes writing that, among other things, makes intent clear in
order to facilitate (1) and is modular and easy to understand to
facilitate (2).
Yet the for_each loop is severely limited in what it can
effect. That it evaluates its boundaries only once is about
the only good thing about for_each.
It's limitations are in fact the good thing. When you see
for_each, you know that what is being done conforms to these
limitations -- for_each is not find_if, for example. It's value
is not in the function itself -- it is in its opposition with
other functions (and explicit loops).
This argument is misplaced. Yes, there's a lot to say about using the
right tool for the job, but for_each has a big problem: it's not
scalable. Adding one more operation to a for_each explodes the cost into
writing an entire new type. In contrast, for loops are one <Enter> away
from accepting more code, which is what often happens. for_each is just
the wrong way to cut the diamond.
As an example of what's scalable and what's not, a coding guideline I
personally adhere to is to brace my code "profilactically".
for (this_; that; the_other) {
one_expression;
}
instead of:
for (this_; that; the_other)
one_expression;
This is to impart liquidity to code: I add and subtract expressions
later without messing with the braces. Some people don't like the
gratuitous braces, and I understand them, but I personally prefer it
this way because it frees my mind from the permanent effort of
distinguishing loops with one expression from loops with several
expressions. I believe that that distinction is irrelevant. To wit, code
changes a lot back and forth between the two cases. I enjoy not having
additional friction (adding and removing braces) when changing code.
Now take a for_each loop. for_each is the biggest emperor's clothes
event since the tulip craze in Holland. So somebody wants to use
for_each and first tries to get lucky by reusing some little functor in
the standard lib.
for_each(v.begin(), v.end(), stl_functor(args));
If now we need to do stl_functor and something more, there are a few
options. First is to obstinate in using STL amenities and delve into the
unreadability of binders and other good things.
Second is write a your own functor - a hecatomb of code that has to go
outside the scope it's used in, with constructors, destructor, bugs, the
works. The usual soothing comment is that maybe that loop body raised to
the status of a class "could be reused elsewhere" - something that,
let's face it, never ends up happening. Abstractions get reused, not
random loop bodies.
Third is to accept that the emperor is butt-naked and switch to a
regular for loop (or Boost's FOREACH which is so useful, it would be
nice to also have in separation from Boost).
Fourth is to delve into a lambda library, which looks pretty good when
you come from (1) and (2), but not so attractive when you come from (3),
and which further slowly forces on you an entire new language as you try
to scale things.
In any case, my point is that for_each won't scale. You want to do
something little, you got to change things big time.
for_each is a tool good for so few jobs, one could just as well avoid it
entirely instead of sitting down and thinking of the minority of cases
in which it's justifiable - just like goto.
And sorry James for picking on you, but you are just lifting the ball
for a dunk there. for_each could be just as well the epitome of code
that is not "clear and concise" - and gratuitously! Yet I distinctly
remember a post that rewrote a one-liner in oh so many ugly lines just
to accommodate for_each. Guess who wrote it? :o)
Ok, I found it:
http://groups.google.com/group/comp.lang.c++.moderated/msg/609bdccf9665c2d9
I also add the response I gave back then, just because I feel my
lavaliere joke went unnoticed:
http://groups.google.com/group/comp.lang.c++.moderated/msg/e8e8242718116417
You gotta admit I'm at least consistent :o). But your viewpoint seems
quite dissonant to me. How can you internally reconcile the "clear and
terse" ideal with the running faucet in your post that I point to? (Just
like with the "C++ is safer than Java" trial Kanze vs. Alexandrescu, I
am getting ready for a 1800-lines post that I'll take the weekend off to
read and won't be able to answer...)
Andrei
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]