JavaScript as a functional programming language

Paul E.S. Wormer

November 2011

Contents



Below some snippets of JavaScript code are shown. All snippets write some information by invoking the user-defined function println(). The output generated by the the call of println() is shown in green in the right margin of the snippet. The output order is determined by the order of the invocations of println().

Preface

Programmers coming from imperative languages such as Fortran 77 or C will encounter two main surprises when they switch to JavaScript: The second point is the subject of the present notes. Some of the more surprising aspects of the functional character of JavaScript (often abbreviated to JS) will be reviewed with Fortran/C programmers as intended readers. The present notes are not meant as an introduction to the syntax of JS. JS syntax is treated in many books and is defined on the Internet (the latest standard, known as ECMAScript 5, can be downloaded as pdf from Edition 5.1 (June 2011). See also Mozilla and the list of references below. The examples that are given in the following notes are as readable as possible for Fortran/C programmers; syntactic JS tricks are avoided.

To contents

Functions

In languages like Fortran and C, functions are independent subprograms, often stored as separate source codes compiled separately; they are joined with the main program at load time. During runtime, C and Fortran procedures cannot be defined or modified. Their visibility is global, functions can be called from anywhere in the program that loaded them. Variables internal to a function have a scope restricted to the function; communication of C or Fortran functions with their callers is mainly by assigning actual arguments to formal parameters. Functions cannot be nested in C or Fortran.

A JavaScript function looks much like a function in C. The only syntactic difference between a C function and a JS function is that JS functions do not have a return-type (there are no int, double, etc., functions) and instead has the keyword function. Obviously, the absence of a return-type is a consequence of JS being a weakly-typed language. More in particular, the syntax of a JS function is the following

      function any_name(p1, p2, ...){
          statements
      }

The function is named any_name and the variables p1, p2 stand for formal parameters. Parameters may be anything: primitive values (numeric constants, strings, etc.) or any kind of compound objects (including functions and arrays). As in C, a return statement is optional. When an early return is needed a return statement can be entered that gives control back to the caller. When a value must be returned, the return statement is necessary: return expression returns the value of expression. Without return statement a JS function "falls off the end" when it reaches the terminating curly bracket, it then returns the JS value undefined.

As in C, internal (local) variables are automatic, they are created on entry and destroyed on exit, so that they are in existence only during execution of the function. JavaScript does not have static internal variables; if internal variables have to retain their value between calls they must be placed in the lexical environment of the function, see below. In Fortran 77 all variables, including local variables, are static, and hence preserve their values between successive calls (in theory the Fortran statement SAVE is required for this, in practice SAVE is redundant).

A JS function is more than a function in C: it is an object comparable to all other objects of JS; this is expressed by referring to JS functions as first-class objects, entities with properties and values. Another important property is that functions may be nested in other functions. In addition to the ordinary—C-type—properties, a JavaScript function has the following characteristics:

Instead of the function statement given above, a function may be created by assignment of a function expression to a variable on the left-hand side. Usually a function in a function expression is anonymous (unnamed). In the next example a function expression is assigned to hiThere. Its body consists of one print statement only. The difference between registering and invoking a function must be noted. The following statement registers the function but does not invoke it:

      var hiThere = function (your_name){
          println("Hi there "+ your_name);
      };

The following statement invokes it:
      hiThere("Paul");

The next statement registers and invokes:
      hiThere = (function(your_name){
          println("Hi there "+ your_name);
      }("Paul"));

Note that the output of these code snippets is on the right in green. The difference between registering and invoking is sometimes subtle, see the difference between functions g and h in the next example. Invocation of h returns the function f that is not yet called. A call of g gives invocation of f. The latter function writes a string and, in absence of an explicit return statement, returns undefined, a value that is then also returned by g.
      var f = function(x){ println(x); };
      var g = function(z){ return f(z);};
      var h = function(y){ return f;   };
      tmp = g("XYZ");    // -> "XYZ"
      h("XYZ");          // No output
      println(tmp);      // -> undefined

A function in a function expression is allowed to carry a name:

     var f = function any_name(){ ... };

The main use of the specification of a name in a function expression is the recursive execution of the function by invoking it by its name.

Consider, as an example of the dynamic definition of a JS function, the product of three functions mappings ℝ → ℝ, functions on the real line):  f1(x),  f2(x),  and f3(x). The product p(x) is written as

