393

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++] may easily result in 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?

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
artlung
  • 33,305
  • 16
  • 69
  • 121
  • 65
    So one should do array[index=index+1] instead of array[++index] (if the former is even permitted!). What a load of hooey. – Lawrence Dol Jun 09 '09 at 17:15
  • 34
    I've not seen Crockford do index=index+1. I've seen him do index+=1. I think that's a reasonable alternative. And it's nice for when you want to change the stride to something besides 1. – Nosredna Jun 09 '09 at 17:51
  • 132
    Personally I am not a big fan of Crockford. He seems to regard anything that has ever caused a bug in his code to be evil. – Paolo Bergantino Jun 10 '09 at 19:41
  • 1
    Ruby lacks the `++` and `--` operators. – Svend Aug 05 '09 at 21:50
  • 39
    In JavaScript you should regard every bug as somewhat evil, since there is no official documentation nor is there a certificate provider nor do you learn JS properly in the University. Crockford and Firebug have filled these holes in JavaScript education. – Stephan Kristyn Sep 19 '10 at 16:54
  • 44
    `++` doesn't cause bugs. Using `++` in "tricky" ways _can_ lead to bugs, especially if more than one person is maintaining the codebase, but that's not a problem with the operator, it's a problem with the programmer. I didn't learn JS at university (because it didn't exist yet), but so what? I did do C, which of course had `++` first, but that also gets a "so what?" I didn't go to university to learn a specific language, I went to learn good programming practices that I can apply to _any_ language. – nnnnnn Nov 09 '11 at 00:37
  • The first video link doesn't work now, it redirects to a video list page. – liori Jul 21 '12 at 13:33
  • 1
    @liori Thanks, updated the link to the blog post from 2010 where first found it. – artlung Jul 21 '12 at 13:52
  • 1
    @nnnnnn if you went to university and learned C, you probably (like most everyone else) learned classical OO programming in strongly typed languages. While I agree with Paulo's assessment, I also agree with Stephan. The problem is, javascript is not like any of the other languages you learned about in school, and when you try to approach it in the same way you would a "classical" language, you can easily run into a lot of problems and create less efficient & manageable code. – 1nfiniti May 02 '13 at 17:04
  • What an utterly **HORRIBLE** video player is this YUI theater? NO TIMELINE **AT ALL**. – MarioDS May 25 '13 at 11:29
  • 2
    @MDeSchaepmeester The "Crockford on JavaScript" videos are also available on YouTube: http://www.youtube.com/watch?v=47Ceot8yqeI&list=PL7664379246A246CB&index=5 – artlung May 28 '13 at 15:03
  • Sheesh, guys, `/*jslint plusplus:true */` ;^) Great links and well-meaning question, but I wonder how this dodged becoming a "closed, not constructive" candidate. – ruffin Nov 28 '13 at 06:17
  • 1
    tl;dr Crockford is known to, let's say, "extravagant" opinions. Sometimes [even *he himself* admits he was wrong in the past](http://javascript.crockford.com/inheritance.html) (see the last paragraph). Treat his hints as just that - *hints and/or proposals*, not *rules*. DC's *often* right. That doesn't mean he's *always* right. Decide for yourself - but be aware that `++` used properly is **highly** idiomatic. Forcibly using `+=` instead will actually make the code **less** readable for any seasoned programmer because of that. –  Jul 18 '17 at 17:32
  • @LawrenceDol No, the point is to not do array access and variable ingrement within the same expression. `index += 1; doSomethingWith(array[index]);` makes it clear what's happening when. – JLRishe Dec 15 '17 at 19:07
  • @JLRishe : And something like `while(idx – Lawrence Dol Dec 16 '17 at 23:44
  • Why not watch Douglas Crockford [explains his opinion](https://www.youtube.com/watch?v=_EANG8ZZbRs&feature=youtu.be&t=42m24s) and decide for yourselves ? – Nir Alfasi Apr 26 '18 at 22:24

17 Answers17

443

My view is to always use ++ and -- by themselves on a single line, as in:

i++;
array[i] = foo;

instead of

array[++i] = foo;

Anything beyond that can be confusing to some programmers and is just not worth it in my view. For loops are an exception, as the use of the increment operator is idiomatic and thus always clear.

Rohit Sharma
  • 3,304
  • 2
  • 19
  • 34
cdmckay
  • 31,832
  • 25
  • 83
  • 114
  • 4
    Yeah, that's what I do too. Hard to go wrong, and easier for other people to figure out what you're doing. – Nosredna Jun 09 '09 at 17:46
  • 74
    That seems to be getting at the core of the issue and my confusion. Used alone, i++; is crystal clear. The minute you add other code around that basic expression, readability and clarity begin to suffer. – artlung Jun 09 '09 at 17:54
  • 5
    Agree, but it's not only JavaScript related – Tobias Feb 04 '13 at 13:37
  • I've only ever seen `++` or `--` as real causes of bugs when programming C, and doing pointer arithmetic. However, I agree that it's easy to miss the increment in `array[++i]` while scanning code quickly. – Luke H May 05 '13 at 10:41
  • 6
    You don't say whether you are writing C or C++. Arguably you should use the prefix increment operator in C++, in case the `i` variable later becomes a composite class, in which case you'd be needlessly creating a temporary object. I find the postfix operator more aesthetically pleasing though. – mc0e Jan 11 '14 at 08:22
  • 4
    I prefer the 1-line version. It reminds of a stack operation. push is array[++i] = foo, pop is bar = array[i--]. (But with 0-based arrays, array[i++] = foo and bar = array[--i] look still better). Another thing, I would hate it if someone added extra code between i++; and array[i] = foo;. – Florian F Jun 22 '16 at 21:38
71

There is a history in C of doing things like:

while (*a++ = *b++);

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

++i = i++;

or

i = i++ + ++i;

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.

Eclipse
  • 44,851
  • 20
  • 112
  • 171
  • 121
    i = i++ + ++i; made my eyes hurt a little - :) – hugoware Jun 09 '09 at 17:38
  • 4
    Mine too. Even if they weren't all the same variable, say I had x = a++ + ++b; -- that combination instantly makes x, a and b harder to hold in my head. now, if each were separate statements on separate lines, as in -- a++; ++b; x = a + b; it would be easier to comprehend on first sight. – artlung Jun 09 '09 at 17:46
  • 1
    But if you keep autoincrement on its own line, there's no reason to ever choose pre-increment over post-increment. So you get a++; b++; x=a+b; – Nosredna Jun 09 '09 at 18:07
  • 11
    Alas, (a++; b++; x=a=b) is not the same value as (a++ + ++b). – Thomas L Holaday Jun 09 '09 at 20:48
  • `++b; x = a + b; ++a;` @Nosredna, there is a reason: pre-increment is ever-so-slightly more efficient – nickf Aug 30 '09 at 06:48
  • 2
    It doesn't get confusing until you try a+++b, a++ +b and a+ ++b – Marius Aug 30 '09 at 06:58
  • 9
    @Marius: `x = a+++b` --> `x = (a++)+b` --> `x = a + b; a++`. The tokeniser is greedy. – Callum Rogers Sep 27 '10 at 13:31
  • 2
    i = i++ + ++i; // Don't do this – senfo Sep 02 '12 at 11:57
  • 17
    For extra job safety, remove the spaces in your last example. – mc0e Jan 11 '14 at 08:28
  • I believe the point is not to avoid for loops but to be more verbose in your incrementing, i += 1 . But this question did bother me initially especially as most text editors when they generate a for loop for you use i++ . – Warren Reilly Feb 07 '15 at 11:10
  • 1
    If people can't read elementary C idioms such as `while (*a++ = *b++);` and think it is "trickery" then they need to learn the language, not only in writing it, but in _reading_ it. Part of the problem is the crap variables names -- when proper names are used the idiom is crystal clear: `while (*pDst++ = *pSrc++);` -- that said, it is almost always better to avoid "one-liners" with excessive increment/decrement ops. – Michaelangel007 Nov 03 '16 at 14:47
  • In what language does ++i = i++; not create compile or runtime error? I tried C#, C and Javascript. – jokogarcia Nov 19 '20 at 17:03
  • @jokogarcia C++ for one, I actually expected it to work in C as well, but it looks like the pre-increment operator returns an rvalue, not an lvalue like it does in c++. It's still undefined behaviour in c++, but it will compile and run. – Eclipse Nov 19 '20 at 17:12
55

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.

Nosredna
  • 83,000
  • 15
  • 95
  • 122
  • Excellent point about the "plusplus" option being just that, an option. Based on yours and other answers I think I'm getting the sense that ++ by itself or a for-loop are not in and of themselves confusing. The second you combine that ++ into another statement you r statement becomes more difficult to read and understand in context. – artlung Jun 09 '09 at 17:43
  • 6
    everyone gets buffer overflows. Even OpenSSH with their open source and their multiple comitees of revision – Eric Jun 10 '09 at 14:22
  • 11
    @Eric Revisiting your five-year-old comment: oh, [how right you were!](https://en.wikipedia.org/wiki/Heartbleed) – wchargin Feb 03 '15 at 00:31
35

In a loop it's harmless, but in an assignment statement it can lead to unexpected results:

var x = 5;
var y = x++; // y is now 5 and x is 6
var z = ++x; // z is now 7 and x is 7

Whitespace between the variable and the operator can lead to unexpected results as well:

a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)

In a closure, unexpected results can be an issue as well:

var foobar = function(i){var count = count || i; return function(){return count++;}}

baz = foobar(1);
baz(); //1
baz(); //2


var alphabeta = function(i){var count = count || i; return function(){return ++count;}}

omega = alphabeta(1);
omega(); //2
omega(); //3

And it triggers automatic semicolon insertion after a newline:

var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6

preincrement/postincrement confusion can produce off-by-one errors that are extremely difficult to diagnose. Fortunately, they are also complete unnecessary. There are better ways to add 1 to a variable.

References

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
  • 18
    But they're not "unexpected" if you understand the operator. It's like not ever using `==` because you don't understand the difference between `==` and `===`. – greg84 Jan 19 '13 at 14:10
  • 1
    Exactly. There's an [C# question](http://stackoverflow.com/questions/3346450/what-is-the-difference-between-i-and-i/3346729#3346729) which debunks false assumptions. – Paul Sweatte Jan 19 '13 at 17:13
  • I think Crockford's point is that most programmers don't fully "understand the operator" even when they think they do; hence, there is danger in using them because the potential for misunderstanding is high. See @Paul's comment about false assumptions which bolsters the argument that people generally misunderstand how prefix and postfix operators actually work. That said, I admit I like using them, but for the sake of others I try to limit their use to idiomatic cases (see [cdmckay's answer](http://stackoverflow.com/a/971442/2502532)). – gfullam Jul 09 '15 at 15:11
  • Your Whitespace link seems to be broken. – Ruslan May 05 '19 at 11:55
  • 2
    What's tricky about your "whitespace" example? I get a straightforward output of `a: 2 b: 0 c: 1`. I don't see anything weird or unexpected in the first example ("assignment statement") either. – Ken Williams Oct 09 '19 at 21:04
18

The "pre" and "post" nature of increment and decrement operators can tend to be confusing for those who are not familiar with them; that's one way in which they can be tricky.

Paul Sonier
  • 38,903
  • 3
  • 77
  • 117
  • 33
    Agreed; however, an experienced professional *should* not be confused. – Nate Jun 09 '09 at 17:11
  • 2
    I think this is similar to the guidance to avoid making everything static or global. There's nothing inherently wrong with it as a programming construct, but ignorant overuse can lead to bad code. – Joel Martinez Jun 09 '09 at 17:16
  • 8
    The question isn't whether a good programmer could "work their way" through the logic - good code ideally doesn't require any work to understand. I think McWafflestix's point is just that you shouldn't write code that upon brief inspection might lead to adding bugs in two weeks or two years. I know I've been guilty of adding code to a routine I didn't fully understand :) – Mike Jun 09 '09 at 17:17
  • 2
    @Mike: yah, notice how I didn't specify whether the operators can be tricky for the original author of the code or for later maintainers. Generally, we try to assume that original coders don't use constructs they're not familiar / comfortable with (sadly, this is frequently an incorrect assumption); however, that familiarity certainly does not extend to maintainers (and, as parenthetically noted above, may not even extend to the orignal author). – Paul Sonier Jun 09 '09 at 17:26
  • 1
    I try to write my code for other programmers to read, but I *don't* try to write it for beginners to read. – Luke H May 05 '13 at 10:42
18

Consider the following code

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[i++] = i++;
    a[i++] = i++;
    a[i++] = i++;

since i++ gets evaluated twice the output is (from vs2005 debugger)

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Now consider the following code :

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = ++i;
    a[++i] = ++i;
    a[++i] = ++i;

Notice that the output is the same. Now you might think that ++i and i++ are the same. They are not

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

Finally consider this code

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = i++;
    a[++i] = i++;
    a[++i] = i++;

The output is now :

    [0] 0   int
    [1] 1   int
    [2] 0   int
    [3] 3   int
    [4] 0   int
    [5] 5   int

So they are not the same, mixing both result in not so intuitive behavior. I think that for loops are ok with ++, but watch out when you have multiple ++ symbols on the same line or same instruction

Eric
  • 19,525
  • 19
  • 84
  • 147
  • 3
    Thanks for doing that experiment. Particularly "simple looking" code, but gets difficult for my brain to hold onto very quickly. Definitely falls into the "tricky" category. – artlung Jun 09 '09 at 18:08
  • @Me & Eric: I didn't vote you down, I know the point you are making is valid, I'm simply countering it. :) – Sam Harwell Aug 05 '09 at 21:52
  • 5
    You've shown that two different piece of code produce different output and this proves it's bad? – nickf Aug 30 '09 at 06:45
  • 7
    the conclusion is "watch out when you have multiple ++ symbols on the same line or same instruction". I don't think you've read it – Eric Aug 30 '09 at 07:07
  • 1
    Eric, I fail to see what you are trying to get at. The code produces exactly the result one would expect. Nothing is counter intuitive here. – Lorenz Lo Sauer Oct 03 '11 at 12:13
  • For novice programmers who presumably have more to gain from visiting SO than experienced programmers, this example illustrates the problem with the trickiness in question (and hence underscores that one should avoid trickiness), so you get my up vote. – squidbe Oct 31 '12 at 20:22
  • 1
    "since i++ gets evaluated twice" - wrong! Modifying a variable twice between sequence points and also using it is invalid in C++ and leads to undefined behaviour. So the compiler may do whatever it wants. The results presented here are accidental of the compiler implementation. – tbleher May 06 '13 at 15:11
  • 1
    I don't understand why this isn't the top answer. This is an actual answer to the question. – mushishi78 Apr 17 '15 at 14:39
  • Please don't post code in C inside a discussion in javascript, so it could be easily pasted and tried. I just tried the first example in the console, and got different results: `0->1, 1->0, 2->3, 3->0, 4->5` – vsync Aug 08 '15 at 16:24
17

In my view, "Explicit is always better than implicit." Because at some point, you may got confused with this increments statement y+ = x++ + ++y. A good programmer always makes his or her code more readable.

artlung
  • 33,305
  • 16
  • 69
  • 121
Sri
  • 4,613
  • 2
  • 39
  • 42
  • 3
    There is nothing implicit in x++ or ++y. – Florian F Jul 19 '16 at 14:23
  • 1
    This *readable code* thing is tricky... I think there is a base line to how simple your code must be, and we -as a community- must thrive a bit and be able to read what's now not readable, such as one-liners with nested ternaries, as to allow more things to kick in. – Hamza Ouaghad Aug 31 '16 at 12:15
15

I've been watching Douglas Crockford's video on this and his explanation for not using increment and decrement is that

  1. It has been used in the past in other languages to break the bounds of arrays and cause all manners of badness and
  2. That it is more confusing and inexperienced JS developers don't know exactly what it does.

Firstly arrays in JavaScript are dynamically sized and so, forgive me if I'm wrong, it is not possible to break the bounds of an array and access data that shouldn't be accessed using this method in JavaScript.

Secondly, should we avoid things that are complicated, surely the problem is not that we have this facility but the problem is that there are developers out there that claim to do JavaScript but don't know how these operators work?? It is simple enough. value++, give me the current value and after the expression add one to it, ++value, increment the value before giving me it.

Expressions like a ++ + ++ b, are simple to work out if you just remember the above.

var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3; 
// a = 2 (equals two after the expression is finished);
// b = 2;

I suppose you've just got to remember who has to read through the code, if you have a team that knows JS inside out then you don't need to worry. If not then comment it, write it differently, etc. Do what you got to do. I don't think increment and decrement is inherently bad or bug generating, or vulnerability creating, maybe just less readable depending on your audience.

Btw, I think Douglas Crockford is a legend anyway, but I think he's caused a lot of scare over an operator that didn't deserve it.

I live to be proven wrong though...

Tony
  • 9,672
  • 3
  • 47
  • 75
Stuart Wakefield
  • 6,294
  • 24
  • 35
14

The most important rationale for avoiding ++ or -- is that the operators return values and cause side effects at the same time, making it harder to reason about the code.

For efficiency's sake, I prefer:

  • ++i when not using the return value (no temporary)
  • i++ when using the return value (no pipeline stall)

I am a fan of Mr. Crockford, but in this case I have to disagree. ++i is 25% less text to parse than i+=1 and arguably clearer.

Hans Malherbe
  • 2,988
  • 24
  • 19
10

Another example, more simple than some others with simple return of incremented value:

function testIncrement1(x) {
    return x++;
}

function testIncrement2(x) {
    return ++x;
}

function testIncrement3(x) {
    return x += 1;
}

console.log(testIncrement1(0)); // 0
console.log(testIncrement2(0)); // 1
console.log(testIncrement3(0)); // 1

As you can see, no post-increment/decrement should be used at return statement, if you want this operator to influence the result. But return doesn't "catch" post-increment/decrement operators:

function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}
ide
  • 19,942
  • 5
  • 64
  • 106
David Levin
  • 6,573
  • 5
  • 48
  • 80
9

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • @downvoter Fascinating. You don't think programmers should be competent in the language? You think they *should* artificially cripple the language? Which is it? No third choice here. – user207421 Jul 16 '13 at 10:29
  • 1
    and an upvote for that COBOL example, makes me even more glad that COBOL mostly died out before I got into coding – Mark K Cowan Feb 28 '15 at 13:21
  • 1
    @MarkCowan I don't see why. My point is about the arbitrary restriction, not the language. The anecdote doesn't indicate anything wrong with Cobol. What needed to die out was that programming shop, and it did. Visit the entrails of any large bank and you'll find Cobol is alive and well. – user207421 Feb 28 '15 at 20:30
3

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.

while ( a < 10 ){
    array[a++] = val
}

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--

burdz
  • 39
  • 3
2

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):

// It's Java, but applies to Js too
vi = list.get ( ++i );
vi1 = list.get ( i + 1 )
out.println ( "Processing values: " + vi + ", " + vi1 )
if ( i < list.size () - 1 ) ...

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:

result = ( ++x - --x ) * x++;

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.

zakmck
  • 2,715
  • 1
  • 37
  • 53
2

As mentioned in some of the existing answers (which annoyingly I'm unable to comment on), the problem is that x++ ++x evaluate to different values (before vs after the increment), which is not obvious and can be very confusing - if that value is used. cdmckay suggests quite wisely to allow use of increment operator, but only in a way that the returned value is not used, e.g. on its own line. I would also include the standard use within a for loop (but only in the third statement, whose return value is not used). I can't think of another example. Having been "burnt" myself, I would recommend the same guideline for other languages as well.

I disagree with the claim that this over-strictness is due to a lot of JS programmers being inexperienced. This is the exact kind of writing typical of "overly-clever" programmers, and I'm sure it's much more common in more traditional languages and with JS developers who have a background in such languages.

Near Privman
  • 3,720
  • 2
  • 16
  • 11
  • 1
    Thanks for the reply. You will need a reputation value of 50 or better in order to comment. See: http://stackoverflow.com/faq – artlung Jan 27 '11 at 17:08
  • 1
    @artlung: I'm aware of that, and of the rationale behind it. I was just saying it's annoying :) – Near Privman Feb 05 '11 at 09:27
1

The operators mean different things when used as prefixes versus suffixes, which can cause hard-to-find bugs. Consider the following example, using bubbleSort:

function bubbleSort(array) {
  if(array.length === 1) return array;

  let end = array.length - 2;
  do {
    for (let i = 0; i < array.length; i += 1) {
      if (array[i] > array[i + 1]) {
        swap(array, i, i + 1);
      }
    }
  } while (end--);
}

bubbleSort([6,5]);

Let's imagine in the course of running our program, we pass a two-item value into our sort function. The code runs fine as-is: the "do/while" loop first executes before reaching the condition. However, the program sees that end is falsy and exits the loop before decrementing the variable.

Now consider the following code, where the -- symbol is used as a prefix, rather than a suffix. This code will enter an infinite loop:

function bubbleSort(array) {
  if(array.length === 1) return array;

  let end = array.length - 2;
  do {
    for (let i = 0; i < array.length; i += 1) {
      if (array[i] > array[i + 1]) {
        swap(array, i, i + 1);
      }
    }
  } while (--end);
}

bubbleSort([6,5]);

Now when we hit the while condition, we decrement the end value before checking it. This returns -1, which in Javascript, is a truthy value.

I don't have a strong opinion on their use one way or the other, but I just wanted to show how they can cause real bugs when used carelessly.

Harrison Cramer
  • 3,792
  • 9
  • 33
  • 61
1

Is Fortran a C-like language? It has neither ++ nor --. Here is how you write a loop:

     integer i, n, sum

      sum = 0
      do 10 i = 1, n
         sum = sum + i
         write(*,*) 'i =', i
         write(*,*) 'sum =', sum
  10  continue

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 ...

      integer i

      do 20 i = 10, 1, -2
         write(*,*) 'i =', i
  20  continue

Is Python C-like? It uses range and list comprehensions and other syntaxes to bypass the need for incrementing an index:

print range(10,1,-2) # prints [10,8.6.4.2]
[x*x for x in range(1,10)] # returns [1,4,9,16 ... ]

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.

Thomas L Holaday
  • 13,614
  • 6
  • 40
  • 51
  • 2
    Yeah, IFortran is from the 1950s, while C is from the 1970s, so maybe no to Fortran being C-like. The example of Python lacking something like the plusplus operator is interesting. Iterating over data structures is more plainly handled in Python, Python being "differently" object oriented JavaScript. Perhaps Crockford's advice is about using more OO-like syntax for iteration. – artlung Jun 09 '09 at 17:34
0

Argument for ++ is that ++ is not applicable for strings which will cause TypeError, which is almost always preferable.