[Checkers] Various Notes Part 2: Type System IGJ

Mahmood Ali mahmood at MIT.EDU
Sun Apr 27 16:50:16 EDT 2008

Hi again,

Here is my second part in the two-part series.


1. Support for Arrays is essential
Personally, I was surprised by the usage of arrays in almost all case  
studies I have done yet!


2. I don't like AssignsFields nor any annotation like it (is Raw  
annotation like it?)

Type Qualifiers on method receivers have multiple meanings:
* Documenting the side effect of the method. (e.g. Mutable, ReadOnly  
in IGJ and Javari)
* Restrict the types on which the method can be dispatched (e.g.  
Mutable, ReadOnly, and Interned, etc)

Simply put, the type qualifier provides an documented interface for  
*using* the method.

AssignsFields does not quite do that.  It does not provide an provide  
an interface (for an outside class it is treated as Mutable).  It  
simply means 'constructor can call this method safely', which is an  
implementation detail, and it impacts how the method is implemented  
and how any overrider method can be implemented!

While the programmer can easily deal with the raised issues, the  
solutions are not elegant.

: Lesson learnt: Never annotate an interface method receiver as  
AssignsFields! Be careful with abstract classes!

By tomorrow I will have an estimate how AssignsFields is actually  
impacting the implementation!


3. Projects have different philosophies

In most of the projects, imperative programming style dominated the  
style; but with a few there were some functional style too.  However  
there is no much overlap between them.  In many of the case studies I  
found almost no @Immutable annotation (like JOlden, JavaCrond), while  
others like functor2 (library for functional programming, with lot of  
immutable java.util.Map and functional mappers and reducers) is  
basically all @Immutable references!

Furthermore, most classes I dealt with did not represent datatypes,  
but rather they were "service" classes, like java.io classes,  
connectivity classes, diff creation classes, database classes, etc.

Even some datatype classes are actually service classes.  
java.sql.ResultSet for example, is a datatype to wrap the result  
received from database statement call.  Yet it actually represents a  
live connection to the database with a close().  In a sense you can  
never have an immutable result set, because at any point the creator  
statement closes which would close the result set and then all the  
sudden the values in ResultSet are not there anymore!  Similarly all  
the updator methods are updating the back-end database.

I don't necessary consider this as weakness in the IGJ type system,  
but rather an indication of a bad design!


4. Allowing type argument qualifiers to change covariantly for  
collection is not general.

IGJ allows type qualifiers to change covariantly in type arguments for  
    @Mutable List<@Mutable Date>  <:  @ReadOnly List<@ReadOnly Date>

However, this rule is not constitute a general sound rule.  Consider  
an interface wrapping a unary operation (method with one parameter).   
The interface may be defined as:

interface UnaryOp<Return, Param> {
     * Apply the unary operator to the parameter
     * @return the result of the operation
    public Return apply(Param param);

In this case, @ReadOnly UnaryOp<@Mutable Date> is not a subtype of  
@ReadOnly UnaryOp<@ReadOnly Date>.

I only saw this style of programming in functor2, I haven't tried to  
deal with this quite yet.


5. We might like to consider allowing '@I' be a method receiver

Motivation: visitor and call-back currently cannot really be immutable.

Problem: Currently, I can either annotate visitor method receivers  
with Mutable or ReadOnly.  If I annotate them as Mutable, I cannot  
have an immutable visitor; and I annotate them as ReadOnly I cannot  
have a mutable visitor or I would need to use a lot of hacks using  
Mutable and Assignable fields

Proposed solution:
For documentation purposes, '@I' as method receiver within  
*interfaces*, means that this method may mutate or not depending on  
the immutability of the subclasses; however, it does not say anything  
regarding its invocation-ability (is this a word?)

More information about the checkers mailing list