I've discovered something a little disturbing about the IFS() function.
The normal IF() function does short-circuit evaluation:
=IF(condition, expression1, expression2)
If condition is true, only expression1 is evaluated; if condition is false, only expression2 is evaluated.
Now, I rewrite this using IFS():
=IFS(condition, expression1, TRUE, expression2)
Regardless of the state of condition, both expression1 and expression2 are evaluated. I discovered this while putting some guard conditions on a recursive LAMBDA() function to prevent runaway evaluation. Even with the guard conditions, Excel would lock up for 20+ seconds, leading me to believe that it was evaluating the IFS() function in its entirety. Taking IFS() out completely and sticking with the final recursive call led to the function taking the same amount of time. Rewriting the guard conditions to use nested IF() calls eliminates the problem.
This can be demonstrated with the following LAMBDA() functions, added to Name Manager:
Recursive1: =LAMBDA(count, IF(count = 0, 0, count + Recursive1(count - 1)))
Recursive2: =LAMBDA(count, IFS(count = 0, 0, TRUE, count + Recursive2(count - 1)))
This is what my workbook looks like:
|
A |
B |
C |
| 1 |
Count |
=Recursive1(A2) |
=Recursive2(A2) |
| 2 |
0 |
0 |
#NUM! |
The #NUM! value is returned when there's a stack overflow in the recursive call; C2 gets there no matter what, and B2 gets there when A2 is above 5,460.
As there is no documentation one way or another regarding how IFS() evaluates its arguments, I hesitate to call this a bug, but with LAMBDA() functions now a core part of Excel, in my opinion it should work as follows:
for index = 1 to count(expressions) increment by 2
if evaluate(expressions(index)) then
return evaluate(expressions(index + 1))
return #N/A
There are three good reasons to handle it this way:
- It would be consistent with the way the IF() function works.
- The IFS() function is a logical choice for input validation in a LAMBDA() function, especially one that is potentially recursive, and going through the evaluation of all expressions can lead to unpleasant performance problems.
- The IFS() function can handle up to 127 conditions, so even without LAMBDA() recursion it's an unnecessary load; large tables with complex formulas could potentially benefit from this optimization as well.