Higher-Order Functions
in Java
javaHigherOrder

Functions as Objects?
In Java, neither static methods nor instance methods are considered to be objects.
How, then, could we implement something that behaves as a function taking functions as arguments, or one giving a function as a result?

Dynamic Creation
In Java, the only things that can be created dynamically are:
Objects
Arrays
and arrays behave as if a special built-in object.

Function Objects
We can define objects that behave as functions:
function world:
f(x, y)
object world:
f.apply(x, y)
Define a class for these objects: Function1, Function2, É depending on the number of arguments.

Example: map
In rex:
map(f, []) => [];
map(f, [A | L]) => [f(A) | map(f, L)];

Example: OpenList map
In Java:
static OpenList
map(Function1 f, OpenList L)
  {
  if( L.isEmpty() )
    return nil;
 else
    return cons(f.apply(L.first()),
                       map(f, L.rest());
  }

Specific case: square each element
class Function1
  {
  Object apply(Object x)
    {
    float num = ((Float)x).floatValue();
    return new Float(num*num);
    }
  }

Slight problem:
WeÕd need a different class for each function to be applied.
WeÕd also need a different map for each of those functions.
So nothing would be gained over ad hoc definitions of map-like functions.

Remedy:
We need a way to define one map, yet use it for lots of different Function classes.
A device that works for this is JavaÕs
interface
concept

Java Interfaces
An interface is like an abstract place-holder class.
A single interface can stand for an arbitrary number of classes that have certain methods in common.
The common methods are defined in the interface.
The various special classes are said to implement the interface.

Java Keywords
interface: used in place of ÒclassÓ for an interface definition
implements: added to class for an interface implementation

map arguments, the right way
interface Function1
  {
  Object apply(Object x);
  }
An interface does not implement methods; it only declares them.
All methods are implicitly public.

A map argument
class Squarer implements Function1
  {
      public Object apply(Object x)
    {
    float num = ((Number)x).floatValue();
    return new Float(num*num);
    }
    }
Usage: map(new Squarer(), L)

Another map argument
class Cuber implements Function1
  {
      public Object apply(Object x)
    {
    float num = ((Number)x). floatValue();
    return new Float(num*num*num);
    }
    }
Usage: map(new Cuber(), L)

Yet another
class Scaler implements Function1
  {
  private float factor;
  Scaler(float _factor) { factor = _factor;}
     public Object apply(Object x)
    {
    float num = ((Number)x). floatValue();
    return new Float(factor*num);
    }
    }
Usage: map(new Scaler(2.5), L)

Number vs. Float and Integer
Number is a class that generalizes Float and Integer.
Technically, Float and Integer ÒinheritÓ from Number
This is often done when they have a lot of methods in common.
Object is the class that generalizes all other classes.

Restrictions on interfaces
All methods are implicitly public.
No static methods are allowed.
No static constants are allowed.
Implementations of interfaces can include other methods and constants not mentioned in the interface itself.
A given class can implement multiple interfaces.

Exercise
Similar to map, develop the java representation of reduce.
In rex:

reduce(b, u, []) => u;
reduce(b, u, [A | L]) => b(A, reduce(b, u, L));