using @inert with collection APIs

"Tyler Close" <[email protected]>
Newsgroups gmane.comp.lang.e.general
Message-ID <[email protected]>
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-@inert variable

and so would:

    @inert Iterator<SomeMutable> i = someKeys.iterator();
    i.next();    // cannot call non-@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-@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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.