p = f1(f2(f3(x)))
As a mathematical example take: f3(x) = √x, f2(x) = cos(x), and f1(x) = ex, then
p(x) = e cos(√x)  .

Mathematically, p(x) (or more precisely  p) is also a map ℝ → ℝ. In JS it is possible to define such a product by introducing a "higher order" function prod that takes three functions f, g, and h as arguments and returns the product function p(x) = f(g(h(x))). (Later we will give the actual form of prod, for now it suffices to say that a product of functions can be formed dynamically and is a new JS function).
// Define the functions
     var f1 = function(x){ ... };
     var f2 = function(x){ ... };
     var f3 = function(x){ ... };
// Create the product function p:
     var p  = prod(f1, f2, f3);
// Invoke the new function p for argument value x
     println(p(-1));
// prod may be used more than once, for instance different order:
     var q  = prod(f3, f1, f2);

In Fortran and C one cannot create dynamically (during runtime) a new function (such as p or q in the example) from existing functions. One would have to write new static code that must be compiled.

To contents

A conceptual difficulty

For programmers without experience in functional programming languages, JavaScript's functional programming rules are weird and difficult to grasp. In the following example, a JS function is invoked. As in C, function invocation is by giving the name of the function followed by an argument list between parentheses. When there are no arguments, the parentheses are still necessary to effectuate the invocation:  a function f without formal parameters is invoked as f(). The reader is challenged to predict the output of the following lines of legitimate JS code (and don't look in the right margin where the answer is given in green):
     var f = (function(x){
        return function(){ println(x);};
     }(1));
     f(2);

Can you explain why the following code, where f(2); is omitted, does not write anything at all (not even 1)?
     var f = (function(x){
        return function(){ println(x);};
     }(1));

If you understood these snippets of code well enough to give the right answers then you can stop reading here. Basically, the answer is that the unnamed function invoked by the argument expression (1) defines a function without parameters that is assigned to f. The function bound to f has x=1 in its lexical environment (f is a closure). However, the new function is not yet called. This is done in the line f(2). To understand this line we must note that the number of actual arguments may larger than the number of formal parameters, the redundant arguments are ignored. Hence, f(2) is equivalent to the call f(). The latter call, absent in the second code snippet, triggers the actual printing of x=1.

To contents

Nested functions

A function may be nested, schematically,
     function host(...){
         ...
         function nested(...){
            ...
         }
         ...
     }

Nested JS functions have access to variables of their outer (host) function. Nested functions are not visible outside their host function, i.e., their scope is restricted to their enclosing function. Consider the next snippet of JavaScript code. The variable x is local to function host, but not to function nested. However, x is in the lexical environment of nested, meaning that nested has full read/write access to it. The statement host() invokes host. The function nested is simple, all it does is print x and add one to x (the operation ++ adds one and stores the updated x). Note that invoking nested outside host generates an error.

     function host(){
        var x  = 0;
        function nested(){
             println(x++);
        }
        nested();
        nested();
     }
     host(); // Invoke host
     nested(); //Try to invoke nested => "nested is not defined"

Formal parameters being local, the following snippet is almost equivalent to the previous one:
     function host(x){
        function nested(){
             println(x++);
        }
        nested();
        nested();
     }
     host(0); // Invoke host while setting x = 0

The following variant is completely equivalent to the previous one:
     function host(x){
        var nested = function(){
             println(x++);
        };
        nested();
        nested();
     }
     host(0); // Invoke host while setting x = 0


To contents

Closure

