First-Class Functions
Another useful feature that a programming language can have is first-class functions. A first-class function is a function that can be used as data.
In a language in which you can treat functions as data, you can create variables that refer to them, pass them around as arguments to functions, and return them from functions. Once case where you might use this is the famous map function.
Say that I just got some string from a file or something and that the string contains a series of integers separated by spaces. Say I use a string-splitting function to get an array of strings containing each of the integers (still as strings). I have access to a library function to parse an integer from a string, and I want to use it to convert each of these strings containing integers to actual integer values. I create the new array and write a loop to convert each string and store the resulting integer in the new array.
Now say I want to take a different array of integers and find the absolute value of each and store the results in a new array. I can use another loop to do this. However, I have this pattern showing up in my code: start with an array, perform some transformation of each value in the array, and store all of the results in a new array. I could just write out the code to do this each time, but there is a way to abstract out the process of creating the new array, looping, transforming, and storing.
I can write a function that takes as arguments
- an array of type x
- a function for somehow transforming objects of type x into objects of type y (possibly the same type as x)
and have it create an array of elements of type y of the correct length, loop over the values in the original array, call the function argument to do the transformation, store the results in the new array, and return the new array.
After I've written this function, map, I don't have to write this code out by hand any more.
Objective-C should have function pointers because C has them.
The way I described map also took advantage of some sort of generic typing.
Closures
Another feature is closures. A closure is a function object that captures some of the variables that existed in the scope in which it was created. What does that mean?
Some languages let you write function literals, functions that don't (necessarily) have names and just appear in you code without a special separate declaration. When you write a function literal in another function, there might be variables in the same scope as the function literal. There are situations where you might find it useful to use those variables inside of the function literal and have those variables stay with the function object. Such a function object would be a closure.
Here's an example of code that I wrote that creates a closure (written in Common Lisp):
(defun exponential-change (function constant)
(lambda (time)
(* (expt constant time) (funcall function time))))
(Don't ((let (the) parentheses) scare you)). Think of it as being written like this:
function exponential_change (function, constant) {
return function (time) {
return exponent(constant, time) * function(time);
};
}
I wrote this for synthesizing sound. I represent a sound as a function of time that returns amplitude samples (-1 to 1). This function, exponential-change, transforms a sound by making the amplitude increase or decrease (depending on the constant) in an exponential fashion. exponential-change creates returns a function of time based on another function of time. The fact that the new function keeps track of what function it needs to modify prevents other code from having to keep track of that detail.
Closures not only keep track of the values of the variables they capture but also the variables themselves. This means that you could create a function that modifies those variables.