Foreach-loop with break/return vs. while-loop with explicit invariant and post-condition
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
17
down vote
favorite
This is the most popular way (it seems to me) of checking if a value is in an array:
for (int x : array)
if (x == value)
return true;
return false;
However, in a book I’ve read many years ago by, probably, Wirth or Dijkstra, it was said that this style is better (when compared to a while-loop with an exit inside):
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
This way the additional exit condition becomes an explicit part of the loop invariant, there are no hidden conditions and exits inside the loop, everything is more obvious and more in a structured-programming way. I generally preferred this latter pattern whenever possible and used the for
-loop to only iterate from a
to b
.
And yet I cannot say that the first version is less clear. Maybe it is even clearer and easier to understand, at least for very beginners. So I’m still asking myself the question of which one is better?
Maybe someone can give a good rationale in favor of one of the methods?
Update: This is not a question of multiple function return points, lambdas or finding an element in an array per se. It’s about how to write loops with more complex invariants than a single inequality.
Update: OK, I see the point of people who answer and comment: I mixed-in the foreach loop here, which itself is already much more clear and readable than a while-loop. I should not have done that. But this is also an interesting question, so let's leave it as it is: foreach-loop and an extra condition inside, or a while-loop with an explicit loop invariant and a post-condition after. It seems that the foreach-loop with a condition and an exit/break is winning. I will create an additional question without the foreach-loop (for a linked list).
coding-style search loops invariants structured-programming
 |Â
show 2 more comments
up vote
17
down vote
favorite
This is the most popular way (it seems to me) of checking if a value is in an array:
for (int x : array)
if (x == value)
return true;
return false;
However, in a book I’ve read many years ago by, probably, Wirth or Dijkstra, it was said that this style is better (when compared to a while-loop with an exit inside):
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
This way the additional exit condition becomes an explicit part of the loop invariant, there are no hidden conditions and exits inside the loop, everything is more obvious and more in a structured-programming way. I generally preferred this latter pattern whenever possible and used the for
-loop to only iterate from a
to b
.
And yet I cannot say that the first version is less clear. Maybe it is even clearer and easier to understand, at least for very beginners. So I’m still asking myself the question of which one is better?
Maybe someone can give a good rationale in favor of one of the methods?
Update: This is not a question of multiple function return points, lambdas or finding an element in an array per se. It’s about how to write loops with more complex invariants than a single inequality.
Update: OK, I see the point of people who answer and comment: I mixed-in the foreach loop here, which itself is already much more clear and readable than a while-loop. I should not have done that. But this is also an interesting question, so let's leave it as it is: foreach-loop and an extra condition inside, or a while-loop with an explicit loop invariant and a post-condition after. It seems that the foreach-loop with a condition and an exit/break is winning. I will create an additional question without the foreach-loop (for a linked list).
coding-style search loops invariants structured-programming
2
The code examples cited here mix several different issues. Early & multiple returns (which for me go to the size of the method (not shown)), array search (which begs for a discussion involving lambdas), foreach vs. direct indexing... This question would be more clear and easier to answer if it focused on just one of these issues at a time.
– Erik Eidt
Aug 10 at 15:38
5
Possible duplicate of Should methods always return from one place?
– gnat
Aug 10 at 15:45
1
I know those are examples, but there are languages that have APIs to handle exactly that use case. I.e.collection.contains(foo)
– Berin Loritsch
Aug 10 at 20:17
2
You may want to find the book and reread it now to see what it actually said.
– Thorbjørn Ravn Andersen
Aug 11 at 6:32
1
"Better" is a highly subjective word. That said, one can tell at a glance what the first version is doing. That the second version does exactly the same thing takes some scrutiny.
– David Hammen
Aug 11 at 22:40
 |Â
show 2 more comments
up vote
17
down vote
favorite
up vote
17
down vote
favorite
This is the most popular way (it seems to me) of checking if a value is in an array:
for (int x : array)
if (x == value)
return true;
return false;
However, in a book I’ve read many years ago by, probably, Wirth or Dijkstra, it was said that this style is better (when compared to a while-loop with an exit inside):
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
This way the additional exit condition becomes an explicit part of the loop invariant, there are no hidden conditions and exits inside the loop, everything is more obvious and more in a structured-programming way. I generally preferred this latter pattern whenever possible and used the for
-loop to only iterate from a
to b
.
And yet I cannot say that the first version is less clear. Maybe it is even clearer and easier to understand, at least for very beginners. So I’m still asking myself the question of which one is better?
Maybe someone can give a good rationale in favor of one of the methods?
Update: This is not a question of multiple function return points, lambdas or finding an element in an array per se. It’s about how to write loops with more complex invariants than a single inequality.
Update: OK, I see the point of people who answer and comment: I mixed-in the foreach loop here, which itself is already much more clear and readable than a while-loop. I should not have done that. But this is also an interesting question, so let's leave it as it is: foreach-loop and an extra condition inside, or a while-loop with an explicit loop invariant and a post-condition after. It seems that the foreach-loop with a condition and an exit/break is winning. I will create an additional question without the foreach-loop (for a linked list).
coding-style search loops invariants structured-programming
This is the most popular way (it seems to me) of checking if a value is in an array:
for (int x : array)
if (x == value)
return true;
return false;
However, in a book I’ve read many years ago by, probably, Wirth or Dijkstra, it was said that this style is better (when compared to a while-loop with an exit inside):
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
This way the additional exit condition becomes an explicit part of the loop invariant, there are no hidden conditions and exits inside the loop, everything is more obvious and more in a structured-programming way. I generally preferred this latter pattern whenever possible and used the for
-loop to only iterate from a
to b
.
And yet I cannot say that the first version is less clear. Maybe it is even clearer and easier to understand, at least for very beginners. So I’m still asking myself the question of which one is better?
Maybe someone can give a good rationale in favor of one of the methods?
Update: This is not a question of multiple function return points, lambdas or finding an element in an array per se. It’s about how to write loops with more complex invariants than a single inequality.
Update: OK, I see the point of people who answer and comment: I mixed-in the foreach loop here, which itself is already much more clear and readable than a while-loop. I should not have done that. But this is also an interesting question, so let's leave it as it is: foreach-loop and an extra condition inside, or a while-loop with an explicit loop invariant and a post-condition after. It seems that the foreach-loop with a condition and an exit/break is winning. I will create an additional question without the foreach-loop (for a linked list).
coding-style search loops invariants structured-programming
edited Aug 10 at 22:36
asked Aug 10 at 15:08


Danila Piatov
9417
9417
2
The code examples cited here mix several different issues. Early & multiple returns (which for me go to the size of the method (not shown)), array search (which begs for a discussion involving lambdas), foreach vs. direct indexing... This question would be more clear and easier to answer if it focused on just one of these issues at a time.
– Erik Eidt
Aug 10 at 15:38
5
Possible duplicate of Should methods always return from one place?
– gnat
Aug 10 at 15:45
1
I know those are examples, but there are languages that have APIs to handle exactly that use case. I.e.collection.contains(foo)
– Berin Loritsch
Aug 10 at 20:17
2
You may want to find the book and reread it now to see what it actually said.
– Thorbjørn Ravn Andersen
Aug 11 at 6:32
1
"Better" is a highly subjective word. That said, one can tell at a glance what the first version is doing. That the second version does exactly the same thing takes some scrutiny.
– David Hammen
Aug 11 at 22:40
 |Â