Closure is a pivotal concept in understanding JavaScript as a functional programming language. The concept arises when a function is defined inside an outer function (the "host"). The "nested" function may be called after the host has finished execution. At first sight this may seem impossible, but it can be done when the host returns the nested function and the returned function is assigned to a variable external to the host. Schematically,
     function host(...){
        var x, y, z, ...
        ...
        var nested = function(){
           ...
        }
        ...
        return nested;
     }
     var fnc = host(...);  // Invoke host; bind nested to fnc
     fnc();   // Invoke nested. Note that host has finished at this point

   /* At this point both host and nested have finished,
    * x, y, z, ... still exist and retain their values.
    * Their values are only accessible through invocation of nested.
    */

The variable fnc, external to host, is bound to the returned function nested. The binding persists (meaning that nested stays alive) after host has finished execution. Invocation of fnc is equivalent to invoking nested. The local (internal) variables x, y, z, .. of the host form the lexical environment of the inner function nested. The inner function has read/write access to the local variables of its host. (In this context the term "lexical" refers to the fact that the environment can be deduced from the source statements.) A closure is defined as a function augmented with its lexical environment. In other words, a closure consists of a function, originally defined within a host function, with access to variables x, y, z, .. local to the host. The latter variables, i.e., those in the lexical environment of the inner function, are sometimes referred to as the upvalues of the closure. The name is somewhat awkward because sometimes one must consider "the values of the upvalues". However, in lack of a better terminology, "upvalue" will be used.

In summary, a closure is a special kind of object that combines two entities: a function, and the lexical environment in which the function was defined (the set of upvalues). Upvalues stay alive, and keep their value, after the host function has finished execution. They also stay alive after the returned function has finished execution. In contrast to upvalues, local variables of returned functions are automatic, they disappear after returned functions are exited.

Closure will be explained in more detail by several examples. In the first example g (a function) is returned and assigned to h.

     function f(){
         var str = "QRS";
         var g = function(){
             println(str);
             str = str + str;  // double str
         };
         return g;
     }
     var h = f(); // h bound to value of g (a function)
     h();         // call h, prints "QRS" and modifies str
     h();         // call h => "QRS"+"QRS"
     f();         // Make new copy of str; does not affect h
     h();         // call h => "QRSQRS"+"QRSQRS" (old copy of str)
     h = f();     // Reassign h
     h();         // => "QRS"

The first call h() invokes function g that prints and modifies the upvalue str. The second call h() prints the modified value of str (and modifies it again, a third call of h prints "QRSQRS"+"QRSQRS", the operator + concatenates strings). As far as the function f is concerned, the variable str is local, all f can do is reset it. Since str is automatic, a new variable str is created that, however, is not an upvalue of h. Only when the closure h is reassigned, the upvalue is reassigned.

The name of the internal (nested) routine is irrelevant, there is not even a reason to assign it to a local variable (to g in the previous example). The function may be returned directly:

     function f(){
         var str = "DEF";
         return function(){
             println(str);
             str = str + str;
         };
     }
     var h = f();
     h(); h();

Even the name f may be omitted and replaced by an unnamed function (if it is used only once), but do not forget to call the unnamed function:
      var h = (function(){
          var str = "KLM";
          return function(){
              println(str);
              str = str + str;
          };
      }());   // call unnamed function on rhs
      h(); h();

The extra parentheses on the right-hand side are optional; they are often used to warn the reader that h does not receive the function as value, but the result of the invocation of the function.

The value of the variable h can be printed. Note in the following example that its value is the (anonymous) function in an earlier example assigned to g.

      println(h)

The local variable str may be promoted to parameter:
      var h = (function(str){
          return function(){
              println(str);
              str = str + str;
          };
      }("IJK"));   // call unnamed function on rhs
      h(); h();

Although the previous examples seem pretty trivial, they show the most important characteristics of JS as a functional programming language: the value of a local (named or unnamed) variable may be a function, this value can be returned and bound to an external variable (in the examples above h). The upvalues of the returned function (in the examples: str) remain accessible, both for reading [as in println(str)] and for modifying (as in str = str + str).

To contents

More on closure

A question that jumps to mind is: which value of an upvalue is bound to a nested function that is returned? Either of the following two choices are arguably sensible:
  1. the value of the upvalue at the time that the inner function is defined,
  2. the value of the upvalue at the time that the inner function is returned.
