I want to use Google Apps Script to make custom functions for a spreadsheet. I've made an extremely simple function:

function foo(){
    return "bar";
};

The problem is that I need this function in a couple hundred cells. When I paste the function =foo() into all of these cells, the function works in a few of the cells, but in most I get this error: "Service invoked too many times: spreadsheet. Try Utilities.sleep(1000) between calls."

[Screenshot here]

I guess I don't understand why this function, simple as it is, is considered an invocation of the Spreadsheet Services. I'm not even requesting any data (except for the function itself). Is that the problem? And if so, is there a workaround? Custom functions could make Google Spreadsheets infinitely more powerful, but this problem hamstrings the possibility of using a custom function in multiple cells. Suggestions?

(P.S. -- Using the Utilities.sleep() function as suggested by the error message doesn't help at all when all of the cells call their functions simultaneously; it only slows the rate at which individual cells repeatedly call the function.)

According to the Optimization section on the Apps Script Function Guide:

Each time a custom function is used in a spreadsheet, Google Sheets makes a separate call to the Apps Script server. If your spreadsheet contains dozens (or hundreds, or thousands!) of custom function calls, this process can be quite slow.

Consequently, if you plan to use a custom function multiple times on a large range of data, consider modifying the function so that it accepts a range as input in the form of a two-dimensional array, then returns a two-dimensional array that can overflow into the appropriate cells.

To do this, pass in an input that represents the size of the array you'd like to return. When you start executing your function check if the input parameter is an array with input.map. If it is, you can call the the function on each item and return that entire collection.

So in your case like this:

<!-- language: lang-js -->
function foo(){
    return "bar";
};

You can update the function like this:

<!-- language: lang-js -->
function foo(input){
  if (input.map) {         // Test whether input is an array.
    return input.map(foo); // Recurse over array if so.
  } else {
    // do actual function work here
    return "bar";
  }
};

And then call it like this:

screenshot