result
return [language.result]
Avoid using result
for returning values.
Use expression-based return or explicit return
keyword with a value
Pros
- Recommended by NEP-1
- Used in standard library
- Saves a line of code avoiding an explicit
var
declaration - Accumulation-style functions that gradually build up a return value gain consistency
Cons
- No visual (or compiler) help when a branch is missing a value, or overwrites a previous value
- Disables compiler diagnostics for code branches that forget to set result
- Risk of using partially initialized instances due to
result
being default-initialized- For
ref
types,result
starts out asnil
which accidentally might be returned - Helpers may accidentally use
result
before it was fully initialized - Async/await using result prematurely due to out-of-order execution
- For
- Partially initialized instances lead to exception-unsafe code where resource leaks happen
- RVO causes observable stores in the left-hand side of assignments when exceptions are raised after partially modifying
result
- RVO causes observable stores in the left-hand side of assignments when exceptions are raised after partially modifying
- Confusing to people coming from other languages
- Confusing semantics in templates and macros
Practical notes
Nim has 3 ways to assign a return value to a function: result
, return
and "expressions".
Of the three:
- "expression" returns guarantee that all code branches produce one (and only one) value to be returned
- Used mainly when exit points are balanced and not deeply nested
- Explict
return
with a value make explicit what value is being returned in each branch- Used to avoid deep nesting and early exit, above all when returning early due to errors
result
is used to accumulate / build up return value, allowing it to take on invalid values in the interim
Multiple security issues, nil
reference crashes and wrong-init-order issues have been linked to the use of result
and lack of assignment in branches.
In general, the use of accumulation-style initialization is discouraged unless made necessary by the data type - see Variable initialization