show 2 more comments
2
The code examples cited here mix several different issues. Early & multiple returns (which for me go to the size of the method (not shown)), array search (which begs for a discussion involving lambdas), foreach vs. direct indexing... This question would be more clear and easier to answer if it focused on just one of these issues at a time.
– Erik Eidt
Aug 10 at 15:38
5
Possible duplicate of Should methods always return from one place?
– gnat
Aug 10 at 15:45
1
I know those are examples, but there are languages that have APIs to handle exactly that use case. I.e.collection.contains(foo)
– Berin Loritsch
Aug 10 at 20:17
2
You may want to find the book and reread it now to see what it actually said.
– Thorbjørn Ravn Andersen
Aug 11 at 6:32
1
"Better" is a highly subjective word. That said, one can tell at a glance what the first version is doing. That the second version does exactly the same thing takes some scrutiny.
– David Hammen
Aug 11 at 22:40
2
2
The code examples cited here mix several different issues. Early & multiple returns (which for me go to the size of the method (not shown)), array search (which begs for a discussion involving lambdas), foreach vs. direct indexing... This question would be more clear and easier to answer if it focused on just one of these issues at a time.
– Erik Eidt
Aug 10 at 15:38
The code examples cited here mix several different issues. Early & multiple returns (which for me go to the size of the method (not shown)), array search (which begs for a discussion involving lambdas), foreach vs. direct indexing... This question would be more clear and easier to answer if it focused on just one of these issues at a time.
– Erik Eidt
Aug 10 at 15:38
5
5
Possible duplicate of Should methods always return from one place?
– gnat
Aug 10 at 15:45
Possible duplicate of Should methods always return from one place?
– gnat
Aug 10 at 15:45
1
1
I know those are examples, but there are languages that have APIs to handle exactly that use case. I.e.
collection.contains(foo)
– Berin Loritsch
Aug 10 at 20:17
I know those are examples, but there are languages that have APIs to handle exactly that use case. I.e.
collection.contains(foo)
– Berin Loritsch
Aug 10 at 20:17
2
2
You may want to find the book and reread it now to see what it actually said.
– Thorbjørn Ravn Andersen
Aug 11 at 6:32
You may want to find the book and reread it now to see what it actually said.
– Thorbjørn Ravn Andersen
Aug 11 at 6:32
1
1
"Better" is a highly subjective word. That said, one can tell at a glance what the first version is doing. That the second version does exactly the same thing takes some scrutiny.
– David Hammen
Aug 11 at 22:40
"Better" is a highly subjective word. That said, one can tell at a glance what the first version is doing. That the second version does exactly the same thing takes some scrutiny.
– David Hammen
Aug 11 at 22:40
 |Â
show 2 more comments
6 Answers
6
active
oldest
votes
up vote
20
down vote
accepted
I think for simple loops, such as these, the standard first syntax is much clearer. Some people consider multiple returns confusing or a code smell, but for a piece of code this small, I do not believe this is a real issue.
It gets a bit more debatable for more complex loops. If the loop's contents cannot fit on your screen and has several returns in the loop, there is an argument to be made that the multiple exit points can make the code more difficult to maintain. For example, if you had to ensure some state maintenance method ran before exiting the function, it would be easy to miss adding it to one of the return statements and you would cause a bug. If all the end conditions can be checked in a while loop, you only have one exit point and can add this code after it.
That said, with loops especially it is good to try and put as much logic as possible into separate methods. This avoids a lot of cases where the second method would have advantages. Lean loops with clearly separated logic will matter more than which of these styles you use. Also, if most of your application's code base is using one style, you should stick with that style.
add a comment |Â
up vote
56
down vote
This is easy.
Almost nothing matters more than clarity to the reader. The first variant I found incredibly simple and clear.
The second 'improved' version, I had to read several times and make sure all the edge conditions were right.
There is ZERO DOUBT which is better coding style (the first is much better).
Now - what is CLEAR to people may vary from person to person. I'm not sure there are any objective standards for that (though posting to a forum like this and getting a variety of peoples inputs can help).
In this particular case, however, I can tell you why the first algorithm is more clear: I know what the C++ iterate over a container syntax looks like and does. I've internalized it. Someone UNFAMILIAR (its new syntax) with that syntax might prefer the second variation.
But once you know and understand that new syntax, its a basic concept you can just use. With the loop iteration (second) approach, you have to carefully check that the user is CORRECTLY checking for all the edge conditions to loop over the entire array (e.g. less than in stead of less-or-equal, same index used for test and for indexing etc).
4
New is relative, as it was already in the 2011 standard. Also, the second demo is obviously not C++.
– Deduplicator
Aug 10 at 16:30
An alternate solution if you want to use a single exit point would be to set a flaglongerLength = true
, thenreturn longerLength
.
– Cullub
Aug 10 at 17:48
@Deduplicator Why isn't the second demo C++? I don't see why not or am I missing something obvious?
– Rakete1111
Aug 10 at 18:59
2
@Rakete1111 Raw arrays don't have any properties likelength
. If it were actually declared as an array and not a pointer, they could usesizeof
, or if it were anstd::array
, the correct member function issize()
, there isn't alength
property.
– IllusiveBrian
Aug 10 at 19:14
@IllusiveBrian:sizeof
would be in bytes... The most generic since C++17 isstd::size()
.
– Deduplicator
Aug 10 at 19:51
 |Â
show 4 more comments
up vote
10
down vote
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
[…] everything is more obvious and more in a structured-programming way.
Not quite. The variable i
exists outside the while loop here and is thus part of the outer scope, while (pun intended) x
of the for
-loop exists only within the scope of the loop. Scope is one very important way to introduce structure to programming.
1
Please see en.wikipedia.org/wiki/Structured_programming
– ruakh
Aug 10 at 19:34
@ruakh I'm not sure what to take away from your comment. It comes across as somewhat passive-aggressive, as if my answer opposes what's written on the wiki page. Please elaborate.
– null
Aug 14 at 15:27
"Structured programming" is a term of art with a specific meaning, and the OP is objectively correct that version #2 conforms to the rules of structured programming while version #1 does not. From your answer, it seemed that you were not familiar with the term of art, and were interpreting the term literally. I'm not sure why my comment comes across as passive-aggressive; I meant it simply as informative.
– ruakh
Aug 14 at 16:25
@ruakh I disagree that version #2 conforms to the rules more in every aspect and explained that in my answer.
– null
Aug 14 at 17:25
You say "I disagree" as if it were a subjective thing, but it's not. Returning from inside a loop is a categorical violation of the rules of structured programming. I'm sure that many structured-programming enthusiasts are fans of minimally-scoped variables, but if you reduce a variable's scope by departing from structured programming, then you have departed from structured programming, period, and reducing the variable's scope doesn't undo that.
– ruakh
Aug 14 at 18:27
 |Â