To answer this question, consider:

      var f = function(x){
         var g = function(){return x;}; // definition g
         x = 2;
         return g;                 // returning g
      };
      var h = f(1);
      println(h());

Noting that the invocation of h (bound to g) prints the value that x possesses just before g is returned, the answer is choice 2: the value of the local variable at the time that host function f returns the value of g and h is bound to the value of g. Being local to the host, the variables in the lexical environment (in this case consisting only of x) of the nested function g may change values during execution of the host function. A snapshot of the values is taken at the time the host gives control back to the calling program after which the host function has lost control over its local variables.

Above it was discussed that local variables are automatic, they are created upon entry and destroyed upon exit. This is also true for local variables of a function that is part of a closure. To show the difference in lifetime between a local variable and an upvalue we first introduce some information about JS boolean expression: The statement var a   creates the local variable a and gives it the JS value undefined. The value undefined is a legitimate JS value that can be handled like any value. In particular, when it appears as a boolean, it has the value false. Furthermore, the exclamation mark ! negates, that is, the value of a will be printed in the following snippet:

      var a;
      if (!a) {
         println(a);
      }

When a obtains a value (other than the number 0, the null string, or undefined), it will return true.
      var a = "a string";
      if (a) {
         println("a true " + a);
      }
      else {
         println("a false " + a);
      }

We are now ready to see the difference between the lifetime of an upvalue (upval) and a local value (locval). The statement in the following fragment: var locval gives locval the value undefined. Every time nested (bound to f) is executed this value is assigned. Similarly, every time host is executed upval obtains the value undefined.

     function host(){
           var upval;
           function nested(){
               var locval;
               if (!upval){
                  upval  = 'Persistent';
                  locval = 'Volatile';
               }
               println(upval);
               println(locval);
           }
           return nested;
     }
     f = host();
     f();
     println(" ");
     f();

When host is called nothing is printed yet, because the printing is done inside nested, however upval (with value undefined) is added to the closure nested (which is bound to f). When f is called for the first time (!upval) returns true and both upval and locval obtain a string value. When f is called the second time (!upval) returns false, because upval still possesses the string value Persistent, the two assignments are skipped, and the value of locval stays equal to the value it obtained in the statement var locval.

Let us next consider two different closures, nested in the same host, that are returned simultaneously and address the question: do they share the values of the variables in their (shared) lexical environment? To find the answer, we let two nested functions change the variable i in their lexical environment in two different ways,

      var f = function(i){
         var func_arr = [];
         func_arr[0]  = function(){i = i + 10;  return i;};
         func_arr[1]  = function(){i = i + 100; return i;};
         return func_arr;
      };
      var c = f(0);    //  array of two functions
      var a = c[0];
      var b = c[1];
      println(a()); // prints effect of invoking a
      println(b()); // prints effect of invoking b
      println(a()); // prints effect of invoking a again
      println(b()); // prints effect of invoking b again

From the output in the right margin the answer is clear: the closures, bound to a and b, share the value of i. Closures returned simultaneously from a host share their upvalues.

The final question is: what happens if a closure is returned more than once, or, in other words, the enclosing function is executed more than once. Do all objects bound to this closure access the same set of values of variable(s) in the lexical environment of the nested function? Or is a new set of variables (holding different values) created every time a closure is assigned to a new variable? In fact, since the var statements in the body of the enclosing function are executed more than once, it is to be expected that different closures with different lexical environments are formed. This is also true when the upvalue is a function parameter and a var statement is optional.

In the next example, the left-hand sides a and b are bound to a (nested, anonymous) function that updates the variable i in the lexical environment offered by the enclosing function f. First a is invoked three times, increasing the value of i from 0 to 2. Then b is invoked, it starts counting anew and returns 0, so that evidently the answer is: b accesses its own private copy of i and does not touch the copy of i belonging to a:

      f = function(i){
            return function(){return i++;};
      };
      a = f(0);
      b = f(0);
      println(a()); println(a()); println(a());
      println(b()); println(b());

