|What Exactly Is A First Class Function - And Why You Should Care|
|Written by Ian Elliot|
|Thursday, 07 March 2019|
Page 2 of 2
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 because you can only pass objects.
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 after all 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 have a code property, i.e. a method by storing an object that happens to be a function.
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. In fact you now have a very clear definition of what a method is - a method is just a function object that is a property of another object.
Notice that this also allows you to have functions that are not methods. That is function objects that are not properties of other objects. 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.
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 the arguments are objects and if the function object returns a result it too is an object. So the () operator acts on a object and returns an object just like all the other operators in the language. Of course it can also have side effects from its evaluation and this is where we part company from functional programming.
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.That's right function objects can have methods and data properties. 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.
Lambdas and Delegates - why bother?
Covariance and contravariance - a simple guide
Programming Paradigms for Languages
What Programmers Know
* Recently revised
or email your comment to: email@example.com
To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
|Last Updated ( Thursday, 07 March 2019 )|