Skip to main content
Engineering LibreTexts

4.5.A Functions as first-class objects

  • Page ID
    10900
  • In most programming languages, functions are not first-class objects. That is, a function cannot be treated as a data value in the same way as a string or an int. However, newer versions of Java do take a step in this direction with ‘lambda expressions’. In Java it is not yet possible for a function to be a parameter to another function. For example, suppose in Java we could write the function prototype

    This is a prototype for a function named sumten whose parameter is a function. The parameter is specified by the prototype Function<Integer,Double> f. This means that the parameter must be a function from int to double. The parameter name, , stands for an arbitrary such function. Mathematically, \(f \in\) double \(^{i n t}\), and so sumten: double \(^{i n t} \rightarrow\) double.

    My idea is that sumten(f) would compute f(1)+ f(2)+···+ f(10). A more useful function would be able to compute f(a)+ f(a+1)+···+ f(b) for any integers and b. This just means that and should be parameters to the function. The prototype for the improved function would look like 

    The parameters to sum form an ordered triple in which the first coordinate is a function and the second and third coordinates are integers. So, we could write

    sum: double \(^{\text { int }} \times i n t \times i n t \rightarrow\) double 

    It’s interesting that computer programmers deal routinely with such complex objects.

    Languages where functions are first-class objects are for example Python and Scala. These languages support what is called functional programming.

    One of the most accessible languages that supports functional programming is JavaS- cript, a language that is used on webpages. (Although the names are similar, JavaScript and Java are only distantly related. You probably knew that.) In JavaScript, the function that computes the square of its parameter could be defined as

    This is similar to the Java definition of the same function, but you’ll notice that no type is specified for the parameter or for the value computed by the function. Given this definition of square, square(x) would be legal for any of any type. (Of course, the value of square(x) would be undefined for most types, so square is a very partial function, like most functions in JavaScript.) In effect, all possible data values in JavaScript are bundled together into one set, which I will call data. We then have square : data → data.

    In JavaScript, a function really is a first-class object. We can begin to see this by look- ing at an alternative definition of the function square:

     Here, the notation function(n) { return n*n; } creates a function that computes the square of its parameter, but it doesn’t give any name to this function. This function object is then assigned to a variable named square. The value of square can be changed later, with another assignment statement, to a different function or even to a different type of value. This notation for creating function objects can be used in other places besides assignment statements. Suppose, for example, that a function with prototype function sum(f,a,b)hasbeendefinedinaJavaScriptprogramtocompute f(a)+ f(a+1)+···+ f(b). Then we could compute \(1^{2}+2^{2}+\cdots+100^{2}\) by saying

    Here, the first parameter is the function that computes squares. We have created and used this function without ever giving it a name.

    It is even possible in JavaScript for a function to return another function as its value. For example,

     Here, Math. pow \((\mathrm{x}, \mathrm{n})\) computes \(x^{n},\) so for any numbers \(a\) and \(n,\) the value of monomial \((a, n)\) is a function that computes axn. Thus,

    would define \(f\) to be the function that satisfies \(f(x)=2 x^{3},\) and if sum is the function described above, then

     would compute \(8 * 3^{4}+8 * 4^{4}+8 * 5^{4}+8 * 6^{4} .\) In fact, monomial can be used to create an unlimited number of new functions from scratch. It is even possible to write monomial(2,3)(5) to indicate the result of applying the function monomial(2,3) to the value \(5 .\) The value represented by monomial \((2,3)(5)\) is \(2 * 5^{3},\) or \(250 .\) This is real functional programming and might give you some idea of its power.

     

    Exercises

     

    1. For each of the following Java-like function prototypes, translate the prototype into a standard mathematical function specification, such as func : float → int.

      a) int strlen(string s)
      b) double pythag(double x, double y)

      c) int round(double x)
      d) string sub(string s, int n, int m)
      e) string unlikely(Function<String,Integer> f )

      f) int h( Function<Integer,Integer> f, Function<Integer,Integer> g )

    2. Write a Java-like function prototype for a function that belongs to each of the following sets.

    a) string \(^{\text { string }}\)

    b) boolean^ float x float

    c) \(f l o a t^{i n t^{i n t}}\)

    3. It is possible to define new types in Java by using classes. For example, the definition

    defines a new type named point. A value of type point contains two values of type double. What mathematical operation corresponds to the construction of this data type? Why?

    4. Let square, sum and monomial be the JavaScript functions described in this section. What is the value of each of the following?

    a) sum(square, 2, 4)
    b) sum(monomial(5,2), 1, 3)

    c) monomial(square(2), 7)
    d) sum(function(n) { return 2 ∗ n; }, 1, 5)e) square(sum(monomial(2,3), 1, 2))

    5. Write a JavaScript function named compose that computes the composition of two functions. That is, compose( ,g) is ◦ g, where and are functions of one parameter. Recall that ◦ is the function defined by ( ◦ g)(x) = (g(x)).