[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: accumulator generator (Java)



> I'm especially interested in knowing what, if any,
> would be the canonical implementation in Java and C++...

"Canonical" in Java would simply be to use a class:

	public class foo {
		private int n;
		public foo( int n ) { this.n = n; }
		public int inc( int i ) { n += i; return n; }
	}

Which is invoked as:

	foo f = new foo( 4 );
	f.inc( 3 );
	f.inc( 2 );

Of course, this uses an object ("to simulate a closure", if you like) as
opposed to "pure" functions.

Can we do better in Java?  Well, sort of yes, but mostly no.  Here are a
couple of definitions that can be added to any class (i.e. a separate
supporting class definition is not required), that use Java's closure-like
construct, an (anonymous) inner class:

	interface Incrementor {
		int inc( int i );
	};

	static public Incrementor gen( final int n ) {
		return new Incrementor() {
			public int inc( int i ) {
				n += i;
				return n;
			}
		};
	}

Assuming this is added to a class named foo, the usage would be:

	Incrementor f = foo.gen( 4 );
	f.inc( 3 );
	f.inc( 2 );

The point about this is that I have attempted, exceedingly awkwardly, to
eliminate the need for an instance variable, making use of the closure-like
behaviour of inner classes in Java.  Unfortunately, this is illegal Java.
Interestingly, though, it works under IBM's Jikes compiler (v1.14), so I'm
pointing it out in the general spirit of perversity that flourishes on lists
like this.

It's illegal because the variable n must be declared as "final" (immutable),
but it is being mutated within the method inc().  Sun's compiler catches
this with "cannot assign a value to final variable n", but Jikes does not.
The code generated by Jikes seems to work correctly, even under the Sun JVM
(v1.3.1).

In Java, the closure-like behavior of an inner class, like the one defined
in the function gen(), is restricted in various ways, one of which is its
ability to access variables in its enclosing scope - it can only access
"final" variables.
So in legal Java, I don't think it's possible (?) to write this code to rely
on closure-like behavior, without using an instance variable; and besides, a
pure object approach tends to be far more natural in Java.

This sort of thing always reminds me of the quotation (or paper title) which
goes "Objects are a poor man's closure".  As soon as I got to the point of
believing that, I read in Queinnec's "Lisp in Small Pieces" a statement very
close to "closures are a poor man's object".  It was at that point that I
reached satori...  ;)

Anton