show 1 more comment
up vote
2
down vote
The two loops have different semantics:
The first loop simply answers a simple yes/no question:
"Does the array contain the object I'm looking for?"
It does so in the most brief manner possible.The second loop answers the question:
"If the array contains the object I'm looking for,
what is the index of the first match?"
Again, it does so in the most brief manner possible.
Since the answer to the second question does provide strictly more information than the answer to the first, you can choose to answer the second question and then derive the answer of the first question. That is what the line return i < array.length;
does, anyway.
I believe that it's usually best to just use the tool that fits the purpose unless you can reuse an already existing, more flexible tool. I.e.:
- Using the first variant of the loop is fine.
- Changing the first variant to just set a
bool
variable and break is also fine. (Avoids secondreturn
statement, answer is available in a variable instead of a function return.) - Using
std::find
is fine (code reuse!). - However, explicitly coding a find and then reducing the answer to a
bool
is not.
Would be nice if the downvoters would leave a comment...
– cmaster
Aug 14 at 12:41
add a comment |Â
up vote
2
down vote
I'll suggest a third option altogether:
return array.find(value);
There are many different reasons to iterate over an array: Check if a specific value exists, transform the array into another array, calculate an aggregate value, filter some values out of the array... If you use a plain for loop, it's unclear at a glance specifically how the for loop is being used. However, most modern languages have rich APIs on their array data structures that make these different intents very explicit.
Compare transforming one array into another with a for loop:
int doubledArray = new int[array.length];
for (int i = 0; i < array.length; i++)
doubledArray[i] = array[i] * 2;
and using a JavaScript-style map
function:
array.map((value) => value * 2);
Or summing an array:
int sum = 0;
for (int i = 0; i < array.length; i++)
sum += array[i];
versus:
array.reduce(
(sum, nextValue) => sum + nextValue,
0
);
How long does it take you to understand what this does?
int newArray = new int[array.length];
int numValuesAdded = 0;
for (int i = 0; i < array.length; i++)
if (array[i] >= 0)
newArray[numValuesAdded] = array[i];
numValuesAdded++;
versus
array.filter((value) => (value >= 0));
In all three cases, while the for loop is certainly readable, you have to spend a few moments to figure out how the for loop is being used and checking that all of the counters and exit conditions are correct. The modern lambda-style functions make the purposes of the loops extremely explicit, and you know for certain that the API functions being called are implemented correctly.
Most modern languages, including JavaScript, Ruby, C#, and Java, use this style of functional interaction with arrays and similar collections.
In general, while I don't think using for loops is necessarily wrong, and it is a matter of personal taste, I've been finding myself strongly favoring using this style of working with arrays. This is specifically because of the increased clarity in determining what each loop is doing. If your language has similar features or tools in its standard libraries, I suggest you consider adopting this style as well!
2
Recommendingarray.find
begs the question, as we then have to discuss the best way to implementarray.find
. Unless you're using hardware with a built-infind
operation, we have to write a loop there.
– Barmar
Aug 11 at 0:44
2
@Barmar I disagree. As I indicated in my answer, a lot of heavily-used languages provide functions likefind
in their standard libraries. Undoubtedly, these libraries implementfind
and its kin using for loops, but that's what a good function does: it abstracts the technical details away from the function's consumer, allowing that programmer to not need to think about those details. So even thoughfind
is likely implemented with a for loop, it still helps make code more readable, and since it's frequently in the standard library, using it adds no meaningful overhead or risk.
– Kevin
Aug 11 at 0:54
4
But a software engineer has to implement these libraries. Don't the same software engineering principles apply to library authors as application programmers? The question is about writing loops in general, not the best way to search for an array element in a particular language
– Barmar
Aug 11 at 1:02
4
To put it another way, searching for an array element is just a simple example that he used to demonstrate the different looping techniques.
– Barmar
Aug 11 at 1:06
add a comment |Â
up vote
-2
down vote
It all boils down to precisely what is meant by 'better'. For practical programmers, it generally means efficient - i.e in this case, exiting directly from the loop avoids one extra comparison, and returning a Boolean constant avoids a duplicate comparison; this saves cycles. Dijkstra is more concerned with making code that is easier to prove correct. [it has seemed to me that CS education in Europe takes 'proving code correctness' far more seriously than CS education in the US, where economic forces tend to dominate coding practice]
3
PMar, performance-wise both loops are pretty much equivalent — they both have two comparisons.
– Danila Piatov
Aug 10 at 21:19
1
If one really cared about performance, one would use a faster algorithm. e.g. sort the array and do a binary search, or use a Hashtable.
– user949300
Aug 11 at 16:30
Danila - you don’t know what data structure is behind this. An iterator is always fast. Indexed access can be linear time, and length need not even exist.
– gnasher729
Aug 15 at 7:52
add a comment |Â
protected by gnat Aug 11 at 15:28
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
20
down vote
accepted
I think for simple loops, such as these, the standard first syntax is much clearer. Some people consider multiple returns confusing or a code smell, but for a piece of code this small, I do not believe this is a real issue.
It gets a bit more debatable for more complex loops. If the loop's contents cannot fit on your screen and has several returns in the loop, there is an argument to be made that the multiple exit points can make the code more difficult to maintain. For example, if you had to ensure some state maintenance method ran before exiting the function, it would be easy to miss adding it to one of the return statements and you would cause a bug. If all the end conditions can be checked in a while loop, you only have one exit point and can add this code after it.
That said, with loops especially it is good to try and put as much logic as possible into separate methods. This avoids a lot of cases where the second method would have advantages. Lean loops with clearly separated logic will matter more than which of these styles you use. Also, if most of your application's code base is using one style, you should stick with that style.
add a comment |Â
up vote
20
down vote
accepted
I think for simple loops, such as these, the standard first syntax is much clearer. Some people consider multiple returns confusing or a code smell, but for a piece of code this small, I do not believe this is a real issue.
It gets a bit more debatable for more complex loops. If the loop's contents cannot fit on your screen and has several returns in the loop, there is an argument to be made that the multiple exit points can make the code more difficult to maintain. For example, if you had to ensure some state maintenance method ran before exiting the function, it would be easy to miss adding it to one of the return statements and you would cause a bug. If all the end conditions can be checked in a while loop, you only have one exit point and can add this code after it.
That said, with loops especially it is good to try and put as much logic as possible into separate methods. This avoids a lot of cases where the second method would have advantages. Lean loops with clearly separated logic will matter more than which of these styles you use. Also, if most of your application's code base is using one style, you should stick with that style.
add a comment |Â
up vote
20
down vote
accepted
up vote
20
down vote
accepted
I think for simple loops, such as these, the standard first syntax is much clearer. Some people consider multiple returns confusing or a code smell, but for a piece of code this small, I do not believe this is a real issue.
It gets a bit more debatable for more complex loops. If the loop's contents cannot fit on your screen and has several returns in the loop, there is an argument to be made that the multiple exit points can make the code more difficult to maintain. For example, if you had to ensure some state maintenance method ran before exiting the function, it would be easy to miss adding it to one of the return statements and you would cause a bug. If all the end conditions can be checked in a while loop, you only have one exit point and can add this code after it.
That said, with loops especially it is good to try and put as much logic as possible into separate methods. This avoids a lot of cases where the second method would have advantages. Lean loops with clearly separated logic will matter more than which of these styles you use. Also, if most of your application's code base is using one style, you should stick with that style.
I think for simple loops, such as these, the standard first syntax is much clearer. Some people consider multiple returns confusing or a code smell, but for a piece of code this small, I do not believe this is a real issue.
It gets a bit more debatable for more complex loops. If the loop's contents cannot fit on your screen and has several returns in the loop, there is an argument to be made that the multiple exit points can make the code more difficult to maintain. For example, if you had to ensure some state maintenance method ran before exiting the function, it would be easy to miss adding it to one of the return statements and you would cause a bug. If all the end conditions can be checked in a while loop, you only have one exit point and can add this code after it.
That said, with loops especially it is good to try and put as much logic as possible into separate methods. This avoids a lot of cases where the second method would have advantages. Lean loops with clearly separated logic will matter more than which of these styles you use. Also, if most of your application's code base is using one style, you should stick with that style.
edited Aug 10 at 20:13
answered Aug 10 at 16:37
Nathanael
6999
6999
add a comment |Â
add a comment |Â
up vote
56
down vote
This is easy.
Almost nothing matters more than clarity to the reader. The first variant I found incredibly simple and clear.
The second 'improved' version, I had to read several times and make sure all the edge conditions were right.
There is ZERO DOUBT which is better coding style (the first is much better).
Now - what is CLEAR to people may vary from person to person. I'm not sure there are any objective standards for that (though posting to a forum like this and getting a variety of peoples inputs can help).
In this particular case, however, I can tell you why the first algorithm is more clear: I know what the C++ iterate over a container syntax looks like and does. I've internalized it. Someone UNFAMILIAR (its new syntax) with that syntax might prefer the second variation.
But once you know and understand that new syntax, its a basic concept you can just use. With the loop iteration (second) approach, you have to carefully check that the user is CORRECTLY checking for all the edge conditions to loop over the entire array (e.g. less than in stead of less-or-equal, same index used for test and for indexing etc).
4
New is relative, as it was already in the 2011 standard. Also, the second demo is obviously not C++.
– Deduplicator
Aug 10 at 16:30
An alternate solution if you want to use a single exit point would be to set a flaglongerLength = true
, thenreturn longerLength
.
– Cullub
Aug 10 at 17:48
@Deduplicator Why isn't the second demo C++? I don't see why not or am I missing something obvious?
– Rakete1111
Aug 10 at 18:59
2
@Rakete1111 Raw arrays don't have any properties likelength
. If it were actually declared as an array and not a pointer, they could usesizeof
, or if it were anstd::array
, the correct member function issize()
, there isn't alength
property.
– IllusiveBrian
Aug 10 at 19:14
@IllusiveBrian:sizeof
would be in bytes... The most generic since C++17 isstd::size()
.
– Deduplicator
Aug 10 at 19:51
 |Â
