remove redundant interfaces and generalize shift/reset generics

Turns out Function can do the jobs of both CallbackReceiver and
FunctionReceiver, so I've removed the latter two.

Also, shift and reset should work with a combination of types, not
just a single type, so I've expanded their generic signatures.
This commit is contained in:
Joel Dice 2014-03-21 07:33:50 -06:00
parent 570b5447bf
commit fd778c2c76
10 changed files with 120 additions and 120 deletions

View File

@ -1,15 +0,0 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public interface CallbackReceiver<T> {
public T receive(Callback<T> callback) throws Exception;
}

View File

@ -127,14 +127,14 @@ public class Continuations {
* specified receiver.
*
* <p>This method will either return the result returned by
* <code>receiver.receive(Callback)</code>, propagate the exception
* <code>receiver.call(Callback)</code>, propagate the exception
* thrown by that method, return the result passed to the
* handleResult(T) method of the continuation, or throw the
* exception passed to the handleException(Throwable) method of the
* continuation.
*/
public static native <T> T callWithCurrentContinuation
(CallbackReceiver<T> receiver) throws Exception;
(Function<Callback<T>,T> receiver) throws Exception;
/**
* Calls the specified "before" and "after" tasks each time a
@ -183,13 +183,13 @@ public class Continuations {
}
}
public static <T> T reset(final Callable<T> thunk) throws Exception {
public static <B,C> C reset(final Callable<B> thunk) throws Exception {
final Reset reset = new Reset(latestReset.get());
latestReset.set(reset);
try {
T result = callWithCurrentContinuation
(new CallbackReceiver<T>() {
public T receive(Callback<T> continuation) throws Exception {
C result = (C) callWithCurrentContinuation
(new Function<Callback<Object>,Object>() {
public Object call(Callback continuation) throws Exception {
reset.continuation = continuation;
return thunk.call();
}
@ -207,26 +207,26 @@ public class Continuations {
}
}
public static <T> T shift
(final FunctionReceiver<T> receiver)
public static <A,B,C> A shift
(final Function<Function<A,B>,C> receiver)
throws Exception
{
return (T) callWithCurrentContinuation(new CallbackReceiver() {
public Object receive(final Callback continuation) {
return (A) callWithCurrentContinuation
(new Function<Callback<Object>,Object>() {
public Object call(final Callback continuation) {
final Reset reset = latestReset.get();
reset.shifts = new Cell(new Callback() {
public void handleResult(Object ignored) {
try {
reset.continuation.handleResult
(receiver.receive
(receiver.call
(new Function() {
public Object call(final Object argument)
throws Exception
{
return callWithCurrentContinuation
(new CallbackReceiver() {
public Object receive
(Callback shiftContinuation)
(new Function<Callback<Object>,Object>() {
public Object call(Callback shiftContinuation)
throws Exception
{
reset.shifts = new Cell

View File

@ -10,6 +10,6 @@
package avian;
public interface Function<T> {
public T call(T argument) throws Exception;
public interface Function<A,B> {
public B call(A argument) throws Exception;
}

View File

@ -1,15 +0,0 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public interface FunctionReceiver<T> {
public T receive(Function<T> function) throws Exception;
}

View File

@ -8044,8 +8044,8 @@ callWithCurrentContinuation(MyThread* t, object receiver)
if (root(t, ReceiveMethod) == 0) {
object m = resolveMethod
(t, root(t, Machine::BootLoader), "avian/CallbackReceiver", "receive",
"(Lavian/Callback;)Ljava/lang/Object;");
(t, root(t, Machine::BootLoader), "avian/Function", "call",
"(Ljava/lang/Object;)Ljava/lang/Object;");
if (m) {
setRoot(t, ReceiveMethod, m);

View File

@ -176,8 +176,6 @@
(type unwindResult avian/Continuations$UnwindResult)
(type callbackReceiver avian/CallbackReceiver)
(type string java/lang/String
(alias data object value)
(alias length uint32_t count)

View File

@ -1,10 +1,9 @@
package extra;
import static avian.Continuations.shift;
import static avian.Continuations.reset;
import avian.FunctionReceiver;
import avian.Function;
import avian.Continuations;
import java.util.concurrent.Callable;
@ -14,10 +13,11 @@ public class ComposableContinuations {
}
public static void main(String[] args) throws Exception {
expect(2 * reset(new Callable<Integer>() {
expect(2 * Continuations.<Integer,Integer>reset(new Callable<Integer>() {
public Integer call() throws Exception {
return 1 + shift(new FunctionReceiver<Integer>() {
public Integer receive(Function<Integer> continuation)
return 1 + shift
(new Function<Function<Integer,Integer>,Integer>() {
public Integer call(Function<Integer,Integer> continuation)
throws Exception
{
return continuation.call(5);
@ -26,10 +26,11 @@ public class ComposableContinuations {
}
}) == 12);
expect(1 + reset(new Callable<Integer>() {
expect(1 + Continuations.<Integer,Integer>reset(new Callable<Integer>() {
public Integer call() throws Exception {
return 2 * shift(new FunctionReceiver<Integer>() {
public Integer receive(Function<Integer> continuation)
return 2 * shift
(new Function<Function<Integer,Integer>,Integer>() {
public Integer call(Function<Integer,Integer> continuation)
throws Exception
{
return continuation.call(continuation.call(4));
@ -38,29 +39,53 @@ public class ComposableContinuations {
}
}) == 17);
expect(equal(reset(new Callable<Cell<Integer>>() {
public Cell<Integer> call() throws Exception {
shift(new FunctionReceiver<Cell<Integer>>() {
public Cell<Integer> receive
(Function<Cell<Integer>> continuation)
expect
(equal
(Continuations.<Cell<Integer>,Cell<Integer>>reset
(new Callable<Cell<Integer>>() {
public Cell<Integer> call() throws Exception {
shift(new Function<Function<Cell<Integer>,Cell<Integer>>,
Cell<Integer>>()
{
public Cell<Integer> call
(Function<Cell<Integer>,Cell<Integer>> continuation)
throws Exception
{
return cons(1, continuation.call(null));
}
});
shift(new Function<Function<Cell<Integer>,Cell<Integer>>,
Cell<Integer>>()
{
public Cell<Integer> call
(Function<Cell<Integer>,Cell<Integer>> continuation)
throws Exception
{
return cons(2, continuation.call(null));
}
});
return null;
}
}), cons(1, cons(2, null))));
expect
(equal
(Continuations.<String,Integer>reset
(new Callable<String>() {
public String call() throws Exception {
return new String
(shift(new Function<Function<byte[],String>,Integer>() {
public Integer call(Function<byte[],String> continuation)
throws Exception
{
return cons(1, continuation.call(null));
return Integer.parseInt
(continuation.call(new byte[] { 0x34, 0x32 }));
}
});
shift(new FunctionReceiver<Cell<Integer>>() {
public Cell<Integer> receive
(Function<Cell<Integer>> continuation)
throws Exception
{
return cons(2, continuation.call(null));
}
});
return null;
}
}), cons(1, cons(2, null))));
}), "UTF-8");
}
}), 42));
}
private static <T> boolean equal(T a, T b) {

View File

@ -2,7 +2,7 @@ package extra;
import static avian.Continuations.callWithCurrentContinuation;
import avian.CallbackReceiver;
import avian.Function;
import avian.Callback;
public class Continuations {
@ -11,22 +11,26 @@ public class Continuations {
}
public static void main(String[] args) throws Exception {
expect(callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation) {
continuation.handleResult(42);
throw new AssertionError();
}
}) == 42);
expect
(callWithCurrentContinuation
(new Function<Callback<Integer>,Integer>() {
public Integer call(Callback<Integer> continuation) {
continuation.handleResult(42);
throw new AssertionError();
}
}) == 42);
expect(callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation) {
return 43;
}
}) == 43);
expect
(callWithCurrentContinuation
(new Function<Callback<Integer>,Integer>() {
public Integer call(Callback<Integer> continuation) {
return 43;
}
}) == 43);
try {
callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation) {
callWithCurrentContinuation(new Function<Callback<Integer>,Integer>() {
public Integer call(Callback<Integer> continuation) {
continuation.handleException(new MyException());
throw new AssertionError();
}
@ -37,8 +41,8 @@ public class Continuations {
}
try {
callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(Callback<Integer> continuation)
callWithCurrentContinuation(new Function<Callback<Integer>,Integer>() {
public Integer call(Callback<Integer> continuation)
throws MyException
{
throw new MyException();

View File

@ -2,7 +2,7 @@ package extra;
import static avian.Continuations.callWithCurrentContinuation;
import avian.CallbackReceiver;
import avian.Function;
import avian.Callback;
public class Coroutines {
@ -40,8 +40,8 @@ public class Coroutines {
final Consumer<Character> consumer = new Consumer<Character>() {
public void consume(final Character c) throws Exception {
callWithCurrentContinuation(new CallbackReceiver() {
public Object receive(Callback continuation) {
callWithCurrentContinuation(new Function<Callback<Object>,Object>() {
public Object call(Callback continuation) {
state.produceNext = continuation;
state.consumeNext.handleResult(c);
@ -53,9 +53,9 @@ public class Coroutines {
};
final Producer<Character> producer = new Producer<Character>() {
final CallbackReceiver<Character> receiver
= new CallbackReceiver<Character>() {
public Character receive(Callback<Character> continuation)
final Function<Callback<Character>,Character> receiver
= new Function<Callback<Character>,Character>() {
public Character call(Callback<Character> continuation)
throws Exception
{
state.consumeNext = continuation;

View File

@ -3,7 +3,7 @@ package extra;
import static avian.Continuations.callWithCurrentContinuation;
import static avian.Continuations.dynamicWind;
import avian.CallbackReceiver;
import avian.Function;
import avian.Callback;
import java.util.concurrent.Callable;
@ -86,24 +86,27 @@ public class DynamicWind {
});
}
private void continuationUnwindTest(final CallbackReceiver<Integer> receiver)
private void continuationUnwindTest
(final Function<Callback<Integer>,Integer> receiver)
throws Exception
{
System.out.println("continuationUnwindTest enter");
try {
expect(callWithCurrentContinuation(new CallbackReceiver<Integer>() {
public Integer receive(final Callback<Integer> continuation)
throws Exception
{
unwindTest(new Callable<Integer>() {
public Integer call() throws Exception {
return receiver.receive(continuation);
}
});
throw new AssertionError();
}
}) == 42);
expect
(callWithCurrentContinuation
(new Function<Callback<Integer>,Integer>() {
public Integer call(final Callback<Integer> continuation)
throws Exception
{
unwindTest(new Callable<Integer>() {
public Integer call() throws Exception {
return receiver.call(continuation);
}
});
throw new AssertionError();
}
}) == 42);
} catch (MyException e) {
e.printStackTrace();
}
@ -118,8 +121,8 @@ public class DynamicWind {
}
private void continuationResultUnwind() throws Exception {
continuationUnwindTest(new CallbackReceiver<Integer>() {
public Integer receive(final Callback<Integer> continuation) {
continuationUnwindTest(new Function<Callback<Integer>,Integer>() {
public Integer call(final Callback<Integer> continuation) {
continuation.handleResult(42);
throw new AssertionError();
}
@ -127,8 +130,8 @@ public class DynamicWind {
}
private void continuationExceptionUnwind() throws Exception {
continuationUnwindTest(new CallbackReceiver<Integer>() {
public Integer receive(final Callback<Integer> continuation) {
continuationUnwindTest(new Function<Callback<Integer>,Integer>() {
public Integer call(final Callback<Integer> continuation) {
continuation.handleException(new MyException());
throw new AssertionError();
}
@ -163,8 +166,8 @@ public class DynamicWind {
task = 1;
return callWithCurrentContinuation
(new CallbackReceiver<Integer>() {
public Integer receive(final Callback<Integer> continuation)
(new Function<Callback<Integer>,Integer>() {
public Integer call(final Callback<Integer> continuation)
throws Exception
{
continuationReference = continuation;