4 ms·
The "Symphony of Functions" example is worth dissecting, since it's a good example of when NOT to use an Option monad. The code computes sqrt(-1 * (log(-1 * (2
by millstone 12y ago
The "Symphony of Functions" example is worth dissecting, since it's a good example of when NOT to use an Option monad.
The code computes sqrt(-1 * (log(-1 * (20 * 2)))^2).
The potentially failing functions are log and sqrt. Failure is determined by checking if the result is a "normal" floating point value. But 'double' and 'square' may also produce non-normal values, e.g. squaring a large float may produce infinity. So why doesn't double() return an Option as well?
Furthermore, checking if a value is normal is not correct. If x slightly exceeds 1, then log x is a small positive value, i.e. a denormal, and therefore log() will incorrectly report failure.
Floating point arithmetic already has a serviceable "Option" type in its non-finite values (NaN and infinities), so the best way to write this code is the naive way:
let result: f64 = sqrt(pow(-1 * (log(-1 * (20 * 2))), 2));
let success: bool = is_finite(result);
The Option monad only makes this code longer, slower, and buggier.
- SamReidHughes 12y ago> If x slightly exceeds 1, then log x is a small positive value, i.e. a denormal, and therefore log() will incorrectly report failure. No it won't, for the neighboring values of 1, which are 1-2^-53 and 1+2^-52, log will return approximately -2^-53 and 2^-52, which are not denormal.
- hoverbear 12y agoIt was a challenge to come up with a good example for the section without utilizing too much of a language that is unfamiliar to most of the readers. I'm debating changing it to a string parsing example. Do you think it would be more appropriate of a use? Or is there a better concept to demonstrate?