Nice TWiki > Dev > StdLib? > FlagInterfaces (r1.2) 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
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{}

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();
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;;;;

-- 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.

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

Topic FlagInterfaces . { Edit | Attach | Ref-By | Printable | Diffs | r1.7 | > | r1.6 | > | r1.5 | More }
Revision r1.2 - 27 Apr 2003 - 13:49 GMT - ArjanB
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.