Which types of loops are most popular in the programming languages you use?

twitter logo github logo ・1 min read

I was thinking about how in Ruby, we rarely use while or for even though they are available. The language prefers array.each do loops or perhaps n.times do.

How does your language handle these sorts of things?

Do you like the way it's done?

twitter logo DISCUSS (43)
markdown guide
 

Go only has for loops so there's not much of a choice there 😂

In Python I use for as well combined with various iterators. List comprehensions are favored over map and reduce there.

 

I like go's for a lot. It can be a for, a while, or an infinite loop. It's all in how you use it.

The same idea shows up all over the place in it: "here's some minimal core, fiddle it however you want". It's one of its main attractions ♥️

 
 

Honestly it's one of many reasons Go is great, no bikeshedding about iteration

 

Though go is kind of cheating since it's "for" loop can behave in many ways.

 

The for loop in Go is more flexible than the one in C though. I just started with Go, and it's surprising how much they chose to diverge from other C-like languages.

 

I'm actually writing a post which touches on this exactly. Figured I might as well post the relevant part of it here:

let sum = 0;
const myArray = [1, 2, 3, 4, 5, ... 99, 100];
for (let i = 0; i < myArray; i += 1) {
  sum += myArray[i];
}

A vanilla for loop is one of the least parallel constructs that exists in programming. At my last job, one of the teams I led spent months trying to come up with a strategy to convert traditional R lang for-loops into automagically parallel code. It's basically an impossible problem with modern technology. The difficulty arises because of a single pattern possible with for loops.

let runningTotal = 0;
for (let i = 0; i < myArray; i += 1) {
  if (i === 50 && runningTotal > 50) {
    runningTotal = 0;
  }
  runningTotal += Math.random();
}

This code only produces the intended result if it is executed in order, iteration by iteration. If you tried to execute multiple iterations at once, the processor might incorrectly branch based on inaccurate values, which invalidates the result. We would be having a different conversation if this was C code, as the usage is different and there are quite a few tricks the compiler can do with loops. In JavaScript, traditional for loops should only be used if absolutely necessary. Otherwise utilize the following constructs:

map

// in decreasing relevancy :0
const urls = ['google.com', 'yahoo.com', 'aol.com', 'netscape'];
const resultingPromises = urls.map((url) => makHttpRequest(url));
const results = await Promise.all(resultingPromises);

for-each

const urls = ['google.com', 'yahoo.com', 'aol.com', 'netscape'];
// note this is non blocking
urls.forEach(async (url) => {
  try {
    await makHttpRequest(url);
  } catch (err) {
    console.log(`${err} bad practice`);
  }
});
 
 

Yes, and I do everything in my power to stay the hell away. Why would I want an async for loop? That's just a map with extra steps.

Probably the use case hasn't really emerged well. Maybe with an infinite stream of data or if you have to build a lazy parser for something like HTML or XML...

 

Lately, I am liking this way of writing fors in JavaScript:

for(const item of array){
   console.log(item)
}

But I have always used the 'indexed' version:

for(let i = 0;i<array.length;i++){
   console.log(array[i]);
}

There are other ways (forEach for example) but as I know they are usually 'slower' so I always use for :)

 

There are other ways (forEach for example) but as I know they are usually 'slower' so I always use for :)

I think that depends on how much data you're processing. If it's a massive amount, then you may notice it to be a bit slower, but generally the discrepancy is so minimal that it's inconsequential. v8 is actually greatly optimised to use forEach. This is a great talk on the subject by Mathias Bynens: youtube.com/watch?v=m9cTaYI95Zc

So, IMO, it's a far nicer developer experience to use forEach or for of/in in certain cases.

 

F# has some traditional looping constructs like for and while. However, they provide functions that take all the common plumbing out of looping. For example, say you want to loop through a list of items and convert each one to a string. You only have to define how to do it for one item.

let stringify item =
    sprintf "%s x%i" item.Name item.Quantity

// stringify {Name="Confabulator"; Quantity=11} = "Confabulator x11"

Then you use a List operation to perform that transformation on a whole list. Without having to worry about the mechanics of looping through it.

let items = [ ... ]
let strings = List.map stringify items