Although the closures a and b share the same nested function, they are different because their values of variables in the lexical environment are different.

The reader is invited to inspect the following two snippets of JS code that both fill an array func with functions. Element func[i] is to contain a function that returns the value i. Both snippets end with the statement println(func[5]()) supposedly writing 5. Can you understand why the first time the number 5 is written correctly and the second time incorrectly the number 10?

      var i;
      var a = function(i){return function(){return i;};};
      var func = [];        // new (empty) array
      for (i=0; i < 10; i=i+1) {
             func[i] = a(i);
      }
      println(func[5]());

/*    Second snippet:           */
      var a = function(){
          var func = [];
          for (i=0; i  < 10; i=i+1) {
                 func[i] = function(){return i;};
          }
          return func;
      };
      func = a();
      println(func[5]());

In the first snippet one function at the time is returned, in the second snippet ten functions are returned simultaneously. Crucial is the value of i at the time that the nested function(s) is/are returned.

To end this section, we summarize the findings of this section as the following rules:

To contents

Use of keyword this

The keyword this is a function variable depending on the context in which the function is called. If this appears in the body of a function that is invoked "stand-alone", not as a method of an object, this receives the name of the global object. In a web browser the global object is named window. If this appears in a function that is invoked as an object method then this refers to the object (receives the name of the object). The keyword this in an inner function, nested within a hosting method, (and not itself invoked as method by the hosting method), refers to the global object, in the same way as a "stand-alone" function.

In the following example fnc is a function nested in obj.method. Note that the print statement (marked with P) in obj.method writes the value of obj.s, while the print statement (marked with Q) in fnc writes the value of window.s:

     var obj  = {};
     obj.s    = "Object string";
     window.s = "Window string";
     obj.method = function(){
            println("P: " + this.s);
            var fnc = (function(){
               println("Q: " + this.s);
            }());                          // fnc invoked "stand-alone" by hosting method
     };
     obj.method();

This somewhat unexpected value of this in a nested function is according to Crockford (The good parts) a mistake in the design of JavaScript.

A mistake or not, guessing the value of this in a nested function is tricky business. After a nested function is returned from its host, the keyword this may or may not refer to the object, even when ostensibly this belongs to the body of the method. The value referred to by this requires close attention, mistakes are easily made. To exemplify this, two code snippets will be introduced that are almost the same, but yet give completely different results. The first snippet is:

     /* First code snippet */
     var obj  = {};
     obj.s    = "Object string";
     window.s = "Window string";
     obj.method = function(){
            println("P: " + this.s);
            return function(){
               println("Q: " + this.s);
            };
         };
     obj.method()();

The output of this example is the same as of the example before last, which is not surprising, because this in the first print belongs to the body of obj.method and this in the second print belongs to the nested function.

However, consider the next snippet which is almost, but not quite, the same. Notice that this in the first print statement still seems to belong to the body of obj.method and yet is bound to window, while this in the second print still appears to belong to the nested function and yet is bound to obj:

     /* Second code snippet */
     var obj  = {};
     obj.s    = "Object string";
     window.s = "Window string";
     obj.method = (function(){         // Evaluate rhs as "stand-alone" function
            println("P: " + this.s);   //    before assigning the return value to lhs
            return function(){
               println("Q: " + this.s);
            };
        }());
     obj.method();                     // inner function is method of obj

It is of interest to point out that the latter code snippet is a model for the assignment of a DOM (document object model, web page) event handler. The object obj models a HTML element that is the target of an event. The call: obj.method() corresponds to the firing of method upon the occurrence of an event on obj. The last snippet does what a web programmer would expect, provided he or she is not aware of the problems associated with the use of this in nested functions. In web applications this, appearing in an event handler, may be expected to refer to a target HTML element and not to the global window object.

Let us consider the two code snippets above in more detail. In the second snippet obj.method is assigned a function:

     obj.method ← function(){ println("Q: " + this.s); }

