By user8314628

2018-12-06 10:36:32 8 Comments

I was confusing about the difference between match and case. In the document, it mentions that match supports general pattern matching.

> (define (m x)
    (match x
      [(list a b c)
       #:when (= 6 (+ a b c))
      [(list a b c) 'sum-is-not-six]))
> (m '(1 2 3))

> (m '(2 3 4))

For this example, I thought I could rewrite it using case expression. But seems it's quite complicated. I have to get the length of the input x, and maybe a lambda function to get the sum of the elements of x and compare it with 6.

So I guess we prefer match when doing pattern matching. Is it true? Any difference other than that?


@Óscar López 2018-12-06 15:25:44

You said it yourself, match does general pattern matching (a very powerful concept!) whereas case only checks if a value belongs in one of several lists of possible (implicitly quoted) values. All that case does is syntactic sugar for a cond with multiple conditions, for example:

(case (+ 7 5)
  [(1 2 3) 'small]
  [(10 11 12) 'big]
  [else 'other])

... is roughly equivalent to:

(let ((val (+ 7 5)))
  (cond ((or (equal? val 1) (equal? val 2) (equal? val 3))
        ((or (equal? val 10) (equal? val 11) (equal? val 12))
        (else 'other)))

Whereas match does some complex matching; it checks if a value is one of several possible patterns, it's not only about comparing values for equality, it also checks the type and "shape" of the value against the pattern, and we can even add additional constraints using #:when. To see how complex this can be check under the grammar part of match's documentation.

@Alex Knauth 2018-12-06 15:30:58

There are two differences:

  1. match is a lot more powerful than case. case doesn't have "patterns" in the way match does, and it implicitly quotes the datums in each "branch question". It only compares the quoted form of the datum against the value, like a switch statement. match has a different and much richer pattern language.

The x in each branch-question of these two examples

(case 5
  [(x) 10]
  [else 'fail])
;=> 'fail

(case 'x
  [(x) 10]
  [else 'fail])
;=> 10

Is implicitly quoted, as the symbol 'x. In match terms, this is equivalent to

(match 5
  ['x 10]
  [_ 'fail])
;=> 'fail

(match 'x
  ['x 10]
  [_ 'fail])
;=> 10

Where quoting is one of many options for creating patterns, not the default. If you leave out the quote in a match, x is no longer a symbol; it is a wildcard that matches anything and defines x as the result.

(match 5
  [x (+ x 1)])
;=> 6

This could never happen with case because of case's implicit quoting.

  1. case branch-questions have multiple datums per branch.

These datums must be wrapped in parentheses.

(case expr
  [(datum ...) answer]

Where match has only one pattern per branch (no parentheses)

(match expr
  [pattern answer]

Related Questions

Sponsored Content

9 Answered Questions

[SOLVED] Check whether a string matches a regex in JS

8 Answered Questions

[SOLVED] What is the difference between and re.match?

10 Answered Questions

[SOLVED] SQL Server: CASE WHEN OR THEN ELSE END => the OR is not supported

3 Answered Questions

[SOLVED] How to write SSIS switch/case expression?

2 Answered Questions


1 Answered Questions

Syntax Error in Racket equal?

  • 2017-04-29 18:48:00
  • Aren Tahmasian
  • 78 View
  • 0 Score
  • 1 Answer
  • Tags:   scheme lisp racket

1 Answered Questions

[SOLVED] Discrepancy in `scan` and `match` behavior for different Ruby versions

  • 2017-03-24 19:46:03
  • Chris Locke
  • 64 View
  • 3 Score
  • 1 Answer
  • Tags:   ruby regex match

1 Answered Questions

[SOLVED] F# : list.[(argument)..] errors in Match Pattern

1 Answered Questions

[SOLVED] Efficiently match elements of character vectors

  • 2015-07-10 21:52:53
  • user1701545
  • 128 View
  • 2 Score
  • 1 Answer
  • Tags:   r match

3 Answered Questions

Sponsored Content