20 March 2009

Glue classes proposal 0.9

OVERVIEW

FEATURE SUMMARY:

Glue classes allow to link utils direct with objects.

MAJOR ADVANTAGE:

Forgotten functionality can be not such big deal now.

MAJOR BENEFIT(s):

  • New functions can be easy localized (critically important while introduce new peoples into project).
  • Security: glue class do not see anything protected.
  • Light binding new functions with existing classes.
  • Number of used classes reduction.
  • Allow to assign methods and functions(static methods) to arrays, classes, interfaces, …
  • It's proof against same method occurs in class and delegator as well like in two delegators.
  • Allow to link gained(.jar) logic with new one, witch is impossible before final developer implements his classes.
  • Allow to project compact interfaces and do not worry about additional logic.

MAJOR DISADVANTAGE:
Do not know any ;) sorry.

ALTERNATIVES:
Utils classes, more work on project, duplicated code...

EXAMPLES

SIMPLE EXAMPLE:

Now time:
public class base {

  public static <T> T[] flatten(T[][] this) {
    int length = 0;
    for (T[] subArray : this) {
      length += subArray.length;
    }
    T[] ret = (T[]) Array.newInstance(this.getClass().getComponentType().getComponentType(), length);
    int pos = 0;
    for (T[] subArray : this) {
      System.arraycopy(subArray, 0, ret, pos, subArray.length);
      pos += subArray.length;
    }
    return ret;
  }

}
Now time(usage):
  public static void main(String[] args) {
    Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { 9, 0 } };
    System.out.println(Arrays.toString(base.flatten(array)));
  }

Glue:
public class base<T> glue( T[][] ) {

  public glue T[] flatten( this) {
    int length = 0;
    for (T[] subArray : this) {
      length += subArray.length;
    }
    T[] ret = (T[]) Array.newInstance(this.getClass().getComponentType().getComponentType(), length);
    int pos = 0;
    for (T[] subArray : this) {
      System.arraycopy(subArray, 0, ret, pos, subArray.length);
      pos += subArray.length;
    }
    return ret;
  }

}
Glue(usage):
  public static void main(String[] args) {
    Integer[][] array = new Integer[][] { { 1, 2, 3, 4 }, { 5, 6, 7 }, {}, { 9, 0 } };
    System.out.println(array..flatten()..toString());
  }

ADVANCED EXAMPLE:

Now time:
public class base {

  public static <T> int addAll( ArrayList<T> this, Iterator<? extends T> iterator) {
    int added = 0;
    while (iterator.hasNext()) {
      added += this.add(iterator.next()) ? 1 : 0;
    }
    return added;
  }

  public static <T, E extends T> int addAll(ArrayList<T> this, E[] elements) {
    int added = 0;
    for (T t : elements) {
      added += this.add(t) ? 1 : 0;
    }
    return added;
  }

}
Now time(usage):
  public static void main(String[] args) {
    Integer[] add = new Integer[] { 1, 2, 34, 2, 5, };
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    ArrayList<Integer> finall = new ArrayList<Integer>();
    
    base.addAll(arrayList, add);
    base.addAll(finall, add);
    base.addAll(finall,arrayList.iterator());
    
    System.out.println(finall);
  }

Glue:
public class base<T> glue( ArrayList<T> ){

  public glue int addAll( this, Iterator<? extends T> iterator) {
    int added = 0;
    while (iterator.hasNext()) {
      added += this.add(iterator.next()) ? 1 : 0;
    }
    return added;
  }

  public glue <E extends T> int addAll( this, E[] elements) {
    int added = 0;
    for (T t : elements) {
      added += this.add(t) ? 1 : 0;
    }
    return added;
  }

}
Glue(usage):
  public static void main(String[] args) {
    Integer[] add = new Integer[] { 1, 2, 34, 2, 5, };
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    ArrayList<Integer> finall = new ArrayList<Integer>();

    arrayList..addAll(add);
    finall..addAll(add);
    finall..addAll(arrayList.iterator());

    System.out.println(finall);
  }

Glue second:
public class base glue( Date )
{
  private static final SimpleDateFormat  sdf  = new SimpleDateFormat("yyyy.MM.dd");

  public glue String format( this ) {
    synchronized (sdf) {
      return sdf.format(this);
    }
  }

  private static final Date  applicationStart  = new Date();

  public static glue Date applicationStart() {
    return applicationStart;
  }
}
Glue second(usage):
  public static void main(String[] args) {
    System.out.println(Date..applicationStart()..format());
  }
DETAILS

SPECIFICATION:
JLS 8.8:
ClassDeclaration:
  NormalClassDeclaration
  GlueClassDeclaration
  EnumDeclaration

GlueClassDeclaration
  ClassModifiersopt class Identifier TypeParametersopt glue ( GlueFormalParameter ) GlueClassBody

GlueFormalParameter
  VariableModifiers Type

GlueClassBody:
  { GlueClassBodyDeclarationsopt }

GlueClassBodyDeclarations:
  GlueClassBodyDeclaration
  GlueClassBodyDeclarations GlueClassBodyDeclaration

GlueClassBodyDeclaration:
  GlueClassMemberDeclaration
  StaticInitializer

GlueClassMemberDeclaration:
  FieldDeclaration
  StaticMethodDeclaration
  GlueMethodDeclaration
  StaticClassDeclaration
  InterfaceDeclaration
  ;

GlueMethodDeclaration:
  GlueMethodHeader MethodBody

GlueMethodHeader:
  MethodModifiersopt glue TypeParameters*opt ResultType GlueMethodDeclarator Throwsopt

GlueMethodDeclarator:
  Identifier ( this,*opt FormalParameterListopt )

*opt: 'this' occurs always and only if glue method is not static.

TypeParameters from GlueClassDeclaration are always visible for TypeParameters in GlueMethodHeader (even if method is static).


15.12 Method Invocation Expressions:
GlueMethodInvocation:
  Primary .. TypeNameopt NonWildTypeArguments*opt Identifier ( ArgumentListopt )
  super .. TypeNameopt NonWildTypeArguments*opt Identifier ( ArgumentListopt )
  ClassName . super .. TypeNameopt NonWildTypeArguments*opt Identifier ( ArgumentListopt )
  TypeName .. TypeNameopt NonWildTypeArguments* Identifier ( ArgumentListopt )

NonWildTypeArguments* suit TypeParameters in GlueMethodHeader.

COMPILATION:

  • If object (except null) is valid for GlueFormalParameter then glue-method can be called for this object.
  • If type is compatible with GlueFormalParameter then static glue-method can be called for this type.
  • For non static methods glued-object is passed as first 'this' parameter.
  • Compiled method signature contains TypeParameters from GlueClassDeclaration (at start), and it's always static.

TESTING:
Like simple static methods.

LIBRARY SUPPORT:
No.

REFLECTIVE APIS:
No.

OTHER CHANGES:
No.

MIGRATION:
None.

COMPATIBILITY

New jars are fully compatible. Code is only backward compatible.

REFERENCES

Glue classes proposal beta
Glue classes proposal 0.9
Extension of 'Interface' definition to include class (static) methods

0 comments / komentarz(y):

Post a Comment