and obviously this refers to obj during execution of object.method(). In the following statement occurring in the second snippet:
     obj.method = (function(){
            println("P: " + this.s);
             ...
            };
        }());

the right-hand side is fully evaluated before assignment of the return parameter to obj.method. To remind the reader of this an extra pair of dummy parentheses is added. During this evaluation, this is not bound yet to any object and then, by default, it is bound to window.

In the penultimate example (the first code snippet), the order of calling triggered by the expression obj.method()() is as follows. First the rightmost pair of parentheses invoke:

     obj.method = function(){
            println("P: " + this.s);
               ...
         };

as method of obj, so that this gets the value obj. Then, because the expression returned:
         function(){
             println("Q: " + this.s);
         }

and the leftmost pair of parentheses is still waiting, the returned function is called as global function (as method of window). Because the latter function does not return an explicit value (it "falls off the end"), it returns undefined as final value of the total expression. A small modification of the first code snippet proves this.
     var obj  = {};
     obj.s    = "Object string";
     window.s = "Window string";
     obj.method = function(){
            println("P: " + this.s);
            return function(){
               println("Q: " + this.s);
            };
        };
     tmp = obj.method()();
     println("tmp: " + tmp);

Even if the above reasoning may not be very clear, the take-home message is clear:

Test the value of the keyword this carefully, especially in cases where nested functions containing the keyword are involved.

To contents

Currying

It may happen that a function fnc has many parameters, x1, x2, ..., that are constant during most of its calls and a few, y1, y2, ..., that vary between calls. It is then useful to turn the function into a closure that has x1, x2, ... in its lexical environment and y1, y2, ... as formal parameters. Schematically,
      var host = function(x1, x2, ...){
         return function(y1, y2, ..){
            ...
         };
      };

//  Assign x1, x2, ..
      var x1 = ..., x2 = ...

//  Fix x1, x2, ... inside fnc:
      fnc = host(x1, x2, ..);

//  From here on fnc can be called with different arguments y1, y2, ..
//  The arguments x1, x2, .. are preserved until reassignment of fnc.
      fnc(y1, y2, ...);

This partial application of arguments is called currying [named after H. B. Curry (1900–1982)]. All it needs is an extra host function.

In the following example the function prt prints four variables, the first two being constant. They are taken out the parameter list of prt and introduced as parameters of host.

      var host = function(x1, x2){
         return function(y1, y2){
            println(x1); println(x2);
            println(y1); println(y2);
         };
      };

      prt =  host("Wild", "horses");

      prt("won't ", "drag you away");

      prt("are a ", "nuisance");

      prt("aren't shot ", "I hope?");


An alternative way of currying is by means of the JS function-method call. If f is a function, f.call(null, x1, x2, y2, y2) calls f with arguments x1, x2, y1, y2. [The first argument replaces this by null everywhere in f]. Because a function is an object, a method (curry) may be defined that executes the function through call. Given a function (f in the next example), it is possible to define the method curry such that the function f is not affected, i.e., it does not have to be rewritten. Schematically,

      var f = function(x1, x2, y1, y2){
            println(x1); println(x2);
            println(y1); println(y2);
      };
      f.curry = function(x1, x2){
         var that = this;
         return function(y1, y2){
            that.call(null, x1, x2, y1, y2);
         };
      };
      g = f.curry("Cuddly", "cats");
      g("are", "sweet");
      g("must be ", "petted");

Along similar lines it is possible to define a general curry method applicable to any function. The JS method apply is similar to call, but takes an array of arguments. The place for a general curry function is as prototype of the built-in object Function.

      Function.prototype.curry = function(){
          var that = this;
          var args1 = arguments;
               return function(){
                  var args = [];
                  var i;
                  for (i=0; i < args1.length; i++) {       // first set of arguments
                          args[i] = args1[i]; }
                  for (i=0; i < arguments.length; i++) {   // second set of arguments
                           args.push(arguments[i]); }
                  that.apply(null, args);
               };
      };
// Trivial example function:
      function fnc(x1, x2, x3, x4, y1, y2){
              println(x1+' '+x2+' '+x3+' '+x4+' '+y1+' '+y2);
      }
      var g = fnc.curry('A', 'B', 'C', 'D');
      g(1,2);
      g(5,6);