show 4 more comments
up vote
56
down vote
This is easy.
Almost nothing matters more than clarity to the reader. The first variant I found incredibly simple and clear.
The second 'improved' version, I had to read several times and make sure all the edge conditions were right.
There is ZERO DOUBT which is better coding style (the first is much better).
Now - what is CLEAR to people may vary from person to person. I'm not sure there are any objective standards for that (though posting to a forum like this and getting a variety of peoples inputs can help).
In this particular case, however, I can tell you why the first algorithm is more clear: I know what the C++ iterate over a container syntax looks like and does. I've internalized it. Someone UNFAMILIAR (its new syntax) with that syntax might prefer the second variation.
But once you know and understand that new syntax, its a basic concept you can just use. With the loop iteration (second) approach, you have to carefully check that the user is CORRECTLY checking for all the edge conditions to loop over the entire array (e.g. less than in stead of less-or-equal, same index used for test and for indexing etc).
4
New is relative, as it was already in the 2011 standard. Also, the second demo is obviously not C++.
– Deduplicator
Aug 10 at 16:30
An alternate solution if you want to use a single exit point would be to set a flaglongerLength = true
, thenreturn longerLength
.
– Cullub
Aug 10 at 17:48
@Deduplicator Why isn't the second demo C++? I don't see why not or am I missing something obvious?
– Rakete1111
Aug 10 at 18:59
2
@Rakete1111 Raw arrays don't have any properties likelength
. If it were actually declared as an array and not a pointer, they could usesizeof
, or if it were anstd::array
, the correct member function issize()
, there isn't alength
property.
– IllusiveBrian
Aug 10 at 19:14
@IllusiveBrian:sizeof
would be in bytes... The most generic since C++17 isstd::size()
.
– Deduplicator
Aug 10 at 19:51
 |Â
show 4 more comments
up vote
56
down vote
up vote
56
down vote
This is easy.
Almost nothing matters more than clarity to the reader. The first variant I found incredibly simple and clear.
The second 'improved' version, I had to read several times and make sure all the edge conditions were right.
There is ZERO DOUBT which is better coding style (the first is much better).
Now - what is CLEAR to people may vary from person to person. I'm not sure there are any objective standards for that (though posting to a forum like this and getting a variety of peoples inputs can help).
In this particular case, however, I can tell you why the first algorithm is more clear: I know what the C++ iterate over a container syntax looks like and does. I've internalized it. Someone UNFAMILIAR (its new syntax) with that syntax might prefer the second variation.
But once you know and understand that new syntax, its a basic concept you can just use. With the loop iteration (second) approach, you have to carefully check that the user is CORRECTLY checking for all the edge conditions to loop over the entire array (e.g. less than in stead of less-or-equal, same index used for test and for indexing etc).
This is easy.
Almost nothing matters more than clarity to the reader. The first variant I found incredibly simple and clear.
The second 'improved' version, I had to read several times and make sure all the edge conditions were right.
There is ZERO DOUBT which is better coding style (the first is much better).
Now - what is CLEAR to people may vary from person to person. I'm not sure there are any objective standards for that (though posting to a forum like this and getting a variety of peoples inputs can help).
In this particular case, however, I can tell you why the first algorithm is more clear: I know what the C++ iterate over a container syntax looks like and does. I've internalized it. Someone UNFAMILIAR (its new syntax) with that syntax might prefer the second variation.
But once you know and understand that new syntax, its a basic concept you can just use. With the loop iteration (second) approach, you have to carefully check that the user is CORRECTLY checking for all the edge conditions to loop over the entire array (e.g. less than in stead of less-or-equal, same index used for test and for indexing etc).
answered Aug 10 at 15:31


Lewis Pringle
2,4761313
2,4761313
4
New is relative, as it was already in the 2011 standard. Also, the second demo is obviously not C++.
– Deduplicator
Aug 10 at 16:30
An alternate solution if you want to use a single exit point would be to set a flaglongerLength = true
, thenreturn longerLength
.
– Cullub
Aug 10 at 17:48
@Deduplicator Why isn't the second demo C++? I don't see why not or am I missing something obvious?
– Rakete1111
Aug 10 at 18:59
2
@Rakete1111 Raw arrays don't have any properties likelength
. If it were actually declared as an array and not a pointer, they could usesizeof
, or if it were anstd::array
, the correct member function issize()
, there isn't alength
property.
– IllusiveBrian
Aug 10 at 19:14
@IllusiveBrian:sizeof
would be in bytes... The most generic since C++17 isstd::size()
.
– Deduplicator
Aug 10 at 19:51
 |Â
show 4 more comments
4
New is relative, as it was already in the 2011 standard. Also, the second demo is obviously not C++.
– Deduplicator
Aug 10 at 16:30
An alternate solution if you want to use a single exit point would be to set a flaglongerLength = true
, thenreturn longerLength
.
– Cullub
Aug 10 at 17:48
@Deduplicator Why isn't the second demo C++? I don't see why not or am I missing something obvious?
– Rakete1111
Aug 10 at 18:59
2
@Rakete1111 Raw arrays don't have any properties likelength
. If it were actually declared as an array and not a pointer, they could usesizeof
, or if it were anstd::array
, the correct member function issize()
, there isn't alength
property.
– IllusiveBrian
Aug 10 at 19:14
@IllusiveBrian:sizeof
would be in bytes... The most generic since C++17 isstd::size()
.
– Deduplicator
Aug 10 at 19:51
4
4
New is relative, as it was already in the 2011 standard. Also, the second demo is obviously not C++.
– Deduplicator
Aug 10 at 16:30
New is relative, as it was already in the 2011 standard. Also, the second demo is obviously not C++.
– Deduplicator
Aug 10 at 16:30
An alternate solution if you want to use a single exit point would be to set a flag
longerLength = true
, then return longerLength
.– Cullub
Aug 10 at 17:48
An alternate solution if you want to use a single exit point would be to set a flag
longerLength = true
, then return longerLength
.– Cullub
Aug 10 at 17:48
@Deduplicator Why isn't the second demo C++? I don't see why not or am I missing something obvious?
– Rakete1111
Aug 10 at 18:59
@Deduplicator Why isn't the second demo C++? I don't see why not or am I missing something obvious?
– Rakete1111
Aug 10 at 18:59
2
2
@Rakete1111 Raw arrays don't have any properties like
length
. If it were actually declared as an array and not a pointer, they could use sizeof
, or if it were an std::array
, the correct member function is size()
, there isn't a length
property.– IllusiveBrian
Aug 10 at 19:14
@Rakete1111 Raw arrays don't have any properties like
length
. If it were actually declared as an array and not a pointer, they could use sizeof
, or if it were an std::array
, the correct member function is size()
, there isn't a length
property.– IllusiveBrian
Aug 10 at 19:14
@IllusiveBrian:
sizeof
would be in bytes... The most generic since C++17 is std::size()
.– Deduplicator
Aug 10 at 19:51
@IllusiveBrian:
sizeof
would be in bytes... The most generic since C++17 is std::size()
.– Deduplicator
Aug 10 at 19:51
 |Â
