What Exactly Is A First Class Function - And Why You Should Care
Written by Ian Elliot   
Friday, 31 May 2013

You may have heard people saying that in some language or another that functions were first class objects, or have come across the term first class function. What does it mean? And why is it so good?

Object-oriented programming is the standard paradigm, no matter what programmers of other persuasions may say. It is the one we use - the others we simply try out as an alternative. However, as well as exploring other ways of doing the job, it is important that at least now and again we look at how we approach objects. 

The big problem is that object-oriented programming was introduced with procedural modular programming as the dominant approach and this has colored the facilities we use to build objects. So too has the need to make our languages efficient. In particular, this has resulted in moving away from the simple principle "everything is an object".

When the object-oriented idea entered programming - about the time Simula was introduced - the key ideas used to construct a program were variables and functions (or procedures or subroutines). What you did was you wrote functions that called other functions that called other functions and so on until you got down to a small enough task for which you could actually write some lines of code that got things done. Programs were structured using decomposition into modules comprised of functions. 

When the idea of organizing things into objects came along it was natural to keep the variables and the functions. So objects had properties and the properties could be variables - i.e. data properties - or they could be functions - i.e. code properties or methods. The idea that an object is comprised of properties and methods is a very old one and something that many programmers don't even think much about. If they do then it is more likely that they would reject the idea of data properties than code properties. For example, Java programmers don't think you should use data properties or fields. Instead every property should be a function and data properties are simply represented by getter and setter methods - or accessor methods. 

The problem with this approach to objects is that it complicates things by having three basic entities in its programming model - objects, variables and functions. 

A much simpler approach is to try to stick as closely as possible to the "everything is an object" idea. 

This is harder than it looks for a programmer brought up on a diet of primitive data types and functions.

For example, what does:

var a=1;

mean? Most programmers would say something like:

"store the value 1 in the variable a"

However with just a little re-orientation you can just as easily tell the story as:

set a to reference the object 1

Once you start telling this story you have to stick to it and sometimes this can be hard. For example, what does:

var b=a+1;

mean?

Again most programmers would say:

"take the contents of a, add one to it and store the result back in b".

A different story that fits in with the "everything is an object idea is:

"the binary operator + takes references to two number objects and returns a reference to a number object as its result.  In this case it acts on the object 1 referenced by a and another reference to the same object and sets b to reference the object 2."

Okay, you get the idea. 

Notice that this is just a different way of telling the same story but in many languages numbers are objects and can have properties. For example in JavaScript you can write:

1.toString();

where toString() is a method of the 1 object. In this case the "everything is an object" way of explaining things is more appropriate.

To come back to the main issue - what are first class functions?

If you want to add objects to a language, or if you are inventing a language that will be suitable for programmers who are used to building programs from functions, it is very natural to create objects that can have properties that are data or code. To allow them to have code properties you need another entity - the function. Methods are the natural way to allow objects to "do" things. You can think of methods as being called, or invoked, in response to a message passed to the object. or triggered in response to an event - but methods are what objects do and data is what objects are.

The big problem with this approach is that you have just introduced something into the programming approach that isn't an object. That is, a method isn't an object. This causes lots of problems later on in any language that has methods as something less than an object.

You often can't just create a function to do a single job because all functions have to be methods that belong to objects, i.e. you can't have a disembodied function just floating around. For example, functions are not part of the type hierarchy because they are not objects. This generally has the knock-on effect that you can't do things like passing a function to a method. 

To solve these, and other problems, languages have had to introduce ideas like delegates in C# - which is an object that wraps a function - and lambda expressions so that you can create functions on the fly. 

This is all very logical if you proceed from the idea that there are objects and functions - but if you decide that functions are objects you get a huge simplification. 

Going back to the way that objects are defined we can simply say that an object has properties and each of those properties is just another object. 

This works fine as long as everything is an object. 

Now you can have a data property by simply storing a number object, or a string object or whatever, as the property. You can has a code property, i.e. a method by storing an object that happens to be a function. 

Problem solved!

With functions as objects you don't need to do anything special to allow them to be used in ways that seem natural. Now you can create a function that isn't a property of another object, i.e a standalone function that isn't a method. You can also pass functions to other functions since objects are the only argument that a parameter can have - remember everything is an object.

There is one small problem.

How do you define a function object?

There are many ways to do it but the simplest, and the one that seems to result in the least contradiction between what is and what isn't an object, is to say that a function object simply has a block of code associated with it. Just as the value 1 is intrinsic to the 1 object, so the code block is intrinsic to a function object. So when you define a function object you have to provide the code that it represents.

For example:

function myFunc(parameters){
 code
}

creates a function object called myFunc and associated it with the code that follows. 

Notice that you could think that allowing the code to be a property would be a good idea but this simply reinvents the idea of a method which isn't an object. No, you can't do much better than just allowing an object to have an association with the code that makes it a function object.

We have one more part of the puzzle to solve - how to invoke the code. 

This is very easy and you can probably guess. All we have to do is invent the () operator which takes a function object and returns the evaluation of its associated code. Of course this makes an object function invocation look exactly like a traditional function call. If you also allow arguments within the operation it is indeed identical. 

Notice that myFunc is now the myFunc function object and yes you it can have properties and some of these properties can be function objects. However myFunc() is the object that the code associated with myFunc produces. 

Now you know what a first class function is. 

It is just an object that happens also to be a function. 

When you think about it for a while you can see that it is a huge simplification and reveals the simple fact that the way that we do objects in other languages, complete with properties that are methods, is just a historical hangover from more primitive times. 

Related Articles

Lambdas and Delegates - why bother?

Covariance and contravariance - a simple guide

Programming Paradigms for Languages

JavaScript Objects With Value - valueOf and toString

Javascript Jems - First class functions

 

To be informed about new articles on I Programmer, install the I Programmer Toolbar, subscribe to the RSS feed, follow us on, Twitter, Facebook, Google+ or Linkedin,  or sign up for our weekly newsletter.

 

blog comments powered by Disqus 

 

Last Updated ( Saturday, 01 June 2013 )
 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.