One of the tips for jslint tool is:
++ and --
The ++ (increment) and -- (decrement) operators have been known to contribute to bad code by encouraging excessive trickiness. They are second only to faulty architecture in enabling to viruses and other security menaces. There is a plusplus option that prohibits the use of these operators.
I know that PHP constructs like $foo[$bar++]
has may easily result with off-by-one errors, but I couldn't figure out a better way to control the loop than a while( a < 10 ) do { /* foo */ a++; }
or for (var i=0; i<10; i++) { /* foo */ }
.
Is the jslint highlighting them because there are some similar languages that lack the "++
" and "--
" syntax or handle it differently, or are there other rationales for avoiding "++
" and "--
" that I might be missing?
My 2cents is that they should be avoided in two cases:
1) When you have a variable that is used in many rows and you increase/decrease it on the first statement that uses it (or last, or, even worse, in the middle):
In examples like this, you can easily miss that the variable is auto-incremented/decremented or even remove the first statement. In other words, use it only in very short blocks or where the variable appears in the block on just a couple of close statements.
2) In case of multiple ++ and -- about the same variable in the same statement. It's very hard to remember what happens in cases like this:
Exams and professional tests asks about examples like above and indeed I've stumbled upon this question while looking for documentation about one of them, but in real life one shouldn't be forced to think so much about a single line of code.
If you read JavaScript The Good Parts, you'll see that Crockford's replacement for i++ in a for loop is i+=1 (not i=i+1). That's pretty clean and readable, and is less likely to morph into something "tricky."
Crockford made disallowing autoincrement and autodecrement an option in jsLint. You choose whether to follow the advice or not.
My own personal rule is to not do anything combined with autoincrement or autodecrement.
I've learned from years of experience in C that I don't get buffer overruns (or array index out of bounds) if I keep use of it simple. But I've discovered that I do get buffer overruns if I fall into the "excessively tricky" practice of doing other things in the same statement.
So, for my own rules, the use of i++ as the increment in a for loop is fine.
Is Fortran a C-like language? It has neither ++ nor --. Here is how you write a loop:
The index element i is incremented by the language rules each time through the loop. If you want to increment by something other than 1, count backwards by two for instance, the syntax is ...
Is Python C-like? It uses range and list comprehensions and other syntaxes to bypass the need for incrementing an index:
So based on this rudimentary exploration of exactly two alternatives, language designers may avoid ++ and -- by anticipating use cases and providing an alternate syntax.
Are Fortran and Python notably less of a bug magnet than procedural languages which have ++ and --? I have no evidence.
I claim that Fortran and Python are C-like because I have never met someone fluent in C who could not with 90% accuracy guess correctly the intent of non-obfuscated Fortran or Python.
I think programmers should be competent in the language they are using; use it clearly; and use it well. I don't think they should artificially cripple the language they are using. I speak from experience. I once worked literally next door to a Cobol shop where they didn't use ELSE 'because it was too complicated'. Reductio ad absurdam.
In my experience, ++i or i++ has never caused confusion other than when first learning about how the operator works. It is essential for the most basic for loops and while loops that are taught by any highschool or college course taught in languages where you can use the operator. I personally find doing something like what is below to look and read better than something with a++ being on a separate line.
In the end it is a style preference and not anything more, what is more important is that when you do this in your code you stay consistent so that others working on the same code can follow and not have to process the same functionality in different ways.
Also, Crockford seems to use i-=1, which I find to be harder to read than --i or i--
There is a history in C of doing things like:
to copy a string, perhaps this is the source of the excessive trickery he is referring to.
And there's always the question of what
or
actually do. It's defined in some languages, and in other's there's no guarantee what will happen.
Those examples aside, I don't think there's anything more idiomatic than a for loop that uses
++
to increment. In some cases you could get away with a foreach loop, or a while loop that checked a different condtion. But contorting your code to try and avoid using incrementing is ridiculous.