Nice TWiki > Dev > StdLib? > FlagInterfaces (r1.3) TWiki webs:
Dev | Doc | Main | TWiki | Sandbox
Dev . { Changes | Index | Search | Go }
This page shows the concept of FlagInterfaces to solve the typesafety problem of the collections api. Note: this is an immature proposal and the syntax will change problably.

A flag interface is an interface with some restrictions it can not have methods and is not an independant type. It can only be used to refine the type of a normal interface or class.


Here a selection of the declarations in the collections api enhanced with FlagInterfaces:
flag CollectionAcces Immutable;
flag Replacable extends Immutable;
flag Reducable extends Immutable;
flag Appendable extends Immutable;
flag Mutable extends Replacable, Reducable, Appendable;

interface Collection@Mutable<E> has CollectionAcces{}
interface List@Mutable<E> extends Collection<E> {}
interface Iterator@Mutable<E> has CollectionAcces {}
interface ListIterator@Mutable<E> extend Iterator<E> {}

<E> boolean contains(Collection@Immutable<E>, E);
<E> int size(Collection@Immutable<E>);
<E> boolean remove(Collection@Reducable<E>, E);
<E> boolean add(Collection@Appendable<E>, E);
<E, CollectionAcces T> Iterator@T<E> iterator(Collection@T<E>);

<E> E get(List@Immutable<E>, int);
<E> E set(List@Replacable<E>, int, E);
<E> E removeAt(List@Reducable<E>, int);
<E> void add(List@Appendable<E>, int, E);
<E, CollectionAcces T> ListIterator@T<E> listIterator(List@T<E>);

class Vector@Mutable<E> implements List<E>{}
class Array@Replacable<E> implements List<E>{}

public void main(String[] args) {
List<String> mylist = new Vector(); //convenience we take the default CollectionAccess type of List here
// List@Mutable<String> mylist = new Vector(); //so this line is the same
mylist.add("abc");
Collection@Immutable<String> coll = mylist; //coll is a immutable view of mylist
coll.remove("abc");//error not allowed
Collection@Appendable<String> c = coll;// error not allowed
}

The same code after removing the syntatic sugar:

interface Immutable{}
interface Replacable extends Immutable{}
interface Reducable extends Immutable{}
interface Appendable extends Immutable{}
interface Mutable extends Replacable, Reducable, Appendable{}

// Do you mean ...<E, +T | ...> (the + for covariant commes first).
interface Collection<E, T+ | Mutable <: T>{}
interface List<E, T+ | Mutable <: T> extends Collection<E,T> {}
interface Iterator<E, T+ | Mutable <: T>{}
interface ListIterator<E, T+ | Mutable <: T> extend Iterator<E,T> {}

<E> boolean contains(Collection<E,Immutable>, E);
<E> int size(Collection<E,Immutable>);
<E> boolean remove(Collection<E,Reducable>, E);
<E> boolean add(Collection<E,Appendable>, E);
<E, T> Iterator<E,T> iterator(Collection<E,T>);

<E> E get(List<E,Immutable>, int);
<E> E set(List<E,Replacable>, int, E);
<E> E removeAt(List<E,Reducable>, int);
<E> void add(List<E,Appendable>, int, E);
<E, T> ListIterator<E,T> listIterator(List<E,T>);

class Vector<E, T+ | Mutable <: T> implements List<E,T>{}
class Array<E, T+ | Replacable <: T> implements List<E,T>{}

public void main(String[] args) {
List<String,Mutable> mylist = new Vector();
mylist.add("abc");
Collection<String,Immutable> coll = mylist; //coll is a immutable view of mylist
coll.remove("abc");//error not allowed
Collection<String,Appendable> c = coll;// error not allowed
}

An experiment as proof of concept of the way of typing, the commented lines are type errors: package test;
interface I{}
interface J extends I{}
interface K extends J{}

class X<+T | K <: T>{}
class Y<+T | J <: T> extends X<T>{}
void foo(X<I>) = println("foo");
void bar(X<J>) = println("bar");

public void main(String[] args) {
X<K> x = new X();
X<J> y = x;
X<I> z = x;
Y<J> a = new Y();
Y<I> b = a;
//Y<K> c = a;
X<I> d = a;
X<J> e = a;
//X<K> f = a;
a.foo();
a.bar();
b.foo();
//b.bar();
d.foo();
//d.bar();
e.foo();
e.bar();
}

-- ArjanB - 26 Apr 2003


The problem with lazylists can be solved by an additional FlagInterfaces.
interface Sizeless {}
interface Immutable extends Sizeless{}                                        
interface Replacable extends Immutable{}
.... // rest of the interfaces

<E> boolean isEmpty(List<E,Sizeless>); //isEmpty is possible on lazylist
<E> int size(List<E,Immutable>);  // but size is not

class LazyVector<E, T | Sizeless <: T> implements List<E,T>{}

An advantage of using type parameters to restrict methods is that only a few interface need to added. I think this can be used without since the existing collections api. Only retypings will be needed.

The sentence doesn't make sense: ... without since ...

An important part of this proposal is the default type parameter of each collection interfaces and classes. This improves the ease of use. Only when writing new methods or using a more restrictive view of the collection class, is additional typing needed.

Daniel does the way of typing make sense?

-- ArjanB

Interesting. I would have to think more in details. It seems like it could work. Have you seen my comments on the JINX page? There I mention & types, and how they can be syntaxtic sugar for constrained types. It would be interesting to compare the two.

One issue is whether we need to be able to dispatch on "flags", or is this just to give types to existing methods. I think if we don't modify (wrap) the collection API, we cannot dispatch on, say, Immutable. Or maybe it would be the same as the list of classes that implement it?

We cannot dispatch on type parameters. With & types, when you declare your own hierarchy, you could really create the interfaces, so you could dispatch.

I think with both proposals, we would have a similar API.

-- DanielBonniot

Topic FlagInterfaces . { Edit | Attach | Ref-By | Printable | Diffs | r1.7 | > | r1.6 | > | r1.5 | More }
Revision r1.3 - 27 Apr 2003 - 21:56 GMT - DanielBonniot
Parents: StdLib?
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.