Software Design/Avoid a variable called "result"
Checklist questions:
- The variable returned from a function has a more meaningful name than just
result
(res
,retVal
,toReturn
, etc.)? - Is it possible to return early from a function instead of creating a "result" variable?
Why
editCalling a variable result
is equivalent to not calling a variable at all because "result" doesn't bear any meaning. The benefits of semantic variable naming are forgone.
When reading through the function down to the final statement like return result
, people have to remember what type of value the function should return instead of just seeing that. The function's name may not embed the full information about the returned type: for example, a function getDiscountPlatinumLoyalityForAccessories(): Double
doesn't encode in its name whether the returned discount is a percent or a value between 0 and 1 because the name is already very long. In this case, a reader should consult the function's documentation every time they want to recall what type of value the function should return. If the documentation doesn't specify that or is absent, this semantic information is completely lost in the code. Thus, a return variable called result
contributes to cognitive load. The code is less obvious and makes readers navigate more.
When the result variable has a semantic name it may also reduce the probability of making a mistake in the function, for example, by assigning a value in the wrong units to the variable. Consider this function:
// A function with a bug
fun getDiscountPlatinumLoyalityForAccessories(): Double {
var result = Loyality.PLATINUM.discountPercent
if (christmasDiscountSeason) {
result += CHRISTMAS_DISCOUNT_DECIMAL
}
if (specialDiscountsForAccessories) {
result += SPECIAL_ACCESSORIES_DISCOUNT_DECIMAL
}
return min(result, MAX_DISCOUNT_DECIMAL)
}
It would be easier to spot the bug in this function if the variable was called discountDecimal
and the first line was
var discountDecimal = Loyality.PLATINUM.discountPercent
Why not
editWhen a function is short, or when the result type doesn't have units, semantic naming of the result variable makes little or no difference. On the other hand, in the presence of a variable called result
, it's harder to make a mistake by accidentally returning another variable from the function, especially if calling variables to be returned from functions result
is a convention which is followed consistently in the codebase. See practice Call function's return variable "result".
Combining the approaches
editA compromise solution is to call functions' result variables resultSemanticName
, for example, resultDiscountDecimal
in getDiscountPlatinumLoyalityForAccessories()
function above.
Removing a result variable altogether
editSometimes, a result
variable can be eliminated by returning early from a function. Consider this function:
fun remove(list: MyList, elemToRemove: Elem): Boolean {
var result = false
var iterElem: Elem? = list.first()
while (iterElem != null) {
if (iterElem == elemToRemove) {
iterElem.remove()
result = true
break;
}
iterElem = iterElem.next()
}
return result
}
It doesn't make much difference whether the result variable is called result
or removed
here. However, the variable can be eliminated altogether to make the function shorter and simpler:[1]
fun remove(list: MyList, elemToRemove: Elem): Boolean {
var iterElem: Elem? = list.first()
while (iterElem != null) {
if (iterElem == elemToRemove) {
iterElem.remove()
return true
}
iterElem = iterElem.next()
}
return false
}
A result
variable is often a sign that such simplication is possible.
Static enforcement
editCheckstyle (Java)
editLocalVariableName and LocalFinalVariableName modules:
<module name="LocalVariableName">
<property name="format" value="(?i)^(?!result$|retValue$|retVal$|ret$|res$|r$).*"/>
</module>
<module name="LocalFinalVariableName">
<property name="format" value="(?i)^(?!result$|retValue$|retVal$|ret$|res$|r$).*"/>
</module>
Related practices
editReferences
edit- ↑ Boswell, Dustin; Foucher, Trevor (2011). The Art of Readable Code. ISBN 978-0596802295. Chapter 9, section "Eliminating Intermediate Results"