Approximating First-Class Functions in Java

The only parts of our JDBC example that would change if we were collecting
a different type of object would be:

The connection, which was obtained outside of the block shown.

The string used in the query.

The body of the while loop.

The connection and the string are easy, since we can pass them in to a
method that captures the pattern. The body of the while loop is tougher,
because it's well, a chunk of code, which is hard to manipulate in Java.
In general, if you want to pass around code in Java, you have to create an
instance of a class. Thanks to interfaces and anonymous classes, we can
create an anonymous class just for the code in question.

To start our translation of the Lisp map idiom into Java, we define the
following interface:

An object that implements RowFunc is sort of like a function
in Lisp, in that it can be called (by invoking the of method),
passed to another function, returned from a function, and stored in a data
structure. Of course, we have to explicitly apply it, but it's a start. We
call RowFunc's method of so that you can read
an invocation of a RowFunc named f as
f "of" whatever it's applied to. I have a mathematical
background (and a possibly too-great love of concision). In any event,
here's how we use the interface to abstract our "collect all of the objects in
the ResultSet" pattern:

You'll note that we don't first pull all of the results into a
List and then map over that. Although that would be a
perfectly valid way to work, JDBC ResultSets are common enough
(and there's enough interesting ResultSetMetaData in them),
that it seemed worthwhile to have a special purpose method to map from a
ResultSet to a List. Later in the article, we
develop a nice way to go from a ResultSet to a
List of HashMaps, which is about as general as
you can get when dealing with unknown data.

With these general definitions in place, we can now rewrite our earlier
specific query using an anonymous inner class as:

Now, in this one case, we haven't saved much in the way of typing, though
it is certainly nice that the JDBC boilerplate has disappeared from our
code. However, if we need to create a list of users again somewhere else,
we can just pass in makeUser again:

If "create a User from a row of a ResultSet"
turns out to be a useful concept, having abstracted it into a function
that can be easily manipulated will prove its value over time. Speaking
of easy manipulation, wouldn't it be nice if we stored the
makeUser function with the User class? As
mentioned above, we can store these function-like objects in data
structures:

Note that before, User had a constructor that took three
params, whereas now we're just directly passing in the ResultSet. This eliminates the possibility of confusing the order of the args. Now our call looks like this:

Let's keep improving things. Every class we're going to fit into this
paradigm is going to have a nearly identical make static
method. That seems a bit wasteful. What if we could write a function
that returned a function to do it for us? We can do that, using a class
constructor and a bit of reflection:

The complexity of using reflection here is a clear demonstration of why
it's too tricky to use in day-to-day programming. As part of an
infrastructure (which is how we can think of RFMaker), it's
worth the effort, but the above multi-exception monstrosity should never
appear in normal code. It's not clear exactly how to best handle the host
of checked exceptions. We opt for a fail-fast runtime exception, which
seems reasonable.