show 4 more comments
up vote
10
down vote
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
[…] everything is more obvious and more in a structured-programming way.
Not quite. The variable i
exists outside the while loop here and is thus part of the outer scope, while (pun intended) x
of the for
-loop exists only within the scope of the loop. Scope is one very important way to introduce structure to programming.
1
Please see en.wikipedia.org/wiki/Structured_programming
– ruakh
Aug 10 at 19:34
@ruakh I'm not sure what to take away from your comment. It comes across as somewhat passive-aggressive, as if my answer opposes what's written on the wiki page. Please elaborate.
– null
Aug 14 at 15:27
"Structured programming" is a term of art with a specific meaning, and the OP is objectively correct that version #2 conforms to the rules of structured programming while version #1 does not. From your answer, it seemed that you were not familiar with the term of art, and were interpreting the term literally. I'm not sure why my comment comes across as passive-aggressive; I meant it simply as informative.
– ruakh
Aug 14 at 16:25
@ruakh I disagree that version #2 conforms to the rules more in every aspect and explained that in my answer.
– null
Aug 14 at 17:25
You say "I disagree" as if it were a subjective thing, but it's not. Returning from inside a loop is a categorical violation of the rules of structured programming. I'm sure that many structured-programming enthusiasts are fans of minimally-scoped variables, but if you reduce a variable's scope by departing from structured programming, then you have departed from structured programming, period, and reducing the variable's scope doesn't undo that.
– ruakh
Aug 14 at 18:27
 |Â
show 1 more comment
up vote
10
down vote
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
[…] everything is more obvious and more in a structured-programming way.
Not quite. The variable i
exists outside the while loop here and is thus part of the outer scope, while (pun intended) x
of the for
-loop exists only within the scope of the loop. Scope is one very important way to introduce structure to programming.
1
Please see en.wikipedia.org/wiki/Structured_programming
– ruakh
Aug 10 at 19:34
@ruakh I'm not sure what to take away from your comment. It comes across as somewhat passive-aggressive, as if my answer opposes what's written on the wiki page. Please elaborate.
– null
Aug 14 at 15:27
"Structured programming" is a term of art with a specific meaning, and the OP is objectively correct that version #2 conforms to the rules of structured programming while version #1 does not. From your answer, it seemed that you were not familiar with the term of art, and were interpreting the term literally. I'm not sure why my comment comes across as passive-aggressive; I meant it simply as informative.
– ruakh
Aug 14 at 16:25
@ruakh I disagree that version #2 conforms to the rules more in every aspect and explained that in my answer.
– null
Aug 14 at 17:25
You say "I disagree" as if it were a subjective thing, but it's not. Returning from inside a loop is a categorical violation of the rules of structured programming. I'm sure that many structured-programming enthusiasts are fans of minimally-scoped variables, but if you reduce a variable's scope by departing from structured programming, then you have departed from structured programming, period, and reducing the variable's scope doesn't undo that.
– ruakh
Aug 14 at 18:27
 |Â
show 1 more comment
up vote
10
down vote
up vote
10
down vote
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
[…] everything is more obvious and more in a structured-programming way.
Not quite. The variable i
exists outside the while loop here and is thus part of the outer scope, while (pun intended) x
of the for
-loop exists only within the scope of the loop. Scope is one very important way to introduce structure to programming.
int i = 0;
while (i < array.length && array[i] != value)
i++;
return i < array.length;
[…] everything is more obvious and more in a structured-programming way.
Not quite. The variable i
exists outside the while loop here and is thus part of the outer scope, while (pun intended) x
of the for
-loop exists only within the scope of the loop. Scope is one very important way to introduce structure to programming.
edited Aug 15 at 6:49
Deduplicator
4,86431735
4,86431735
answered Aug 10 at 17:16
null
3,1021520
3,1021520
1
Please see en.wikipedia.org/wiki/Structured_programming
– ruakh
Aug 10 at 19:34
@ruakh I'm not sure what to take away from your comment. It comes across as somewhat passive-aggressive, as if my answer opposes what's written on the wiki page. Please elaborate.
– null
Aug 14 at 15:27
"Structured programming" is a term of art with a specific meaning, and the OP is objectively correct that version #2 conforms to the rules of structured programming while version #1 does not. From your answer, it seemed that you were not familiar with the term of art, and were interpreting the term literally. I'm not sure why my comment comes across as passive-aggressive; I meant it simply as informative.
– ruakh
Aug 14 at 16:25
@ruakh I disagree that version #2 conforms to the rules more in every aspect and explained that in my answer.
– null
Aug 14 at 17:25
You say "I disagree" as if it were a subjective thing, but it's not. Returning from inside a loop is a categorical violation of the rules of structured programming. I'm sure that many structured-programming enthusiasts are fans of minimally-scoped variables, but if you reduce a variable's scope by departing from structured programming, then you have departed from structured programming, period, and reducing the variable's scope doesn't undo that.
– ruakh
Aug 14 at 18:27
 |Â
show 1 more comment
1
Please see en.wikipedia.org/wiki/Structured_programming
– ruakh
Aug 10 at 19:34
@ruakh I'm not sure what to take away from your comment. It comes across as somewhat passive-aggressive, as if my answer opposes what's written on the wiki page. Please elaborate.
– null
Aug 14 at 15:27
"Structured programming" is a term of art with a specific meaning, and the OP is objectively correct that version #2 conforms to the rules of structured programming while version #1 does not. From your answer, it seemed that you were not familiar with the term of art, and were interpreting the term literally. I'm not sure why my comment comes across as passive-aggressive; I meant it simply as informative.
– ruakh
Aug 14 at 16:25
@ruakh I disagree that version #2 conforms to the rules more in every aspect and explained that in my answer.
– null
Aug 14 at 17:25
You say "I disagree" as if it were a subjective thing, but it's not. Returning from inside a loop is a categorical violation of the rules of structured programming. I'm sure that many structured-programming enthusiasts are fans of minimally-scoped variables, but if you reduce a variable's scope by departing from structured programming, then you have departed from structured programming, period, and reducing the variable's scope doesn't undo that.
– ruakh
Aug 14 at 18:27
1
1
Please see en.wikipedia.org/wiki/Structured_programming
– ruakh
Aug 10 at 19:34
Please see en.wikipedia.org/wiki/Structured_programming
– ruakh
Aug 10 at 19:34
@ruakh I'm not sure what to take away from your comment. It comes across as somewhat passive-aggressive, as if my answer opposes what's written on the wiki page. Please elaborate.
– null
Aug 14 at 15:27
@ruakh I'm not sure what to take away from your comment. It comes across as somewhat passive-aggressive, as if my answer opposes what's written on the wiki page. Please elaborate.
– null
Aug 14 at 15:27
"Structured programming" is a term of art with a specific meaning, and the OP is objectively correct that version #2 conforms to the rules of structured programming while version #1 does not. From your answer, it seemed that you were not familiar with the term of art, and were interpreting the term literally. I'm not sure why my comment comes across as passive-aggressive; I meant it simply as informative.
– ruakh
Aug 14 at 16:25
"Structured programming" is a term of art with a specific meaning, and the OP is objectively correct that version #2 conforms to the rules of structured programming while version #1 does not. From your answer, it seemed that you were not familiar with the term of art, and were interpreting the term literally. I'm not sure why my comment comes across as passive-aggressive; I meant it simply as informative.
– ruakh
Aug 14 at 16:25
@ruakh I disagree that version #2 conforms to the rules more in every aspect and explained that in my answer.
– null
Aug 14 at 17:25
@ruakh I disagree that version #2 conforms to the rules more in every aspect and explained that in my answer.
– null
Aug 14 at 17:25
You say "I disagree" as if it were a subjective thing, but it's not. Returning from inside a loop is a categorical violation of the rules of structured programming. I'm sure that many structured-programming enthusiasts are fans of minimally-scoped variables, but if you reduce a variable's scope by departing from structured programming, then you have departed from structured programming, period, and reducing the variable's scope doesn't undo that.
– ruakh
Aug 14 at 18:27
You say "I disagree" as if it were a subjective thing, but it's not. Returning from inside a loop is a categorical violation of the rules of structured programming. I'm sure that many structured-programming enthusiasts are fans of minimally-scoped variables, but if you reduce a variable's scope by departing from structured programming, then you have departed from structured programming, period, and reducing the variable's scope doesn't undo that.
– ruakh
Aug 14 at 18:27
 |Â