To contents

Examples

Several examples that are more than mere code snippets will be discussed.

Countdown

Closure is at the basis of the following example of JavaScript code running in a web browser. Below the following piece of code, it is printed: "Will fire in x seconds" with x counting down from x = 10, 9, ... down to 0 with intervals of one second (1000 msec). After 10 seconds, countdown ends and *** FIRE *** is printed. (To restart the countdown hit the refresh key F5 of your browser.)
      function host(x){
          var a = document.getElementById("fire");
          var f = function(){
              a.firstChild.nodeValue = "Will fire in " + x-- +" seconds";
          };
          var id = setInterval(f, 1000);
          return function(){
              clearInterval(id);
              a.firstChild.nodeValue = "*** FIRE ***";
          };
      }
      var clear = host(10);  //call host with x=10; assign clear
      setTimeout(clear, 10100);         //cancel infinite loop calling f

Start count down


Explanation

To contents

Precomputation

In programming it often happens that a function needs repeatedly data that take many CPU cycles to generate and that are only needed by this one function. Of course, for efficiency reasons one does not want to recompute expensive data over and over again, and it is also preferable that the data are visible only to the function. In other words, one wants to precompute and save the expensive data inside the function. Such a function has the great advantage of being transferable as black box. There is no need for clumsy directions as: "precompute an array with such-and-such data and pass this array as third argument to the function".

In Fortran, with its static internal variables and its possibility to assign variables at compile time, precomputing is easy. One defines a boolean variable, call it first, internal to the function and one sets first at compile time equal to true. When the function is called for the first time, first is true: the expensive data are precomputed, stored in an internal (static) array, and first is set to false. Following entries into the function find the static variable first to be false and skip accordingly the precomputation.

In JavaScript one may use closure. Suppose for the sake of example that computation of the mathematical function cosine (in JS: Math.cos) is expensive and that its values are only needed in function f for certain angles, say between 0 and π in steps of π/10. For readers whose knowledge of trigonometry is rusty: cos(0) = 1, cos(π/2) = cos(90°) = 0, and cos(π) = cos(180°) = −1. As is usual on computers, the number zero will not appear as zero, but as a small number: x ⋅ 10−17, which is printed as x e−17.

     var f = (function(){
        var cos = [], i, angle, step = Math.PI/10;
        println("setting cos");
        for (i=0, angle = 0; angle <= Math.PI; angle=i*step){
           cos[i++] = Math.cos(angle);
        }
        return function(k){
           println("cos["+ k*step*180/Math.PI + "] = " +cos[k]);
        };
     }());     // assign return value
     f(0); f(5); f(10);

The big red parentheses are not required by the language. They are a conventional warning to the reader of the code that the anonymous function on the right-hand side is invoked. Consequently, f receives the return value of the anonymous function, not the anonymous function itself. The array cos, in the lexical environment of f, is set when the anonymous function is invoked, which happens only once. Note also that the string setting cos is printed once, indicating that the computation of the cosines happens indeed only once. The function f is assigned the nested function that prints the kth value.

To contents

Triple-product function

The following statements define the "higher order" function prod. It has three functions f, g, and h as parameters and returns a function that is the product of the three arguments. The parameters are in the lexical environment of the returned function and hence are constant.
      function prod(f,g,h){
         return function(x){
            return f(g(h(x)));
         };
      }

Note that prod returns a function of x. In the next example two mathematical triple-product functions will be defined, named p and q. Recall that

cos(0) = 1,  cos(π/2) = 0,  cos(π) = −1,  e0 = 1,   e1 = 2.718..,  e−1 = 0.3678...

so that

p(x) ≡ exp(cos(√x))   ⇒   p(0) = e,   p(π2/4) = 1,   p(π2) = 1/e. And q(x) ≡ exp(√cos(x))   ⇒   q(0) = e,   q(π/2) = 1.

