I think checking preconditions is one of many places where the
Matchers (and thanks for them!) in unittest would be useful outside
the unittest library. I think checking preconditions could look
exactly like the "expect" API, except just change the function name to
"assert":
void assert<T>(T item, [Matcher<T> matcher = isTrue, String reason]);
This has the advantage over "Expect" that the assertions won't slow
you down in production mode, and won't bloat your dart2js generated
code. This would also allow assertions to have detailed error
messages making them easier to debug, and be more terse and reusable.
For preconditions you do want to keep in production mode, there could
either be a separate function for that with the same signature, or
there could be a way to configure which asserts to keep, such as with
annotations. Maybe some concept of "assert levels" similar to "log
levels".
There is some discussion in the spec. about how "assert" could just be
a top-level function in dart:core as opposed to being handled
specially by the spec. and I think this would definitely be a good
thing. It would allow you to for example to configure when you want
assertions to be kept in production.
Matchers could also be used in some of the Collection APIs:
collection.some(greaterThan(5).matches);
collection.every(isNotNull.matches);
collection.filter(isPositive.matches);
and if Matcher used "operator call" instead of a "matches" method by
extending something like:
typedef bool Predicate<T>(T item);
interface Matcher<T> extends Predicate<T> ...
then the examples become:
collection.some(same(value));
collection.every(isNotNull);
collection.filter(isPositive);
Matchers could also be useful for a pattern matching construct
whenever that is added.
The first step to all of this would probably be separating Matchers
out into their own library, and possibly putting the Matcher interface
itself into dart:core so that it can be used by "assert".
Cheers,
Sean Eagan