Support lazy conditions in `if`-expression
Summary
With the v1.5.0 API of if
-expressions all conditions have to be evaluated before the expression starts to be evaluated. In some scenarios this can be inefficient, e.g. if the n
-th condition is expensive to compute but unlikely because some condition i
, i<n
, commonly holds. Thus, like if
-statements (try running if (true) { console.log('a') } else if (console.log('b') === undefined) { console.log('c') }
if you don't believe me), it should be possible to evaluate conditions lazily.
Proposals
Proposal 1
Provide alternatives to fi
and .elseIf
that must be provided with a function which will be evaluated lazily to obtain the condition value.
This syntax is not final but it illustrates how this could be supported:
const value = lazyIf(() => false)
.then(optionA)
.lazyElseIf(() => true)
.then(optionB)
.else(optionC);
assert.equal(value, optionB);
It should not be required to start with lazyIf
to use lazyElseIf
, i.e. the following should be possible as well:
const value = fi(false)
.then(optionA)
.lazyElseIf(() => true)
.then(optionB)
.else(optionC);
assert.equal(value, optionB);
Proposal 2
If the value provided to fi
or .elseIf
is a function, evaluate the function lazily and use the return value as the condition value:
const value = fi(() => false)
.then(optionA)
.elseIf(() => true)
.then(optionB)
.else(optionC);
assert.equal(value, optionB);
While this is arguably more convenient, it eliminates the possibility of using a value that could be a function from being a condition. This would make it impossible to emulate certain valid if
-statements as if
-expression. For example:
const maybeFn = /* ??? */;
// Works
let value;
if (maybeFn) {
value = maybeFn();
} else {
console.log("Not a function so we can't run it!");
value = 42;
}
// Doesn't work
const value = fi(maybeFn)
.thenDo(() => maybeFn())
.elseDo(() => {
console.log("Not a function so we can't run it!");
return 42;
});