show 1 more comment
up vote
2
down vote
The two loops have different semantics:
The first loop simply answers a simple yes/no question:
"Does the array contain the object I'm looking for?"
It does so in the most brief manner possible.The second loop answers the question:
"If the array contains the object I'm looking for,
what is the index of the first match?"
Again, it does so in the most brief manner possible.
Since the answer to the second question does provide strictly more information than the answer to the first, you can choose to answer the second question and then derive the answer of the first question. That is what the line return i < array.length;
does, anyway.
I believe that it's usually best to just use the tool that fits the purpose unless you can reuse an already existing, more flexible tool. I.e.:
- Using the first variant of the loop is fine.
- Changing the first variant to just set a
bool
variable and break is also fine. (Avoids secondreturn
statement, answer is available in a variable instead of a function return.) - Using
std::find
is fine (code reuse!). - However, explicitly coding a find and then reducing the answer to a
bool
is not.
Would be nice if the downvoters would leave a comment...
– cmaster
Aug 14 at 12:41
add a comment |Â
up vote
2
down vote
The two loops have different semantics:
The first loop simply answers a simple yes/no question:
"Does the array contain the object I'm looking for?"
It does so in the most brief manner possible.The second loop answers the question:
"If the array contains the object I'm looking for,
what is the index of the first match?"
Again, it does so in the most brief manner possible.
Since the answer to the second question does provide strictly more information than the answer to the first, you can choose to answer the second question and then derive the answer of the first question. That is what the line return i < array.length;
does, anyway.
I believe that it's usually best to just use the tool that fits the purpose unless you can reuse an already existing, more flexible tool. I.e.:
- Using the first variant of the loop is fine.
- Changing the first variant to just set a
bool
variable and break is also fine. (Avoids secondreturn
statement, answer is available in a variable instead of a function return.) - Using
std::find
is fine (code reuse!). - However, explicitly coding a find and then reducing the answer to a
bool
is not.
Would be nice if the downvoters would leave a comment...
– cmaster
Aug 14 at 12:41
add a comment |Â
up vote
2
down vote
up vote
2
down vote
The two loops have different semantics:
The first loop simply answers a simple yes/no question:
"Does the array contain the object I'm looking for?"
It does so in the most brief manner possible.The second loop answers the question:
"If the array contains the object I'm looking for,
what is the index of the first match?"
Again, it does so in the most brief manner possible.
Since the answer to the second question does provide strictly more information than the answer to the first, you can choose to answer the second question and then derive the answer of the first question. That is what the line return i < array.length;
does, anyway.
I believe that it's usually best to just use the tool that fits the purpose unless you can reuse an already existing, more flexible tool. I.e.:
- Using the first variant of the loop is fine.
- Changing the first variant to just set a
bool
variable and break is also fine. (Avoids secondreturn
statement, answer is available in a variable instead of a function return.) - Using
std::find
is fine (code reuse!). - However, explicitly coding a find and then reducing the answer to a
bool
is not.
The two loops have different semantics:
The first loop simply answers a simple yes/no question:
"Does the array contain the object I'm looking for?"
It does so in the most brief manner possible.The second loop answers the question:
"If the array contains the object I'm looking for,
what is the index of the first match?"
Again, it does so in the most brief manner possible.
Since the answer to the second question does provide strictly more information than the answer to the first, you can choose to answer the second question and then derive the answer of the first question. That is what the line return i < array.length;
does, anyway.
I believe that it's usually best to just use the tool that fits the purpose unless you can reuse an already existing, more flexible tool. I.e.:
- Using the first variant of the loop is fine.
- Changing the first variant to just set a
bool
variable and break is also fine. (Avoids secondreturn
statement, answer is available in a variable instead of a function return.) - Using
std::find
is fine (code reuse!). - However, explicitly coding a find and then reducing the answer to a
bool
is not.
answered Aug 11 at 8:17
cmaster
5,46011118
5,46011118
Would be nice if the downvoters would leave a comment...
– cmaster
Aug 14 at 12:41
add a comment |Â
Would be nice if the downvoters would leave a comment...
– cmaster
Aug 14 at 12:41
Would be nice if the downvoters would leave a comment...
– cmaster
Aug 14 at 12:41
Would be nice if the downvoters would leave a comment...
– cmaster
Aug 14 at 12:41
add a comment |Â
up vote
2
down vote
I'll suggest a third option altogether:
return array.find(value);
There are many different reasons to iterate over an array: Check if a specific value exists, transform the array into another array, calculate an aggregate value, filter some values out of the array... If you use a plain for loop, it's unclear at a glance specifically how the for loop is being used. However, most modern languages have rich APIs on their array data structures that make these different intents very explicit.
Compare transforming one array into another with a for loop:
int doubledArray = new int[array.length];
for (int i = 0; i < array.length; i++)
doubledArray[i] = array[i] * 2;
and using a JavaScript-style map
function:
array.map((value) => value * 2);
Or summing an array:
int sum = 0;
for (int i = 0; i < array.length; i++)
sum += array[i];
versus:
array.reduce(
(sum, nextValue) => sum + nextValue,
0
);
How long does it take you to understand what this does?
int newArray = new int[array.length];
int numValuesAdded = 0;
for (int i = 0; i < array.length; i++)
if (array[i] >= 0)
newArray[numValuesAdded] = array[i];
numValuesAdded++;
versus
array.filter((value) => (value >= 0));
In all three cases, while the for loop is certainly readable, you have to spend a few moments to figure out how the for loop is being used and checking that all of the counters and exit conditions are correct. The modern lambda-style functions make the purposes of the loops extremely explicit, and you know for certain that the API functions being called are implemented correctly.
Most modern languages, including JavaScript, Ruby, C#, and Java, use this style of functional interaction with arrays and similar collections.
In general, while I don't think using for loops is necessarily wrong, and it is a matter of personal taste, I've been finding myself strongly favoring using this style of working with arrays. This is specifically because of the increased clarity in determining what each loop is doing. If your language has similar features or tools in its standard libraries, I suggest you consider adopting this style as well!
2
Recommendingarray.find
begs the question, as we then have to discuss the best way to implementarray.find
. Unless you're using hardware with a built-infind
operation, we have to write a loop there.
– Barmar
Aug 11 at 0:44
2
@Barmar I disagree. As I indicated in my answer, a lot of heavily-used languages provide functions likefind
in their standard libraries. Undoubtedly, these libraries implementfind
and its kin using for loops, but that's what a good function does: it abstracts the technical details away from the function's consumer, allowing that programmer to not need to think about those details. So even thoughfind
is likely implemented with a for loop, it still helps make code more readable, and since it's frequently in the standard library, using it adds no meaningful overhead or risk.
– Kevin
Aug 11 at 0:54
4
But a software engineer has to implement these libraries. Don't the same software engineering principles apply to library authors as application programmers? The question is about writing loops in general, not the best way to search for an array element in a particular language
– Barmar
Aug 11 at 1:02
4
To put it another way, searching for an array element is just a simple example that he used to demonstrate the different looping techniques.
– Barmar
Aug 11 at 1:06
add a comment |Â
up vote
2
down vote
I'll suggest a third option altogether:
return array.find(value);
There are many different reasons to iterate over an array: Check if a specific value exists, transform the array into another array, calculate an aggregate value, filter some values out of the array... If you use a plain for loop, it's unclear at a glance specifically how the for loop is being used. However, most modern languages have rich APIs on their array data structures that make these different intents very explicit.
Compare transforming one array into another with a for loop:
int doubledArray = new int[array.length];
for (int i = 0; i < array.length; i++)
doubledArray[i] = array[i] * 2;
and using a JavaScript-style map
function:
array.map((value) => value * 2);
Or summing an array:
int sum = 0;
for (int i = 0; i < array.length; i++)
sum += array[i];
versus:
array.reduce(
(sum, nextValue) => sum + nextValue,
0
);
How long does it take you to understand what this does?
int newArray = new int[array.length];
int numValuesAdded = 0;
for (int i = 0; i < array.length; i++)
if (array[i] >= 0)
newArray[numValuesAdded] = array[i];
numValuesAdded++;
versus
array.filter((value) => (value >= 0));
In all three cases, while the for loop is certainly readable, you have to spend a few moments to figure out how the for loop is being used and checking that all of the counters and exit conditions are correct. The modern lambda-style functions make the purposes of the loops extremely explicit, and you know for certain that the API functions being called are implemented correctly.
Most modern languages, including JavaScript, Ruby, C#, and Java, use this style of functional interaction with arrays and similar collections.
In general, while I don't think using for loops is necessarily wrong, and it is a matter of personal taste, I've been finding myself strongly favoring using this style of working with arrays. This is specifically because of the increased clarity in determining what each loop is doing. If your language has similar features or tools in its standard libraries, I suggest you consider adopting this style as well!
2
Recommendingarray.find
begs the question, as we then have to discuss the best way to implementarray.find
. Unless you're using hardware with a built-infind
operation, we have to write a loop there.
– Barmar
Aug 11 at 0:44
2
@Barmar I disagree. As I indicated in my answer, a lot of heavily-used languages provide functions likefind
in their standard libraries. Undoubtedly, these libraries implementfind
and its kin using for loops, but that's what a good function does: it abstracts the technical details away from the function's consumer, allowing that programmer to not need to think about those details. So even thoughfind
is likely implemented with a for loop, it still helps make code more readable, and since it's frequently in the standard library, using it adds no meaningful overhead or risk.
– Kevin
Aug 11 at 0:54
4
But a software engineer has to implement these libraries. Don't the same software engineering principles apply to library authors as application programmers? The question is about writing loops in general, not the best way to search for an array element in a particular language
– Barmar
Aug 11 at 1:02
4
To put it another way, searching for an array element is just a simple example that he used to demonstrate the different looping techniques.
– Barmar
Aug 11 at 1:06
add a comment |Â
up vote
2
down vote
up vote
2
down vote
I'll suggest a third option altogether:
return array.find(value);
There are many different reasons to iterate over an array: Check if a specific value exists, transform the array into another array, calculate an aggregate value, filter some values out of the array... If you use a plain for loop, it's unclear at a glance specifically how the for loop is being used. However, most modern languages have rich APIs on their array data structures that make these different intents very explicit.
Compare transforming one array into another with a for loop:
int doubledArray = new int[array.length];
for (int i = 0; i < array.length; i++)
doubledArray[i] = array[i] * 2;
and using a JavaScript-style map
function:
array.map((value) => value * 2);
Or summing an array:
int sum = 0;
for (int i = 0; i < array.length; i++)
sum += array[i];
versus:
array.reduce(
(sum, nextValue) => sum + nextValue,
0
);
How long does it take you to understand what this does?
int newArray = new int[array.length];
int numValuesAdded = 0;
for (int i = 0; i < array.length; i++)
if (array[i] >= 0)
newArray[numValuesAdded] = array[i];
numValuesAdded++;
versus
array.filter((value) => (value >= 0));
In all three cases, while the for loop is certainly readable, you have to spend a few moments to figure out how the for loop is being used and checking that all of the counters and exit conditions are correct. The modern lambda-style functions make the purposes of the loops extremely explicit, and you know for certain that the API functions being called are implemented correctly.
Most modern languages, including JavaScript, Ruby, C#, and Java, use this style of functional interaction with arrays and similar collections.
In general, while I don't think using for loops is necessarily wrong, and it is a matter of personal taste, I've been finding myself strongly favoring using this style of working with arrays. This is specifically because of the increased clarity in determining what each loop is doing. If your language has similar features or tools in its standard libraries, I suggest you consider adopting this style as well!
I'll suggest a third option altogether:
return array.find(value);
There are many different reasons to iterate over an array: Check if a specific value exists, transform the array into another array, calculate an aggregate value, filter some values out of the array... If you use a plain for loop, it's unclear at a glance specifically how the for loop is being used. However, most modern languages have rich APIs on their array data structures that make these different intents very explicit.
Compare transforming one array into another with a for loop:
int doubledArray = new int[array.length];
for (int i = 0; i < array.length; i++)
doubledArray[i] = array[i] * 2;
and using a JavaScript-style map
function:
array.map((value) => value * 2);
Or summing an array:
int sum = 0;
for (int i = 0; i < array.length; i++)
sum += array[i];
versus:
array.reduce(
(sum, nextValue) => sum + nextValue,
0
);
How long does it take you to understand what this does?
int newArray = new int[array.length];
int numValuesAdded = 0;
for (int i = 0; i < array.length; i++)
if (array[i] >= 0)
newArray[numValuesAdded] = array[i];
numValuesAdded++;
versus
array.filter((value) => (value >= 0));
In all three cases, while the for loop is certainly readable, you have to spend a few moments to figure out how the for loop is being used and checking that all of the counters and exit conditions are correct. The modern lambda-style functions make the purposes of the loops extremely explicit, and you know for certain that the API functions being called are implemented correctly.
Most modern languages, including JavaScript, Ruby, C#, and Java, use this style of functional interaction with arrays and similar collections.
In general, while I don't think using for loops is necessarily wrong, and it is a matter of personal taste, I've been finding myself strongly favoring using this style of working with arrays. This is specifically because of the increased clarity in determining what each loop is doing. If your language has similar features or tools in its standard libraries, I suggest you consider adopting this style as well!
edited Aug 15 at 6:50
Deduplicator
4,86431735
4,86431735
answered Aug 10 at 22:11


