I would like to propose a new language construction for block level checks, which can be useful im many situations One application can be error handling, but the construction is not limited to this only
The new keyword will be in the form:
until [condition] { check expression } else { expressions }
Where
-
check is optionnal - if not specified, confition will not be evaluated; This has some drawbacks, as leaves responsibility to developer, but will not degrade performance with unnecessary evalutioans of condition;
On first check, where condition evaluate to false, the execution will continue with the first expression after the block
-
else is optional (as with if construction) - if not specified, the execution will continue with the first expression after the block;
The construction is similar to try-catch construction in other languages, but it's not limited to error handling only.
- More dense code
- Code flow is easy to understand (no bouncing between handlers)
- Construction is generic enough to be used for all kinds of checks
- Constructions can be nested is nested ifs (IMHO this is bad design)
- Additional level of nesting (more brackets...)
- As check is optional, developer may forget to put it in a line, where required; Compiler may issue a error for lines, where variable, used in expression, is referensed (either as assignement or passsed as value) and no check keyword
- For complex conditions, including several variables, all of them will be checked (even one of them is referensed in current line)
this is roughly equivalent to the following construction:
var v Variable
var check := func(){if !(condition_with_v) {goto ELSE} }
{
v = expression_changes; check();
goto END_BLOCK
ELSE:
// expressions_in_else_block
END_BLOCK: //
}
The condition will not be evaluated in declaration, but will be inserted after any expression with check keyword The else clause is optional and will be executed if condition evaluate to false - the code path will go to else block
This allow avoid repetitive if{} statements in the code for group of commands and improve readbility
Error handling can be expressed like this:
var err error
until err == nil {
check value,err := someFunc() // condition is evaluated
someFunc2(val) // condition is not evaluated
check item,err := value.GetItem(x) // condition is evaluated
} else {
//handle error or ok (we can use **switch** construction here to check which part of condition is causing block interruption)
}
For more complex cases, the construction can be used with arbitrary checks that are evaluated to boolean Suppose we have settings structure with Valid() method, which performs various checks based on combination of settings
until s := &Settings{}; s.Valid(){
check s.SetParam1(x)
check s.SetParam2(y)
} else {
return errors.New("Settings are not valid",s)
}
See also
proposal: Go 2: add syntax to repeat a Condition check for different StatementLists
proposal: Go 2: add collect statements to the language