9

I recently read somewhere that calling a function within a loop is considered bad practice. Is this true? So for example, if I had the following:

function foo(value){
    console.log(value);
}

var bar = ["Foo", "Bar"];

for(var i = 0; i < bar.length; i++){
    foo(bar[i]);
}

Is it bad practice do do this? Should there be another way I should be calling foo?

Note: This question is not specific to Javascript, it's just what I wrote the question in.

14
  • 37
    I ... what ... how ... where did you read that? On The Onion?
    – user7043
    Apr 6, 2016 at 18:47
  • 17
    That link you give says defining functions inside loops can lead to bugs. It's not talking about calling functions.
    – 8bittree
    Apr 6, 2016 at 18:54
  • 3
    Not quite sure why it's getting downvoted though, it's a legitimate question that could possibly educate others. If you don't like that it was asked, simply move on.
    – Robert
    Apr 6, 2016 at 19:07
  • 4
    @8bittree In which case the link is correct, and the advice is highly specific to JavaScript's scoping rules.
    – btilly
    Apr 6, 2016 at 19:28
  • 3
    You misread something. It happens. Do you still feel this question is going to benefit anyone? Questions that don't benefit other programers tend to get down voted.
    – JeffO
    Apr 6, 2016 at 19:49

3 Answers 3

19

It's not a bad practice... it all depends on what the function is doing, and whether the code in the function needs to be within a loop, or whether it can be refactored outside of a loop.

A function is just a set of instructions, so you could, theoretically, take any function's instructions and put them directly inside the loop, and you have essentially the same thing. If that set of instructions is to add two plus two, you don't have much to worry about. If that set of instructions is to open a database table of 10 million rows, find a row, write the values to disk, close the connection and repeat, then you've got something to think about.

Often times, regardless of how long it actually takes, it might just plain be required even if it's not performant. Other times, you could really put some dumb stuff in a loop.

Let's take the "open a database table of 10 million rows and write each row's values to a file" example.

Bad loop:

int count = GetFullCountFromSomewhere();
for (int i = 0 i < count; i++) {
   GetMyRow(i);
   WriteMyRow(i);
}

function GetMyRow(i) {
   Table table = new Table();
   table.Fill(someConnection);
   Row row = table.Rows[i];
   return row;
}

In the above, a table instance (and all of the associated overhead) is done necessarily for each iteration.

Better loop:

Table table = GetMyTable()
for (int i = 0 i < table.Rows.count; i++) {
   WriteMyRow(table.Rows[i]);
}

function GetMyTable(i) {
   Table table = new Table();
   table.Fill(someConnection);
   return table;
}

or, perhaps even better (as it could be internally optimized by the language compiler):

Table table = GetMyTable();
ForEach(var row in Table.Rows) {
    WriteMyRow(row);
}

So, you can see a few ways that we could manage code within a loop versus setting it up outside of the loop.

That's really the only thing worth considering, at least on a day to day basis.

3
  • a downvote for explaining to keep an eye out for unnecessary overhead in a loop?
    – jleach
    Apr 6, 2016 at 19:24
  • 2
    It's classic SE behavior. Users don't understand how to use these sites. you answered the question in a clear and precise way, gave details, and even provided examples. What exactly warranted a downvote?
    – Robert
    Apr 6, 2016 at 19:28
  • This is a good segue into referential transparency[1]: a function call can always be replaced with the same set of instructions, but referentially transparent functions can always be replaced with their output (by definition). These kinds of functions are usually easier to reason about since they avoid side effects in other parts of your program. [1]: en.wikipedia.org/wiki/Referential_transparency [2]: en.wikipedia.org/wiki/Side_effect_(computer_science)
    – rayhem
    Dec 19, 2023 at 22:15
1

That’s rather strange advice.

If you call a function repeatedly without need that’s a waste of time. It’s not bad practice, it’s just stupid.

If you need to call it repeatedly, then you call it repeatedly. What else what you do? “Sorry, I can give you the address of the first company but not the second customer because calling a function in a loop is bad practice”.

Now sometimes it’s better to solve a complete problem instead of doing it bit by bit. If you have a function that returns the k-largest item in an unsorted array, you don’t want to call that in loop for k = 1 to n, you sort the array once. Again, not bad practice but doing so would be stupid.

-2

My main complaint about using recursion vs iteration is that every time you call a function, a copy of that code is brought into memory. Suppose you are writing code for an operating system, where this particular module gets called for every job that's running at that installation. Think about the amount of memory being taken up by calling the function over and over again, not to mention the amount of time it takes the CPU to actually fetch these instructions. It just seems to me that iteration makes more sense.

2
  • 5
    "every time you call a function, a copy of that code is brought into memory" This is completely false I'm afraid - you get a new stack frame, but that's much smaller than the code for the function. And languages which make heavy use of recursion (in particular, the functional languages) do tail call optimisation so you don't even have the cost of a stack frame. Dec 19, 2023 at 14:53
  • What the OP is talking about is not recursion. Dec 22, 2023 at 13:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.