I really like the separation of concerns. My stringify function only worries about a single item... it doesn't know anything about lists. And since List introduces the need to loop, it also provide functions to do that for you (map, filter, reduce, etc). You simply plug in a function for a single item, and it takes care of doing it to the whole list.

 

From the CoffeeScript language reference:

# Eat lunch.
eat = (food) -> "#{food} eaten."
eat food for food in ['toast', 'cheese', 'wine']

# Fine five course dining.
courses = ['greens', 'caviar', 'truffles', 'roast', 'cake']
menu = (i, dish) -> "Menu Item #{i}: #{dish}" 
menu i + 1, dish for dish, i in courses

# Health conscious meal.
foods = ['broccoli', 'spinach', 'chocolate']
eat food for food in foods when food isnt 'chocolate'

Thanks to map/reduce I don't often use loops, but when I do, I prefer them with coffee.

 

This reminds me of when I wrote a snake game to learn javascript back in 2013. I was very proud of this particular line of code:
snake.eat(food)

 
(loop for i in *random*
   counting (evenp i) into evens
   counting (oddp i) into odds
   summing i into total
   maximizing i into max
   minimizing i into min
   finally (return (list min max total evens odds)))

Or, more realistic example from a project I'm currently working on:

(loop
   with entities = (%get-entities-for-rendering x (+ x w) y (+ y h))
   for (ent-x ent-y ent-fg ent-char) in entities
   for realx = (+ cx (- ent-x x))
   for realy = (+ cy (- ent-y y))
   do
     (tcod:console-set-char-foreground console realx realy ent-fg)
     (tcod:console-set-char console
                            realx
                            realy
                            ent-char))

Common Lisp's loop can do crazy amount of things in a compact form, though there are things that are missing, and the whole thing isn't extensible (though there are library-provided alternatives like iterate that are better in this aspect).

 

In Rust it's quite a simple syntax:

for i in 1..100 {
    println!("{}", i);
}

And for Vec:

let mut nums: Vec<i32> = Vec::new();
nums.push(1);
nums.push(2);
nums.push(3);

for i in nums {
    println!("{}", i);
}

Same syntax for everything \o/

 

With Groovy I use closures inside the each() or eachWithIndex() methods.
You can even build the closure before hand and store it in a variable. Really cool:

Closure cl = { person ->
  println person.name
}

List<Person> people = [...]

people.each(cl)

check out my article on Groovy 😄

 

I generally work with collections in C# so I use ForEach loops a lot.

var numbers = new List<int>() { 1, 2, 3, 4 };

foreach (var number in numbers)
{
    Console.WriteLine(number + 1);
}
 

In PHP foreach pretty much exclusively, I pretty much always need to iterate through everything and the performance difference between for i is not enough to matter. In javascript I like to use the for of syntax.

 

I just published this

and after doing so all the comments I got were that JavaScript developers should only use maps and functional constructs at this point 🤷🏻‍♀️
 

In JavaScript I only use loops in special cases.

Normally, I use filter/map/reduce.

When I have an array of promises I use a for-of-loop with await.

When I see perf problems I use plain for-loops.

 

Ada is based on old-style grammar, so basically we have the usual for loop (but only with +1 or -1 increments, a-la Pascal), while loop and just "loop" for never ending loops (you exit with an exit in the middle).

For loop allows for a very convenient construction. If V is an array you can write

for Idx in V'Range loop 
   V(Idx) := V(Idx)+1;
end loop; 

to run over the index range of V. No risk of buffer overflow or off-by-one errors.

However, recently (Ada 2005 or 2012) the syntax of for has been extended in something that resembles the each loop in Ruby (compatibly with old syntax, of course). If Container is any kind of container (standard or defined by you) you can write

for Item of Container loop
  Item :=  Item + 1;  -- Here Item is an element stored in Container
end loop;

Very convenient. Not much different from the Ruby-sque

container.each do |item|
  item = item+1;
end

The same syntax can be used even if Container is a simple array.

You also have an extension of "old school loop" for a container that is not an array

for Idx in Container.Iterate loop
  Container(Idx) := Container(Idx)+1;
end loop;
 

Would prefer to use forEach more but for loops are faster in older javascript engines so thats what I've been using lately

 

