Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #31190 > unrolled thread

JSlint finds for loops intolerable

Started byemf <emfril@gmail.com>
First post2016-08-28 06:56 -0400
Last post2016-08-28 14:59 -0700
Articles 11 — 6 participants

Back to article view | Back to comp.lang.javascript


Contents

  JSlint finds for loops intolerable emf <emfril@gmail.com> - 2016-08-28 06:56 -0400
    Re: JSlint finds for loops intolerable "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-08-28 14:28 +0200
      Re: JSlint finds for loops intolerable emf <emfril@gmail.com> - 2016-08-29 22:35 -0400
      Re: JSlint finds for loops intolerable Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-08-30 12:11 +0200
        Re: JSlint finds for loops intolerable "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-09-03 20:54 +0200
        Re: JSlint finds for loops intolerable Scott Sauyet <scott@sauyet.com> - 2016-09-03 23:03 +0000
      Re: JSlint finds for loops intolerable Scott Sauyet <scott@sauyet.com> - 2016-09-03 22:47 +0000
    Re: JSlint finds for loops intolerable Lewis Perin <perin@panix.com> - 2016-08-28 16:50 -0400
      Re: JSlint finds for loops intolerable Lewis Perin <perin@panix.com> - 2016-08-28 18:49 -0400
        Re: JSlint finds for loops intolerable Lewis Perin <perin@panix.com> - 2016-08-28 19:13 -0400
    Re: JSlint finds for loops intolerable $Bill <news@todbe.com> - 2016-08-28 14:59 -0700

#31190 — JSlint finds for loops intolerable

