001 // Copyright 2007 Waterken Inc. under the terms of the MIT X license
002 // found at http://www.opensource.org/licenses/mit-license.html
003 package org.waterken.factorial;
004
005 import org.ref_send.promise.Eventual;
006 import org.ref_send.promise.Promise;
007
008 /**
009 * A tail recursive factorial implementation.
010 */
011 public final class
012 Factorial {
013 private Factorial() { /* no instance interface */ }
014
015 /**
016 * Computes a factorial.
017 * @param _ eventual operator
018 * @param n <code>>= 0</code>
019 * @return promise for the factorial of <code>n</code>
020 */
021 static public Promise<Integer>
022 make(final Eventual _, final int n) {
023 if (n < 0) { return Eventual.reject(new Exception()); }
024 /*
025 * We'll simulate tail recursive calls by doing eventual invocations of
026 * our loop function. Since the call is eventual, the current stack
027 * frame is popped right away and the loop's stack frame isn't created
028 * until the next event loop turn. The same trick is used inside the
029 * loop itself. The chain of promises produced by these calls also
030 * collapses during each event loop turn, so that there's always only
031 * a constant number of objects referenced. The efficiency of this
032 * probably isn't as good as in a VM designed for tail recursion, but
033 * may be good enough for some purposes.
034 */
035 final Recursion loop_ = _._(new Recursion() {
036 public Promise<Integer>
037 apply(final Recursion tail_, final int i, final int acc) {
038 if (i == 0) { return Eventual.ref(acc); }
039 return tail_.apply(tail_, i - 1, i * acc);
040 }
041 });
042 return loop_.apply(loop_, n, 1);
043 }
044
045 /**
046 * The inner loop of a tail recursive factorial implementation.
047 */
048 static public interface
049 Recursion { Promise<Integer> apply(Recursion tail_, int i, int acc); }
050 }