Home > Blockchain >  Please explain why firstWhere with a malformed orElse expression results in a weird/unexpected resul
Please explain why firstWhere with a malformed orElse expression results in a weird/unexpected resul

Time:11-05

Consider this piece of code:

  [1, 2, 3].firstWhere(
    (n) => n > 3,
    orElse: () => throw StateError('No match'),
  );

This fails, as expected, with an error:

Bad state: No matchError: Bad state: No match

But if I change the orElse and the test condition:

 [1, 2, 3].firstWhere(
    (n) => n > 1,
    orElse: throw StateError('No match'),
  );
}

So:

  • Yes, I have made a mistake: orElse should be a function.
  • But I don't get any syntax errors. And the result is the same error (and not 2).
  • Dart warns (not a compilation error, which is why I missed it at first) that the test condition is dead code.

I realized the mistake and changed the orElse to a function, but I am puzzled about the behavior.

Can you help me understand why changing the orElse from a function:

orElse: () => throw StateError('No match')

... to an expression:

orElse: throw StateError('No match')

... results in the test condition becoming dead code (but no compilation errors are thrown)?

CodePudding user response:

You have an expression:

list.firstWhere(condition, orElse: throw StateError('No match'));

There is no syntax error because it is legal syntax; throw StateError('No match') is a valid Dart expression. That is what allows:

void alwaysThrow() => throw Exception();

to be valid.

Now, orElse expects a Function, and throw StateError('No match') doesn't return a Function, so you might expect a TypeError at compilation time. However, throw StateError('No match') doesn't return anything. Dart is an applicative-order language; that is, arguments to a function are evaluated before the function (in this case, firstWhere) is invoked. throw StateError(...) is evaluated immediately, and therefore the entire list.firstWhere(...) expression is known to unconditionally throw an exception. Therefore condition is irrelevant and is dead code.

  •  Tags:  
  • dart
  • Related