Hi everyone, this question originally came to me while working with Typed Racket. The current Typed Racket seems not to support match very well, so in many cases, ? cannot be used to mark type through predicate. For example, the following code will not work:
And this code looks much clearer than the previous one. So I wonder whether using #:when will reduce the performance of match? If not, should we try to use #:when instead of ? and let Racket support listof? directly to improve code readability (even in untyped version)?
The second way, with #:when, does two traversals of the list, so it can be slower. The ? pattern shown by @capfredf will also do two traversals, but one can be fast if list? is fast.
In general Typed Racket finds it hard to see through the loop generated by ... in match, unless the ... is the end of the list. For example, if you omit the t1 binding then your example typechecks, and similarly for @jbclements' example given an appropriate type annotation.
Thanks for your answers! I rarely wrote very complex pats in the past, so I overlooked a lot of ? applies, thanks @capfredf for the example!
Maybe this problem finally has to go back to Typed Racket, because using match in TR, we generally need to use predicate to check the types of pattern variables, so what I want to ask is what @capfredf said about the second case: is it more appropriate to use #:when than ? if I want to match pattern variables.
Judging from @samth's answer, in the #:when case, val-expr needs to be matched by pat first, and then checked by #:when, so that match does a repeat operation.
For me in general it may be rare to match very large data, so I think the cost of using #:when is acceptable to me.