The CS ‘closure’ notion is closely associated with the first class function. (elaborate!)
The first Fortran provided only a few built in functions such as square root. The Fortran programmer had to pass arguments and results in global variables and arrange to do a computed return in order to define his own function. Fortran II allowed the programmer to define a function with real parameters and to return an answer using the same invocation syntax as the square root function.
Here are three significant features of functional programming:
Apple blocks provides the functionality of all three features without garbage collection, but with a somewhat awkward syntax and semantics.
Here are three small programs that both gcc 4.2.1 and clang 3.0 approve of:
#include <stdio.h> int main(){int x = 123; void(^p)(int) = ^(int y){printf("%d %d\n", x, y);}; p(456); return 0;} #include <stdio.h> int main(){int x = 123; (^(int y){printf("%d %d\n", x, y);})(456); return 0;} #include <stdio.h> typedef void t(int); t^ u; void r(int y){int x = 123; u = ^(int y){printf("%d %d\n", x, y);};} int main(){r(42); u(456); return 0;}They all print “123 456”. x is read-only in the inner scopes however, unlike nested functions. I wish I knew what ‘^’ means! Perhaps it is a throwback to the notation “x̂(x+2)” of Principia Mathematica which means λx(x+2). The last example returns a routine via the global variable u, but cannot return a function the normal way:
#include <stdio.h> typedef void t(int); t r(int y){int x = 123; return ^(int y){printf("%d %d\n", x, y);};} int main(){t e = r(42); e(456); return 0;}Both gcc and clang recoil at a function returning a function. I can’t imagine why.
You can pass a block as argument between these two separately compiled routines:
typedef void(^p)(int); void rou(p u){u(3);} #includetypedef void(^p)(int); void rou(p); int main(){rou(^(int y){printf("%d\n", y);}); return 0;}