One can now understand the output of the following code,
      var f1 = function(x){return Math.exp(x);};
      var f2 = function(x){return Math.cos(x);};
      var f3 = function(x){return Math.sqrt(x);};
      var pi = Math.PI;

// Define two different triple-product functions:
      var p  = prod(f1, f2, f3);
      var q  = prod(f1, f3, f2);

      var t;   // temp for printing
// Invoke and print them:
      t =  p(0);        println( t.toPrecision(6) );
      t =  p(pi*pi/4);  println( t.toPrecision(6) );
      t =  p(pi*pi);    println( t.toPrecision(5) );
      t =  q(0);        println( t.toPrecision(6) );
      t =  q(pi/2);     println( t.toPrecision(6) );

To contents

First derivative of function

Define a first derivative f  of a function f by the symmetric formula
f (x) := [f(x+h) − f(x−h)] / (2h),
where h is a small step (h2 may be neglected). Note that one finds often in this context the asymmetric definition
f (x) := [f(x+h) − f(x)] / h,
which also requires two evaluations of f(x) [usually the evaluation of  f(x)  is the cost-determining step]. Because the symmetric formula can be shown to give more significant figures than the asymmetric formula, it will be used in the next example.

Recall that the first derivative of x2 is 2x and of ex it is ex. The latter function is printed as comparison and gives an indication of numerical accuracy.

      // Define the differentiation function with
      //    global variable h as step size.
      var h = 1.e-3;
      function deriv(f){
          return  function(x){
              return (f(x+h)-f(x-h))/(2*h);
          };
      }

      // Define functions to be differentiated:
      var sq  = function(x){return x*x; };
      var exp = Math.exp;

      // and their derivatives (primed functions)
      var sqPrime  = deriv(sq);
      var expPrime = deriv(exp);

      // Invoke and print derivatives
      println(sqPrime(0).toPrecision(6));
      println(sqPrime(1).toPrecision(6));
      println(sqPrime(2).toPrecision(6));

      println(' ');
      println(expPrime(0).toPrecision(6)+' '
            + ' '+ exp(0).toPrecision(6));
      println(expPrime(1).toPrecision(6)+' '
            + ' '+ exp(1).toPrecision(6));
      println(expPrime(2).toPrecision(6)+' '
            + ' '+ exp(2).toPrecision(6));


The step size h was introduced as global variable. It can also be made part of the derivative function by currying. A new enclosing function with h as parameter is introduced and a closure deriv with upvalue h is returned.
      function derivative(h){
          return function(f){
             return  function(x){
                 return (f(x+h)-f(x-h))/(2*h);
             };
          };
      }
      var deriv   = derivative(1.e-3);

      // As before :
      var sq  = function(x){return x*x; };
      var sqPrime = deriv(sq);
      println(sqPrime(2).toPrecision(6));

To contents

Priviliged methods

The following example is due to Douglas Crockford. It describes a construction that keeps the value of the parameter param private to the object myContainer. The latter object is equipped with the priviliged method service that it receives as method during execution of the constructor function Constructor. A privileged method is able to access private variables and methods, and is itself callable by the outside world.

When object myContainer is constructed (by means of the operator new), the constructor function Constructor is executed with the keyword this having the value myContainer. Hence during execution of Container, the priviliged method myContainer.service becomes a closure that has access to the inner function dec and the local variable secret. The value of param cannot be modified (other than by reconstruction of myContainer) and it can be read three times only. A fourth attempt of reading returns Too many attempts. This is shown in the next code snippet in which an effort to modify param by a call Container('DEF') clearly fails.

     function Container(param) {
         var secret = 3;
         function dec() {
             if (secret > 0) {
                 secret--;
                 return true;
             } else {
                 return false;
             }
         }
         this.service = function () {
             if (dec()) {
                 return param;
             } else {
                 return "Too many attempts";
             }
         };
     }
     var myContainer = new Container('ABC');
     println(myContainer.service());
     println(myContainer.service());
     println(myContainer.service());
     println(myContainer.service());
     Container('DEF');
     println(myContainer.service());

To contents

References

To contents