Function Pointer – Does Function Pointer Have the Same Expressive Power as Function as Parameter?

functional programming

In functional programming language, a function can be passed as an argument to another function. In programming language like C/C++, a function pointer referring to a function can be passed to a function that can invoke the external function through dereference.

Then, does function pointer have the same expressive power as function as parameter in functional programming language?

Best Answer

A function pointer (e.g. in C or C++) is only the address of some machine code (computing some function). It does know about any data except the constants embedded in the code, and the static data referenced by it.

Conceptually (e.g. in lambda-calculus) a function needs both some code to be computed, and some data to be accessed. So a function usually has bound variables, that is closed variables. Hence, a function is a mixture of code and data, that is, a closure. Practically speaking, a closure contains not only code (some "function pointer" à la C) but also data.

Notice that C++11 introduced closures, anonymous functions (a.k.a. lambda-expressions), and std::function.

Most (but not all) functional languages (e.g. Ocaml) prohibit comparing functions (that is, closures), because conceptually that would mean comparing the behavior of functions (and that is undecidable, read about Rice's theorem).

So closures are more expressive than function pointers. In this answer I claim that every function is conceptually a closure (in C, the closed values being the static data).

Because C does not have genuine closures (but n2030 is a proposal to add them to some future C2x standard), most libraries wanting "closures" are actually taking the convention that function pointers are passed as callbacks with some explicit client data (mimicking closed values); for a simple example look into GNU libc qsort_r(3). For a more complex example look into the source code and coding conventions of the GTK graphical toolkit.

From both an implementation and a theoretical point of view, closures are mixing (like objects) data and code. In the RefPerSys system this property is used, since it aims to generate more and more of its code.

Books like the Pi-calculus (by Davide Sangiori and David walker) ISBN 0-521-78177-9, or a Theory of objects (by Martin Abadi and Luca Cardelli) ISBN 0-387-94775-2 or Artificial Beings - the conscience of a conscious machine (by Jacques Pitrat) ISBN 9781848211018 or Types and Programming languages (by Benjamin Pierce) ISBN 9-780282-162098 or Theories of programming languages (by John Reynolds) ISBN 0-521-59414-8 or Christian Queinnec's Lisp in Small Pieces are explaining all that much better than I could do.

If you can afford going to some university library or buying books, I recommend reading them.