Loop is boring, and recursion is my choice.
hehe)

  void printNextValue(int index, List<String> list) {
        if (list.size() == index) {
            return;
        }

        System.out.println(list.get(index));

        printNextValue(++index, list);
    }

 

Ruby is unique in the “more than one way to do the same thing” and while (no pun intended) for/while loops may not be as common, they were made for developers entering ruby from other languages particularly java and php (I don’t have source for this, will look it up)

 

Ruby is not as unique in that respect as you think.

There are not one, not two, but three ways to loop over an array in JavaScript, and that's not counting special cases like map, reduce, or filter. You have classic C-style for loops, 'for...of' loops (iteration), and the callback-based .forEach() approach.

 

I always used to use foreach in php, but now I’ve swapped to using collection methods in Laravel as they are much more powerful and you can chain them together instead of having multiple loops or nested loops.

Here is an example of map, taken from the docs, which I use a lot

$collection = collect([1, 2, 3, 4, 5]);

$multiplied = $collection->map(function ($item, $key) {
    return $item * 2;
});

$multiplied->all();

// [2, 4, 6, 8, 10]
 

Python got those list comprehensions 👀

numbers = [1, 2, 3, 4, ...]
odds = [
    number
    for number in numbers
    if number % 2 == 1
]
 

Really like the forEach in Java for anything you don't need the return value for. With the logic in a separate method it makes the code both short and readable.
When I do need the return value is stream, and ending in some collect.
But there are still some cases where you need to integration number in the loop, so back to for loops in that case.
With Clojure it's for if I want the return value, or doseq if I don't. It's also common to use reduce for looping when you need the return value.
After reading previous reactions maybe I should give Go a go. Having only one way to do things seems boring. But now I'm sometimes busy with Java changing the loops to someone else's taste to get the merge request approved.

 

In PHP the implementation of collections is quite popular now. This makes map and reduce a breeze. It also makes it more readable.

However I am curious to know why not many people know about and have implemented a Duff’s Device.

This is probably the most optimized way of iteration over items. My take is because it is less readable or understandable.

I have implemented this approach both in JavaScript and PHP. And it is quite faster than normal iterations. I think it can be implemented in any language that supports a while loop.

However only use it where optimizations are needed.

 

I'm a fan of ruby's each method for the fact that you can use it as an interface to make any object enumerable (or what other languages call iterable).

I particularly love it for the lazy evaluation. You can iterate over a collection of infinite size like a prime number generator or like something I did the other day, wrap a large remote resource but make it feel like any other local one. You just stream in as much of it as you need and no more.

 

JavaScript

In production I prefer map, reduce, etc. because I always want to return the same type as input. Sometimes I do use for loop when writing temporary utility scripts, or trying to validate some ideas. It's just because for loop is easy to read even without much context.

 

While not a “loop” in the conventional sense, I’m a big fan of javascript’s [].map which allows you to produce a new array by iterating over the original arrays elements.

 

PHP developer here, so of course foreach, which arguably is one of the most useful structures even in object-oriented PHP (you can really easily iterate through arrays of objects, for example, because PHP treats almost anything as an array, and the most straightforward way to get at its elements, hence often the fastest, is foreach).

 
 

JavaScript has many approaches you can take do the one you like best and gets the job done. My opinion is none are right or wrong those arguments are generally pedantic bikeshedding micro-optimizing.

 

I prefer the callback approach in JavaScript: movies.forEach. Also I am liking this more and more in Java as well with lambdas.

 

(Java uses boolean...)


While(true) {}

or
(Python also uses Boolean, but can convert int to binary to Boolean!)

while 1:
    pass
 

Lambda loops (Array methods) are now the well-deserved default in JS/TS, but I still like the simplicity of a good old for/while loop now and then.

 

I use higher order functions (map, filter, fold) whenever reasonable - easier to think about and maintain in the long run.

 
 
Classic DEV Post from Jan 29

CSS and JS Are at War, Here’s How to Stop It

There are a lot of people who love both JS and UX/CSS. If we stop labeling people just as “JS developers” or “UX developers”, we can achieve a ceasefire in the current “JS vs. CSS” war and achieve a mutually benefiting peace.

Ben Halpern profile image
A Canadian software developer who thinks he’s funny.

Sore eyes?

dev.to now has dark mode.

Go to the "misc" section of your settings and select night theme ❤️