Less as a real argument than as devil's advocate, here's a shorter non-library version:
function f1(s) {
try {
let data = JSON.parse(s);
let x = parseFloat(data.a.b.c.substr(0));
if (x === x)
return x;
} catch(e) {}
return null;
}
...ok, it's a bit golfy, and in JavaScript you don't get much control over exception catching. But in general, exceptions can be used like an implicit Maybe/Either monad, just as mutability is an implicit IO monad.
(Also, you picked an odd task - it's unusual to expect a float to be represented as a string in a JSON object, and a check that rejects NaN but accepts weird floats like Infinity is not terribly useful.)
Your counterexample is informative. I hadn't thought of exceptions in this way. The downside of putting everything in a `try` block, of course, is that we'll potentially catch exceptions arising from a bug in our code which should crash our program.
(Also, you picked an odd task - it's unusual to expect a float to be represented as a string in a JSON object, and a check that rejects NaN but accepts weird floats like Infinity is not terribly useful.)