[e-lang] using @inert with collection APIs

Tyler Close tyler.close at gmail.com
Wed Sep 24 15:45:16 CDT 2008


In working on the @inert auditor, I've come across some new
requirements for the APIs for collections. I'm not overjoyed with the
solutions I've been able to come up with, so I thought e-lang members
might be able to do better.

Consider an algorithm like:

/**
 * A const map of keys to values.
 */
interface ConstMap<T> {
    @inert T getValue(String key);
    ...
}

/**
 * Creates a list of some of the values in a map.
 */
static ConstArray<SomeMutable>
listValues(@inert ConstMap<SomeMutable> allValues,
               @inert ConstArray<String> someKeys);

The implementation of listValues() needs to extract some of the values
in the given map and create a ConstArray of them.

As a refresher, when you've got an @inert reference to an object,
    - you can only access its Immutable state
    - any return value from an operation that takes an @inert argument
MUST be held in an @inert variable

So, listValues() could be implemented as:

/**
 * This method guarantees it will not mutate any of the objects held
in the provided map.
 */
static ConstArray<SomeMutable>
listValues(@inert ConstMap<SomeMutable> allValues,
               @inert ConstArray<String> someKeys) {
    @inert ConstArray<SomeMutable> r = ConstArray.array();
    for (int i = someKeys.length(); i-- > 0;) {
        r = r.with(allValues.getValue(someKeys.get(i)));    // assumes
ConstArray.with(@inert Object x)
    }
    return r;
}

There are 2 issues with this implementation:

1. We were unable to use the standard iteration API, since it uses a
mutable iterator object. So the following code would generate a
verifier error:

    Iterator<SomeMutable> i = someKeys.iterator();    // cannot hold
return value in non- at inert variable

and so would:

    @inert Iterator<SomeMutable> i = someKeys.iterator();
    i.next();    // cannot call non- at inert method on @inert reference.

2. We were unable to use the ArrayBuilder API. Again the following
code would generate a verifier error:

    ConstArray.Builder builder = ConstArray.builder(someKeys.length());
    builder.append(someKeys.get(1));    // can't pass @inert reference
to non- at inert parameter

The declaration of append() cannot be: ArrayBuilder.append(@inert
object), since the implementation needs to store the received
reference.

I don't see how to make use of either the java.lang.Iterable or
org.joe_e.array.ArrayBuilder interfaces with the @inert auditor.
Anyone see a way to fix this?

If not, this also means we need to make the ConstArray.with()
implementation efficient enough for this task. If we do so, we might
as well deprecate the ArrayBuilder interface.

The toy example used in this email reproduces similar issues that
arise in the more realistic, but more complicated, JSON
deserialization code.

Thoughts?
--Tyler


More information about the e-lang mailing list