Zero clause in a `match` expression

according to the documentation for the match form,

we don't need to supply a clause to a match expression. For example:

(define (g x)
  (match x))

However, this does not seem very useful to me, because calling g with any values will result in a runtime error.

I am wondering why match supports zero clause. Is it because match inherits the design from Andrew Wright's original pattern matcher?

I'm pretty sure it's worked like this for a long time. Both (case 1) and (cond) are legal as well, so this is consistent.

Yes, they are consistent in terms of syntax. But, (cond) are (case 1) are legal statically and dynamically, whereas (match x) is a runtime error.

1 Like

I’m confused by the original post. The documentation says

If no clause matches, then the exn:misc:match? exception is raised.

“Not supplying a clause” means no clause will match. So it would seem match does not support a no-clause form, and the error is consistent with the docs.

Maybe you’re basing your original comment on the ... in the (match val-expr clause ...) form at the top of the docs for match? Looks like that just needs to be corrected to ...+.

@joeld, I believe the point is that while (match x) is syntactically
valid (therefore "supported"), it is guaranteed to always result in
a runtime error.

The question is, as I understand it, why support this at all?

One argument put forth by @samth is that it is consistent with case
and cond. @capfredf counters that they are not consistent
semantically, however, since empty clauses of the latter two are
silent ((void? (case x)) and (void? (cond))), while the former is
a runtime error.

Does that make sense?

1 Like

I believe the point is that while (match x) is syntactically
valid (therefore "supported") …

If I provide a variable-arity function foo as follows

(define (foo . n)
  (when (null? n) (error "Error!"))
  (format "Good: ~a" n))

Am I “supporting” the no-argument form, or “not supporting” it?

1 Like

Let me try answering @capfredf why it's better to support a form like this.

  1. It's more natural. Supporting the 0-clause case is as natural as supporting (+), (*), (or), or (and). Implementation-wise, it would take one extra step to restrict the inputs. match's behavior, as @samth says, is consistent with (cond) and (case 1). It's just that (cond) and (case 1) default to (void), while match defaults to error.

  2. While it's not obvious why such a form is useful for a human writing programs, Racket code are also target for macro expansion. Allowing 0-clause match can simplify macros expanding to match, so each of them won't have to take care of the special case that could have naturally been taken care of by generalizing match to 0-clause.

9 Likes