# Closures and Multiple Return Values

Posted by brucechapman on November 28, 2007 at 8:00 PM PST

In javaposse 150 the guys were talking about something and veered off on a tangent talking about multiple return values and tuples and such like. Next up they talked about the closures JSR. That sparked a thought that maybe we could transform the multiple return values problem in order to solve it using closures.

So what if instead of returning multiple values, a method returned void, but had another formal parameter which was a closure to receive the results of the method?

I've downloaded the closures prototype compiler (2007-11-20 version) and had a play with that idea. Now if it had been a complete disaster you wouldn't be reading this, because I wouldn't have blogged about it, but you are reading it so lets get on with it.

Here is a method to convert rectangular to polar coordinates and pass the results (r,theta) to a receiver closure.

``    static void toPolar(double x, double y, {double, double => void } rThetaReceiver) {        rThetaReceiver.invoke(Math.sqrt(x*x + y*y), Math.atan2(y, x));    }``

And this is how you use it

``        // test toPolar        toPolar(3,4,{double r, double theta =>            System.out.format("3,4 = %f<%fRad%n",r,theta);        });``

Here is the complete class with both converters, and a round trip test. Note how the round trip nests the closures.

``package closures.multireturn;/** * * @author bchapman */public class RectangularToPolar {        static void toPolar(double x, double y, {double, double => void } rThetaReceiver) {        rThetaReceiver.invoke(Math.sqrt(x*x + y*y), Math.atan2(y, x));    }        static void toRectangular(double r, double theta, { double, double => void} xYReceiver) {        xYReceiver.invoke(r * Math.cos(theta), r * Math.sin(theta));    }    public static void main(String[] args) {                // test toPolar        toPolar(3,4,{double r, double theta =>            System.out.format("3,4 = %f<%fRad%n",r,theta);        });                // test toRectangular        toRectangular(5, Math.PI / 2, { double x, double y =>                System.out.format("5<90deg = %f,%f%n",x,y);        });        // test Round trip - toPolar and back to rectangular        toPolar(3,4,{double r, double theta =>            System.out.format("3,4 = %f<%fRad%n",r,theta);            toRectangular(r, theta, { double x, double y =>                System.out.format("%f<%fRad = %f,%f%n",r,theta,x,y);            });        });    }}``

And here's the output

``C:\projects\quickhacks\src>javac closures\multireturn\RectangularToPolar.javaC:\projects\quickhacks\src>java closures.multireturn.RectangularToPolar3,4 = 5.000000<0.927295Rad5<90deg = 0.000000,5.0000003,4 = 5.000000<0.927295Rad5.000000<0.927295Rad = 3.000000,4.000000``

This looks promising. I'll keep exploring.

One of the interesting things which I think this demonstrates is how closures are such a fundamental building block that they offer the potential of solving quite a few other problems that we've traditionally thought of as requiring specialist language changes. Maybe such solutions are not quite as nice as a specialist language change, but good enough that the advantage of not having yet another language feature outweighs the now small disadvantage of not having the perfect solution.

Related Topics >>