A wrinkle in Java's do-while

Posted by    |       Ceylon

Today I tried to write (approximately) this code in Java:

//Java
Scope scope = declaration.getContainer();
do {
    if (scope.getDirectMemberOrParameter(model.getName())!=null) {
        node.addError("duplicate declaration name: " + declaration.getName());
    }
    boolean isControlBlock = scope instanceof ControlBlock;
    scope = scope.getContainer();
}
while (isControlBlock);  //compile error

This didn't work, since Java doesn't consider the while condition expression to belong to the do block. I think this is wrong. Surely the loop should be allowed to compute it's own termination condition? I realize that do/while is a fairly uncommon construct, but when it is used, I imagine it's pretty common that it would be used like this.

The only reasonable way to fix the above code is to move the declaration of isControlBlock outside the loop:

//Java
boolean isControlBlock;
Scope scope = declaration.getContainer();
do {
    if (scope.getDirectMemberOrParameter(model.getName())!=null) {
        node.addError("duplicate declaration name: " + declaration.getName());
    }
    isControlBlock = scope instanceof ControlBlock;
    scope = scope.getContainer();
}
while (isControlBlock);

Note that isControlBlock is now a variable. I would not be able to declare it final.

The Ceylon type analyzer accepts the equivalent code:

//Ceylon
variable local scope = declaration.container;
do {
    if (scope.directMemberOrParameter(model.name) exists) {
        node.addError("duplicate declaration name: " + declaration.name);
    }
    local isControlBlock = scope is ControlBlock;
    scope = scope.container;
}
while (isControlBlock);

I'm going to clarify that this is allowed in the language specification.


Back to top