|
ref_send API 1.16 defensive programming in Java |
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | |||||||||
See:
Description
| Interface Summary | |
|---|---|
| Promise<T> | A promise for a referent. |
| Volatile<T> | A promise of unknown origin. |
| Class Summary | |
|---|---|
| Fulfilled<T> | A promise that alleges to be fulfilled. |
| Inline<T> | A fulfilled promise that should not use persistent object faulting. |
| Rejected<T> | A rejected promise. |
| Exception Summary | |
|---|---|
| Infinity | Signals an infinity. |
| NaN | Signals a NaN. |
| NegativeInfinity | Signals a negative infinity. |
| PositiveInfinity | Signals a positive infinity. |
A promise interface.
The ref_send API provides a language for expressing eventual control flow, where operations are only scheduled to happen later, instead of being executed immediately, as is the case with the normal flow of control in Java. To support eventual control flow, the ref_send API uses a different kind of reference, called a promise. A promise is a reference to an object which has yet to be determined. It's this flexibility that enables coding of an algorithm that manipulates values which won't be calculated until later, as is done in eventual control flow.
One way to think about promises is as a generalization of floating point
numbers. Floating point arithmetic has a special way of dealing with error
conditions, different from that used in integer arithmetic. For example, the
expression "0 / 0" will throw an
ArithmeticException, which aborts the current flow of
control. In contrast, the expression "0.0 / 0.0" does not throw
an exception, instead returning a special value called a NaN and
allowing the current flow of control to continue.
Like a floating point number, a promise can represent either a normal
value or an error condition. A Fulfilled promise
is a wrapper containing a normal Java reference. A
Rejected promise is a wrapper containing an
Exception specifying the details of the error condition.
Instead of throwing an exception, thus terminating the current flow of
control, an expression that returns a Promise
can return a Rejected promise to indicate an
error condition, or a Fulfilled promise for a
normal result. Most often, an expression will only need to be coded to return
a Fulfilled promise, so some syntactic sugar is
provided to facilitate construction. For example:
import static org.ref_send.promise.Fulfilled.ref;
…
private int balance;
…
public Promise<Integer>
getBalance() { return ref(balance); }
…
The static ref() function takes
a normal Java reference and returns a corresponding
Promise.
Constructing a Rejected promise is a little
more verbose. For example:
import static org.ref_send.promise.Fulfilled.ref;
…
private int balance;
…
public Promise<Integer>
getBalance() {
if (balance < 0) {
return new Rejected<Integer>(new Overdraft());
}
return ref(balance);
}
…
In floating point arithmetic, the NaN value is contagious,
meaning that any other expression that uses it also returns NaN.
For example, the expression "0.0 / 0.0 + 1.0" also returns
NaN. An algorithm that uses floating point numbers can thus be
coded such that it always runs to completion and the error condition is
propagated through to the return value. A
Rejected promise can be used in a similar way by
turning it into a proxy, which
can then be used like any other object implementing the specified interface.
For example:
public interface
Account {
public Promise<Integer>
getBalance();
}
public class
Customer {
…
public Account
getSavings() {
if (frozen) {
return new Rejected<Account>(new Frozen())._(Account.class);
}
return savings;
}
}
…
final Customer client = …
final Promise<Integer> current = client.getSavings().getBalance();
…
In the above code, the current balance will be a
Rejected promise, with
reason Frozen,
if the customer's savings account has been frozen by the bank. The
Rejected promise was originally produced by the
getSavings() method, but propagated through the
getBalance() invocation to the current balance.
In addition to representing a normal or error condition, a promise is most
useful for representing a value which is yet to be determined. Such a promise
may be used to refer to a value which will be calculated later, based on
inputs which are not yet known. The
Eventual class supports creating this
kind of
deferred promise,
as well as doing
conditional
operations on promises.
|
ref_send API 1.16 defensive programming in Java |
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | |||||||||
Copyright 1998-2007 Waterken Inc. under the terms of the MIT X license.