A sentinel value is a value such as -1
or the empty string, that has a special
meaning in the context of a program.
Sentinel values are undesirable because:
It isn't obvious that a type contains a sentinel value, which may result in new code not handling the sentinel value without getting a compiler error or looking obviously wrong.
Mistakes or future changes may result in sentinel values colliding with real values.
A better option is to use an adequate composite type such as a union type.
ā Don't:
/* endDate: the unix time or -1 if there is no end date */
function isDateValid(date:number endDate: number) {
return date < endDate || endDate === -1;
}
The above code is wrong because Unix times can be negative: -1 is both a real date and the sentinel value.
It is also brittle, as the condition could have been implemented as only
date < endDate
without looking obviously wrong or causing a compiler error.
ā Do:
function isDateValid(date: number, endDate: number | null) {
return endDate === null || date < endDate;
}
fn is_date_valid(date:i64, end_date: Option<i64>) -> bool {
match endDate {
Some(x) => date < x,
None => true,
}
}
Even without comments, it is clear that there may or may not be an end date.