Posted by & filed under Java.

Here’s a sillier one from last night…

People often complain about not being able to return multiple values from a method in Java. I can’t see a good reason for wanting to do this, but some do.

The example I was given was wanting to do:

int foo, bar, baz; list(foo, bar, bar) = func(ponies);

Where func(ponies) returns 3 values which are then assigned to the local variables foo, bar, and baz.

There are plenty of sensible ways of achieving this, but what if we’re trying to get as close as possible to the above method? We can only return one thing from a method, but that could be a chain. We also can’t modify the local foo,bar,baz from inside the list method, but we could if we wrap them in references.

If we abuse the fact that currency characters are valid identifiers in Java, for the ultimate in unreadability; We can use $(x,y) to be a pair of x and y, $$ to terminate a list, and £(x) to either reference or dereference x.

Then we can do something like this ¬_¬

/** OUTPUT
Foo = 1
Bar = 2
Bingo = Badgers
Baz = 3
**/
 
package scratchpad;
 
import static scratchpad.$.$;
import static scratchpad.$$.$$;
import static scratchpad.$.expand;
import static scratchpad.£.£;
 
public class MultipleReturn
{
	public static void main(String... args)
	{
		new MultipleReturn().demo();
	}
 
	public void demo()
	{
		£<Integer> foo = £(-1), bar = £(-1), baz = £(-1);
		£<String> bingo = £("");
 
		expand(foo()).into(foo,bar,bingo,baz);
 
		System.out.println("Foo = " + £(foo));
		System.out.println("Bar = " + £(bar));
		System.out.println("Bingo = " + £(bingo));
		System.out.println("Baz = " + £(baz));
	}
 
	public $<Integer,$<Integer,$<String,$<Integer,$$>>>> foo()
	{
		return $(1,$(2,$("Badgers",$(3,$$))));
	}
}
 
interface Tuple {}
 
class $$ implements Tuple
{
	private $$() { }
	public static $$ $$ = new $$();
}
 
class $<T,U extends Tuple> implements Tuple
{
	public T _1;
	public U _2;
 
	protected $(T t,U u)
	{
		this._1 = t;
		this._2 = u;
	}
 
	public static <T> $<T,$$> $(T t)
	{
		return new $<T,$$>(t,$$);
	}
 
	public static <T,U extends Tuple> $<T,U> $(T t, U u)
	{
		return new $<T,U>(t,u);
	}
 
	public interface Expander
	{
		public void into(£... refs);
	}
 
	public static Expander expand(final $<?,? extends Tuple> vals)
	{
		return new Expander()
		{
			public void into(scratchpad.£... refs)
			{
				if (refs.length < 1)
					return;
 
				$ current = vals;
				refs[0]._1 = current._1;
				if (current._2 instanceof $$)
					return;
				int i = 1;
				while (!(current._2 instanceof $$))
				{
					if (i >= refs.length)
						return;
					current = ($)current._2;
					refs[i]._1 = current._1;
					i++;
				}
			}
 
		};
 
	}
}
 
class £<T> extends $<T,$$>
{
	protected £(T t)
	{
		super(t,$$);
	}
 
	public static <T> £<T> £(T t)
	{
		return new £<T>(t);
	}
 
	public static <T> T £(£<T> t)
	{
		return t._1;
	}
}

Tags:

Leave a Reply

  • (will not be published)