Fromemf <emfril@gmail.com>
Date2016-08-28 06:56 -0400
SubjectJSlint finds for loops intolerable
Message-ID<npug18$166s$1@gioia.aioe.org>
In the current JSLint help webpage (http://jslint.com/help.html) it now 
says:

"Tolerate for statement:
true if the for statement should be allowed
It is almost always better to use the array methods instead."

Getting rid of the for loops is a big change. Reflecting on it, however, 
the for loop is an awkward construction -- it's just something you learn 
as a matter of fact when you begin and that time on you take it for 
granted. Instead of

for (var i = 0; i < 10; i += 1) {
     ...
}

the while loop does seem more straightforward:

var i = 0;
while (i < 10) {
     ...
     i += 1;
}

After stopping using for loops, I can imagine a time when I won't be 
able to understand why I once almost always preferred to use them.

I do not understand, however, the comment about array methods. I seldom 
find use for them. Can someone explain what Crawford implies??

Thanks.

Eustace

-- 
The folk oratorios of Mikis Theodorakis
http://emf.neocities.org/mt/folkoratorios.html

[toc] | [next] | [standalone]


#31191

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2016-08-28 14:28 +0200
Message-ID<npuldh$q9l$1@solani.org>
In reply to#31190
On 28.08.2016 at 12:56, emf wrote:

> In the current JSLint help webpage (http://jslint.com/help.html) it now
> says:
> 
> "Tolerate for statement:
> true if the for statement should be allowed
> It is almost always better to use the array methods instead."

JSLint, as well as its author, are highly opinitated. :-)

> Getting rid of the for loops is a big change. Reflecting on it, however,
> the for loop is an awkward construction -- it's just something you learn
> as a matter of fact when you begin and that time on you take it for
> granted. Instead of
> 
> for (var i = 0; i < 10; i += 1) {
>     ...
> }
> 
> the while loop does seem more straightforward:
> 
> var i = 0;
> while (i < 10) {
>     ...
>     i += 1;
> }

I would prefer the `while` only, if you can count down, e.g.

  var i = 10;
  while (--i) {
      ...
  }

> After stopping using for loops, I can imagine a time when I won't be
> able to understand why I once almost always preferred to use them.

Perhaps because they clearly signal a loop with N iterations?

> I do not understand, however, the comment about array methods. I seldom
> find use for them. Can someone explain what Crawford implies??

Instead of looping with `for` or `while` over all elements of an array,
you can instead do:

  myArray.forEach(function(el) {
      ...
  });

Once you get the hang of using Array.prototype.forEach(), you'll
probably find many places where a more specific array method is more
appropriate (for instance, .filter() and map()), and these can simplify
the code (even more).

Note that this programming style is often referred to as applicative or
functional programming.  You may consider to learn about it (I can
recommend <https://drboolean.gitbooks.io/mostly-adequate-guide/content/>).

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#31211

Fromemf <emfril@gmail.com>
Date2016-08-29 22:35 -0400
Message-ID<nq2re1$1rua$1@gioia.aioe.org>
In reply to#31191
On 2016-08-28 08:28, Christoph M. Becker wrote:
> On 28.08.2016 at 12:56, emf wrote:
>
>> In the current JSLint help webpage (http://jslint.com/help.html) it now
>> says:
>>
>> "Tolerate for statement:
>> true if the for statement should be allowed
>> It is almost always better to use the array methods instead."
>
> JSLint, as well as its author, are highly opinitated. :-)

For the time being I've been following its direction, though I'd prefer 
that it wouldn't change that often.
>
>> Getting rid of the for loops is a big change. Reflecting on it, however,
>> the for loop is an awkward construction -- it's just something you learn
>> as a matter of fact when you begin and that time on you take it for
>> granted. Instead of
>>
>> for (var i = 0; i < 10; i += 1) {
>>     ...
>> }
>>
>> the while loop does seem more straightforward:
>>
>> var i = 0;
>> while (i < 10) {
>>     ...
>>     i += 1;
>> }
>
> I would prefer the `while` only, if you can count down, e.g.
>
>   var i = 10;
>   while (--i) {
>       ...
>   }
s
Interesting, however JSLint doesn't tolerate ++ and --. Following its 
trajectory, I wouldn't be surprised if at sone point it will stop 
tolerating += and -= also.

>> After stopping using for loops, I can imagine a time when I won't be
>> able to understand why I once almost always preferred to use them.
>
> Perhaps because they clearly signal a loop with N iterations?

No. from my recollections, it's because when learning programming we 
were taught the for loop first -- maybe because it was the most 
complicated -- and only after we had mastered it, as an afterthought, we 
were taught that there were also the while and the do-while loops.

>> I do not understand, however, the comment about array methods. I seldom
>> find use for them. Can someone explain what Crawford implies??
>
> Instead of looping with `for` or `while` over all elements of an array,
> you can instead do:
>
>   myArray.forEach(function(el) {
>       ...
>   });
>
> Once you get the hang of using Array.prototype.forEach(), you'll
> probably find many places where a more specific array method is more
> appropriate (for instance, .filter() and map()), and these can simplify
> the code (even more).

I'll have to look into this. In the meantime, I'll get used to using the 
while loop.

> Note that this programming style is often referred to as applicative or
> functional programming.  You may consider to learn about it (I can
> recommend <https://drboolean.gitbooks.io/mostly-adequate-guide/content/>).

I downloaded the kindle version of the book. Thanks,

Eustace

-- 
Natal Transits Calculator
http://emf.neocities.org/nt/nataltransits.html

[toc] | [prev] | [next] | [standalone]


#31215

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-08-30 12:11 +0200
Message-ID<3919372.LvFx2qVVIh@PointedEars.de>
In reply to#31191
Christoph M. Becker wrote:

> Once you get the hang of using Array.prototype.forEach(), you'll
> probably find many places where a more specific array method is more
> appropriate (for instance, .filter() and map()), and these can simplify
> the code (even more).

Yes, but:

Efficiency issues aside (while the callback is usually compiled only once, 
there is a *function call* for *each* iteration), one has to be really 
careful when refactoring loops to calls to iterating Array prototype methods 
because then in the callback you are in a *function* where things work 
differently.

For example, it will be difficult to impossible to convert a “for” or 
“while” loop that uses the ”break”, “continue” or “return” statements to 
*equivalent* callback code: “break” and “continue” are not allowed outside 
of loops.  “return” in a callback is equivalent to a “continue” without 
label, but there is no elegant equivalent for ”break” (keeping to call the 
callback and querying a non-local flag so that the callback returns early is 
_not_ elegant IMO), and “return” returns *from the callback*, _not_ from the 
function that called the Array method, so there is no elegant equivalent for 
that either.

One also has to deal with the fact that the “this” value in the callback is 
either the “undefined” value (strict mode) or a reference to the global 
object (otherwise) by default.  In an object’s method that used a loop, you 
have to pass the “this” value of the method as the second argument of a 
iterating native Array prototype method, and if you define your own general 
iteration method, you have to make a provision so that the user can call it 
like that [or they would have to pass theirCallback.bind(theirThis), which 
is comparably inefficient and not backwards-compatible].

I encountered these issues last week when I wanted to convert “for” loops in 
a jQuery-based application to .each() calls, as a jQuery array-like object 
was to be iterated over and this modification would have produced more 
uniform code – code that in the end would not have worked.
 
-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#31222

From"Christoph M. Becker" <cmbecker69@arcor.de>
Date2016-09-03 20:54 +0200
Message-ID<nqf67r$8uj$1@solani.org>
In reply to#31215
On 30.08.2016 at 12:11, Thomas 'PointedEars' Lahn wrote:

> Christoph M. Becker wrote:
> 
>> Once you get the hang of using Array.prototype.forEach(), you'll
>> probably find many places where a more specific array method is more
>> appropriate (for instance, .filter() and map()), and these can simplify
>> the code (even more).
> 
> Yes, but:
> 
> Efficiency issues aside (while the callback is usually compiled only once, 
> there is a *function call* for *each* iteration), one has to be really 
> careful when refactoring loops to calls to iterating Array prototype methods 
> because then in the callback you are in a *function* where things work 
> differently.
> 
> For example, it will be difficult to impossible to convert a “for” or 
> “while” loop that uses the ”break”, “continue” or “return” statements to 
> *equivalent* callback code: “break” and “continue” are not allowed outside 
> of loops.  “return” in a callback is equivalent to a “continue” without 
> label, but there is no elegant equivalent for ”break” (keeping to call the 
> callback and querying a non-local flag so that the callback returns early is 
> _not_ elegant IMO), and “return” returns *from the callback*, _not_ from the 
> function that called the Array method, so there is no elegant equivalent for 
> that either.

Indeed, good caveats!  However, one can come a long way without using
`break`, `continue` or early `return`, and I often prefer that, except
when performance is of utmost importance.  One rather common use of
`break`, for instance, is for (linear) searching/checking;
Array.prototype.every() resp. Array.prototype.some() can be alternatives.

> One also has to deal with the fact that the “this” value in the callback is 
> either the “undefined” value (strict mode) or a reference to the global 
> object (otherwise) by default. […]

In my humble opinion, the dynamic binding of `this` has been a most
unfortunate design decision, even though it allows for some interesting
programming techniques (such as borrowing).

-- 
Christoph M. Becker

[toc] | [prev] | [next] | [standalone]


#31226

FromScott Sauyet <scott@sauyet.com>
Date2016-09-03 23:03 +0000
Message-ID<nqfkra$s0m$1@dont-email.me>
In reply to#31215
Thomas 'PointedEars' Lahn wrote:
> Christoph M. Becker wrote:

>> Once you get the hang of using Array.prototype.forEach(), you'll
>> probably find many places where a more specific array method is more
>> appropriate (for instance, .filter() and map()), and these can
>> simplify the code (even more).
> 
> Yes, but: [ ... ] 
> it will be difficult to impossible to convert a “for” or
> “while” loop that uses the ”break”, “continue” or “return” statements
> to *equivalent* callback code: “break” and “continue” are not allowed
> outside of loops.  “return” in a callback is equivalent to a “continue”
> without label, but there is no elegant equivalent for ”break” (keeping
> to call the callback and querying a non-local flag so that the callback
> returns early is _not_ elegant IMO), and “return” returns *from the
> callback*, _not_ from the function that called the Array method, so
> there is no elegant equivalent for that either. [ ... ]

As mentioned elsewhere on this thread, Crockford and JSLint are quite
opinionated.  I would expect that his response to this would be similar
to my, admittedly opinionated, one: Code written with `break` or
`continue` is most likely poorly written and should be rewritten to avoid
them; it's simply too difficult to reason about for reasons related to
those that caused the programming community to five up `GOTO` statements.

So the point isn't that all existing `for-` loops should be converted to
`filter`, `map`, `some`, `includes`, `reduce`, _et. al._  Instead, one
should write code so that those functions are natural.  *Then* one can
convert it, if there are still actual `for-` loops remaining.

  -- Scott

[toc] | [prev] | [next] | [standalone]


#31225

FromScott Sauyet <scott@sauyet.com>
Date2016-09-03 22:47 +0000
Message-ID<nqfjto$o1c$1@dont-email.me>
In reply to#31191
Christoph M. Becker wrote:
> emf wrote:

>> In the current JSLint help webpage (http://jslint.com/help.html) it now
>> says:
>> 
>> "Tolerate for statement:
>> true if the for statement should be allowed It is almost always better
>> to use the array methods instead."

[ ... ] 

>> I do not understand, however, the comment about array methods. I seldom
>> find use for them. Can someone explain what Crawford implies??
> 
> Instead of looping with `for` or `while` over all elements of an array,
> you can instead do:
> 
>   myArray.forEach(function(el) {
>       ...
>   });
> 
> Once you get the hang of using Array.prototype.forEach(), you'll
> probably find many places where a more specific array method is more
> appropriate (for instance, .filter() and map()), and these can simplify
> the code (even more).

Indeed.  This is the first thing I teach JS developers trying to move 
beyond a junior level.  I emphasize pure, side-effect free functions, and 
once they're doing this, I point out that every `for-` and `forEach-` 
loop remaining is better expressed with one of the standard functions.

 
> Note that this programming style is often referred to as applicative or
> functional programming.  You may consider to learn about it (I can
> recommend
> <https://drboolean.gitbooks.io/mostly-adequate-guide/content/>).

I heartily concur.  That's an excellent book.  I'd also add Reginald 
Braithwaite's _JavaScript Allongé_, either the first edition [1] or the 
second, ES6/ES2015, focused one [2].

  [1]: https://leanpub.com/javascript-allonge
  [2]: https://leanpub.com/javascriptallongesix

  -- Scott

[toc] | [prev] | [next] | [standalone]


#31195

FromLewis Perin <perin@panix.com>
Date2016-08-28 16:50 -0400
Message-ID<pc74m64lis5.fsf@panix1.panix.com>
In reply to#31190
ram@zedat.fu-berlin.de (Stefan Ram) writes:

>emf <emfril@gmail.com> writes:
>>for (var i = 0; i < 10; i += 1) {
>>     ...
>>}
>>var i = 0;
>>while (i < 10) {
>>     ...
>>     i += 1;
>>}
>
>  When one compares this, one can see:
>
>  - The for loop is a Statement.
>
>  - The corresponding sequence that uses
>    »while« is a StatementList with /two/
>    StatementListItems.
>
>  So the corresponding statement would be
>
>{ var i = 0; while( i < 10 ){ ... ++i; }}
>
>  . But »...« could be quite long, so it might
>  be hard to see »++i« at the same time as the
>  start of the loop.
>
>  The for loop-head is one »chunk« in the brain.
>  The control of the while loop is distributed
>  in two, or possibly three, different places, 
>  it cannot be seen as a single idiom by the brain.
>
>  While theoretically the while loop /is/ simpler,
>  it might be too low-level. It seems that the for
>  loop comes more naturally to humans. Especially
>  for counting loops and similar loops.
>
>  Due to hoisting »for( var« might be misleeding,
>  so I deem »for( let« more natural.
>

I’m generally sympathetic to the idea that one criterion for judging
programs is how easy they are to reason about.  But there’s often a
glibness about this when it isn’t clear who is doing the reasoning: a
person or a computer program?

/Lew
---
Lew Perin / perin@acm.org
http://babelcarp.org

[toc] | [prev] | [next] | [standalone]


#31199

FromLewis Perin <perin@panix.com>
Date2016-08-28 18:49 -0400
Message-ID<pc7k2f0se4p.fsf@panix1.panix.com>
In reply to#31195
ram@zedat.fu-berlin.de (Stefan Ram) writes:

>Lewis Perin <perin@panix.com> writes:
>>I'm generally sympathetic to the idea that one criterion for judging
>>programs is how easy they are to reason about.  But there's often a
>>glibness about this when it isn't clear who is doing the reasoning: a
>>person or a computer program?
>
>      »[P]rograms must be written for people to read,
>      and only incidentally for machines to execute.«
>
>    SICP
>
>      "Any fool can write code that a computer can understand.
>      Good programmers write code that humans can understand." 
>
>    Martin Fowler

Sure, and you could quote Knuth on literate programming.  I agree with
all of this.  Apparently I should have elaborated on what I meant by
“reasoning about a program.”  I meant to include under that rubric not
just correctly executing the source code, but also understanding what
the source code was trying to do and satisfying oneself (proving) that
the code achieves that goal under all circumstances.

/Lew
---
Lew Perin / perin@acm.org
http://babelcarp.org

[toc] | [prev] | [next] | [standalone]


#31201

FromLewis Perin <perin@panix.com>
Date2016-08-28 19:13 -0400
Message-ID<pc7fuposd0h.fsf@panix1.panix.com>
In reply to#31199
ram@zedat.fu-berlin.de (Stefan Ram) writes:

>Lewis Perin <perin@panix.com> writes:
>>                              I meant to include under that rubric not
>>just correctly executing the source code, but also understanding what
>>the source code was trying to do and satisfying oneself (proving) that
>>the code achieves that goal under all circumstances.
>
>  And, since we were discussing »while versus for«: do you believe
>  that either of these two (»while« and »for«) is adapted better
>  for this purpose?
>

No.  But once you get beyond this microscopic level, I see no reason to
assume that optimizing for human understanding is the same as optimizing
for machine verifiability.

/Lew
---
Lew Perin / perin@acm.org
http://babelcarp.org

[toc] | [prev] | [next] | [standalone]


#31197

From$Bill <news@todbe.com>
Date2016-08-28 14:59 -0700
Message-ID<npvmrs$uac$1@dont-email.me>
In reply to#31190
On 08-28-16 03:56, emf wrote:
> In the current JSLint help webpage (http://jslint.com/help.html) it now says:
>
> "Tolerate for statement:
> true if the for statement should be allowed
> It is almost always better to use the array methods instead."
>
> Getting rid of the for loops is a big change. Reflecting on it, however, the for loop is an awkward construction -- it's just something you learn as a matter of fact when you begin and that time on you take it for granted. Instead of
>
> for (var i = 0; i < 10; i += 1) {
>     ...
> }
>
> the while loop does seem more straightforward:
>
> var i = 0;
> while (i < 10) {
>     ...
>     i += 1;
> }
>
> After stopping using for loops, I can imagine a time when I won't be able to understand why I once almost always preferred to use them.
>
> I do not understand, however, the comment about array methods. I seldom find use for them. Can someone explain what Crawford implies??

Anyone that's been a programmer prior to HTML is familiar with the standard C for loop.
Seems more straightforward than the 3-piece while loop you have there.
It's concise, self contained on one line and obvious to any programmer that's been
around a while.  Combined with a while and a foreach loop, you have all the looping
constructs you need.  Of course there was no object oriented programming at the time
of invention - everything was procedural which could make a difference.

So "Tolerate For == true;"

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web