Local functions
Neal Gafter
neal at gafter.com
Tue Feb 9 17:12:41 PST 2010
The Lambda project page (and various other references to the project)
describe it as being about "First-class functions, function types, and
lambda expressions". So far we've been talking exclusively about the
latter two issues, and not "first-class functions".
Functions would provide a way of writing recursive computations in a
local scope. Unlike lambda expressions (which are anonymous
functions), function declarations introduce a name for the function
being declared.
For example, if we add functions, you could write (in a local scope)
either something like
int factorial(int x)
(x <= 1) ? 1 : x*factorial.(x-1);
or
int factorial(int x) {
if (x <= 1) return 1;
return x * factorial.(x-1);
}
or both (syntax TBD).
For consistency with function types and lambda expressions, I would
expect the introduced name to be in the variable namespace, and
describe a final variable of function type. In short, the two
declarations above would be defined as meaning
final #int(int) factorial = #(int x)
((x <= 1) ? 1 : x*factorial.(x-1));
and
final #int(int) factorial = #(int x) {
if (x <= 1) return 1;
return x * factorial.(x-1);
};
But without any worry about the variable being usable (recursively)
inside the function because of definite assignment issues.
These would be usable as a value of function type
#int(int) fac2 = factorial;
The traditional distinction between functions and methods is that
methods are defined in an object scope, and therefore the object's
members are in scope. Functions, on the other hand, are defined in
whatever scope they are declared in, and therefore inherit their
lexical scope (including, e.g., "this") from their point of
declaration.
The main downside of the syntax I've selected, above, is that it
provides no way to distinguish a method declaration from a member
function declaration. The reason that the distinction is meaningful
is that these two concepts imply different namespaces for the name
that is defined, and also because methods are by default virtual.
(Interestingly, functions and methods declared in class scope would
have the same treatment of "this" - the enclosing instance - because
both are declared in class scope.) Adding support for "method
references" <http://javac.info/closures-v06a.html> eases distinction.
Local functions can be convenient in writing code that would otherwise
require writing a complex lambda (e.g. too complex to write inline in
the middle of some expression, but you still want to keep it local to
its use site).
I don't know if Sun had anything like this in mind when they described
project Lambda. Local functions appeared in version 00 of BGGA
<http://www.javac.info/closures-v00.html> but were dropped in later
revisions.
More information about the lambda-dev
mailing list