ref_send API 1.16
defensive programming in Java

Package org.ref_send.promise

A promise interface.

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.
 

Package org.ref_send.promise Description

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

Submit a bug or feature, or get help

Copyright 1998-2007 Waterken Inc. under the terms of the MIT X license.