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.