Kevin
6241415
6241415
2
Recommendingarray.find
begs the question, as we then have to discuss the best way to implementarray.find
. Unless you're using hardware with a built-infind
operation, we have to write a loop there.
– Barmar
Aug 11 at 0:44
2
@Barmar I disagree. As I indicated in my answer, a lot of heavily-used languages provide functions likefind
in their standard libraries. Undoubtedly, these libraries implementfind
and its kin using for loops, but that's what a good function does: it abstracts the technical details away from the function's consumer, allowing that programmer to not need to think about those details. So even thoughfind
is likely implemented with a for loop, it still helps make code more readable, and since it's frequently in the standard library, using it adds no meaningful overhead or risk.
– Kevin
Aug 11 at 0:54
4
But a software engineer has to implement these libraries. Don't the same software engineering principles apply to library authors as application programmers? The question is about writing loops in general, not the best way to search for an array element in a particular language
– Barmar
Aug 11 at 1:02
4
To put it another way, searching for an array element is just a simple example that he used to demonstrate the different looping techniques.
– Barmar
Aug 11 at 1:06
add a comment |Â
2
Recommendingarray.find
begs the question, as we then have to discuss the best way to implementarray.find
. Unless you're using hardware with a built-infind
operation, we have to write a loop there.
– Barmar
Aug 11 at 0:44
2
@Barmar I disagree. As I indicated in my answer, a lot of heavily-used languages provide functions likefind
in their standard libraries. Undoubtedly, these libraries implementfind
and its kin using for loops, but that's what a good function does: it abstracts the technical details away from the function's consumer, allowing that programmer to not need to think about those details. So even thoughfind
is likely implemented with a for loop, it still helps make code more readable, and since it's frequently in the standard library, using it adds no meaningful overhead or risk.
– Kevin
Aug 11 at 0:54
4
But a software engineer has to implement these libraries. Don't the same software engineering principles apply to library authors as application programmers? The question is about writing loops in general, not the best way to search for an array element in a particular language
– Barmar
Aug 11 at 1:02
4
To put it another way, searching for an array element is just a simple example that he used to demonstrate the different looping techniques.
– Barmar
Aug 11 at 1:06
2
2
Recommending
array.find
begs the question, as we then have to discuss the best way to implement array.find
. Unless you're using hardware with a built-in find
operation, we have to write a loop there.– Barmar
Aug 11 at 0:44
Recommending
array.find
begs the question, as we then have to discuss the best way to implement array.find
. Unless you're using hardware with a built-in find
operation, we have to write a loop there.– Barmar
Aug 11 at 0:44
2
2
@Barmar I disagree. As I indicated in my answer, a lot of heavily-used languages provide functions like
find
in their standard libraries. Undoubtedly, these libraries implement find
and its kin using for loops, but that's what a good function does: it abstracts the technical details away from the function's consumer, allowing that programmer to not need to think about those details. So even though find
is likely implemented with a for loop, it still helps make code more readable, and since it's frequently in the standard library, using it adds no meaningful overhead or risk.– Kevin
Aug 11 at 0:54
@Barmar I disagree. As I indicated in my answer, a lot of heavily-used languages provide functions like
find
in their standard libraries. Undoubtedly, these libraries implement find
and its kin using for loops, but that's what a good function does: it abstracts the technical details away from the function's consumer, allowing that programmer to not need to think about those details. So even though find
is likely implemented with a for loop, it still helps make code more readable, and since it's frequently in the standard library, using it adds no meaningful overhead or risk.– Kevin
Aug 11 at 0:54
4
4
But a software engineer has to implement these libraries. Don't the same software engineering principles apply to library authors as application programmers? The question is about writing loops in general, not the best way to search for an array element in a particular language
– Barmar
Aug 11 at 1:02
But a software engineer has to implement these libraries. Don't the same software engineering principles apply to library authors as application programmers? The question is about writing loops in general, not the best way to search for an array element in a particular language
– Barmar
Aug 11 at 1:02
4
4
To put it another way, searching for an array element is just a simple example that he used to demonstrate the different looping techniques.
– Barmar
Aug 11 at 1:06
To put it another way, searching for an array element is just a simple example that he used to demonstrate the different looping techniques.
– Barmar
Aug 11 at 1:06
add a comment |Â
up vote
-2
down vote
It all boils down to precisely what is meant by 'better'. For practical programmers, it generally means efficient - i.e in this case, exiting directly from the loop avoids one extra comparison, and returning a Boolean constant avoids a duplicate comparison; this saves cycles. Dijkstra is more concerned with making code that is easier to prove correct. [it has seemed to me that CS education in Europe takes 'proving code correctness' far more seriously than CS education in the US, where economic forces tend to dominate coding practice]
3
PMar, performance-wise both loops are pretty much equivalent — they both have two comparisons.
– Danila Piatov
Aug 10 at 21:19
1
If one really cared about performance, one would use a faster algorithm. e.g. sort the array and do a binary search, or use a Hashtable.
– user949300
Aug 11 at 16:30
Danila - you don’t know what data structure is behind this. An iterator is always fast. Indexed access can be linear time, and length need not even exist.
– gnasher729
Aug 15 at 7:52
add a comment |Â
up vote
-2
down vote
It all boils down to precisely what is meant by 'better'. For practical programmers, it generally means efficient - i.e in this case, exiting directly from the loop avoids one extra comparison, and returning a Boolean constant avoids a duplicate comparison; this saves cycles. Dijkstra is more concerned with making code that is easier to prove correct. [it has seemed to me that CS education in Europe takes 'proving code correctness' far more seriously than CS education in the US, where economic forces tend to dominate coding practice]
3
PMar, performance-wise both loops are pretty much equivalent — they both have two comparisons.
– Danila Piatov
Aug 10 at 21:19
1
If one really cared about performance, one would use a faster algorithm. e.g. sort the array and do a binary search, or use a Hashtable.
– user949300
Aug 11 at 16:30
Danila - you don’t know what data structure is behind this. An iterator is always fast. Indexed access can be linear time, and length need not even exist.
– gnasher729
Aug 15 at 7:52
add a comment |Â
up vote
-2
down vote
up vote
-2
down vote
It all boils down to precisely what is meant by 'better'. For practical programmers, it generally means efficient - i.e in this case, exiting directly from the loop avoids one extra comparison, and returning a Boolean constant avoids a duplicate comparison; this saves cycles. Dijkstra is more concerned with making code that is easier to prove correct. [it has seemed to me that CS education in Europe takes 'proving code correctness' far more seriously than CS education in the US, where economic forces tend to dominate coding practice]
It all boils down to precisely what is meant by 'better'. For practical programmers, it generally means efficient - i.e in this case, exiting directly from the loop avoids one extra comparison, and returning a Boolean constant avoids a duplicate comparison; this saves cycles. Dijkstra is more concerned with making code that is easier to prove correct. [it has seemed to me that CS education in Europe takes 'proving code correctness' far more seriously than CS education in the US, where economic forces tend to dominate coding practice]
answered Aug 10 at 20:43
PMar
51
51
3
PMar, performance-wise both loops are pretty much equivalent — they both have two comparisons.
– Danila Piatov
Aug 10 at 21:19
1
If one really cared about performance, one would use a faster algorithm. e.g. sort the array and do a binary search, or use a Hashtable.
– user949300
Aug 11 at 16:30
Danila - you don’t know what data structure is behind this. An iterator is always fast. Indexed access can be linear time, and length need not even exist.
– gnasher729
Aug 15 at 7:52
add a comment |Â
3
PMar, performance-wise both loops are pretty much equivalent — they both have two comparisons.
– Danila Piatov
Aug 10 at 21:19
1
If one really cared about performance, one would use a faster algorithm. e.g. sort the array and do a binary search, or use a Hashtable.
– user949300
Aug 11 at 16:30
Danila - you don’t know what data structure is behind this. An iterator is always fast. Indexed access can be linear time, and length need not even exist.
– gnasher729
Aug 15 at 7:52
3
3
PMar, performance-wise both loops are pretty much equivalent — they both have two comparisons.
– Danila Piatov
Aug 10 at 21:19
PMar, performance-wise both loops are pretty much equivalent — they both have two comparisons.
– Danila Piatov
Aug 10 at 21:19
1
1
If one really cared about performance, one would use a faster algorithm. e.g. sort the array and do a binary search, or use a Hashtable.
– user949300
Aug 11 at 16:30
If one really cared about performance, one would use a faster algorithm. e.g. sort the array and do a binary search, or use a Hashtable.
– user949300
Aug 11 at 16:30
Danila - you don’t know what data structure is behind this. An iterator is always fast. Indexed access can be linear time, and length need not even exist.
– gnasher729
Aug 15 at 7:52
Danila - you don’t know what data structure is behind this. An iterator is always fast. Indexed access can be linear time, and length need not even exist.
– gnasher729
Aug 15 at 7:52
add a comment |Â
protected by gnat Aug 11 at 15:28
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
2
The code examples cited here mix several different issues. Early & multiple returns (which for me go to the size of the method (not shown)), array search (which begs for a discussion involving lambdas), foreach vs. direct indexing... This question would be more clear and easier to answer if it focused on just one of these issues at a time.
– Erik Eidt
Aug 10 at 15:38
5
Possible duplicate of Should methods always return from one place?
– gnat
Aug 10 at 15:45
1
I know those are examples, but there are languages that have APIs to handle exactly that use case. I.e.
collection.contains(foo)
– Berin Loritsch
Aug 10 at 20:17
2
You may want to find the book and reread it now to see what it actually said.
– Thorbjørn Ravn Andersen
Aug 11 at 6:32
1
"Better" is a highly subjective word. That said, one can tell at a glance what the first version is doing. That the second version does exactly the same thing takes some scrutiny.
– David Hammen
Aug 11 at 22:40