27 March 2009

'forget' keyword proposal

OVERVIEW

FEATURE SUMMARY:
'forget' keyword allows to erase variable from current context, or it means that field should not be used.

MAJOR ADVANTAGE:
This change makes language be more WYSIWYG.

MAJOR BENEFIT(s):

  • It makes people be able to erase 'variable' from current context, while now it's:
    • impossible for final variables (only by comments),
    • impossible for arguments (for not final Object we can assign null),
    • impossible for fields.
    • local fields need more or 'less' artificial blocks (two lines wasted and one indent level).
  • Declaring that variable should not be used, or does not contain valid information for this scope (at current time) will be possible.
  • Code quality does not fall so drastically after we leave it, comparing to '=null', 'only comments' or 'weird blocks'.

MAJOR DISADVANTAGE:
New keyword == Someone can have declared method/field/variable named 'forget'.

ALTERNATIVES:
It's already listed.

EXAMPLES

SIMPLE / ADVANCED EXAMPLE(s):

  public static void main(final String[] args) {
    System.out.println(Arrays.toString(args));
    forget args; // 'args' cannot be used anymore
    String[] args; // Error: Duplicate local variable args
   ...
  }

public class Forget {

  private ArrayList<String> criticKeys;
  
  public void addKey(String newKey){
    forget this.criticKeys; // use synchronized method ONLY
    ... // validate
    ... // add
  }
  
}

  public static void main(final String[] arguments) {
    int sum = 0;
    for (String s : arguments) {
      sum += Integer.parseInt(s);
      System.out.println(sum);
      forget s; // OK
      forget args; // OK: arguments variable is final
      forget sum; // Error: cannot erase variable it it will still can be used
    }
    System.out.println(arguments.length); // Error: erased context
  }
DETAILS

SPECIFICATION:
   forget VariableIdentifier;
or
   forget this. FieldIdentifier;

Forbid using given identifier in all followed expressions, in all blocks in which variable could be used in current method scope.

If variable is not final then forget expression cannot occurs in loop block if variable was declared in wider block, it's because variable should not be forgotten if it will be used again.

If field is not final than forget expression cannot occurs in any loop block.

COMPILATION:
Variable is not erased (but it can be, if it's not field), it's just protected from access that should not happen for any reason. What's more, handling variable, as if it still exists, prevents a situation when a programmer creates new variable with the same name and then removes forget statement.

TESTING:
It's the same as testing effects of exiting from the block for variables. For fields, it's just an access control.

LIBRARY SUPPORT:
None.

REFLECTIVE APIS:
None.

OTHER CHANGES:
None.

MIGRATION:
None.

COMPATIBILITY

New keyword can be problem. There is not other impact.

REFERENCES

-

2 comments:

  1. Can you please explain with a real life example

    ReplyDelete
  2. @C.Karthik
    Quite simple example can be done using Streams.

    final InputStream is = ...;
    ...
    is.close;
    forget is; // Reason

    public void readContext(final InputStream is){
        ...
        forget is; // Reason
        ...
    }

    Similar effect can be obtained using blocks to prevent further access. Any way, this is not always the solution, or it decrease code readability like when there are few variables and one of them need to be prevent from access, to do not damage data.

    {
    InputStream is = null;
    try{
        is = ...;
        ...
        }
    finally{
        is.close;
        }
    }
    ...


    Mixing final with forget can make you to be sure that the variable contains one and the same object and after all operations will be done, there will be clear specification that it should be not accessed any more.

    When you back to such a code after few months, it can be a great advantage.

    ReplyDelete