4.7. Parallel Matching

Matching a value against multiple patterns, as we have seen it so far, is a linear process, and requires a def whose clauses have patterns in their argument lists. Such a match is linear; each pattern is tried in order until one succeeds.

What if we want to match a value against multiple patterns in parallel, executing every clause that succeeds? Fortunately, this is very easy to do in Orc. Suppose we have an expression F which publishes pairs of integers, and we want to publish a signal for each 3 that occurs.

We could write:

F >(x, y)>
  ( Ift(x = 3) >> signal
  | Ift(y = 3) >> signal ) 

But there is a more general alternative:

F >x>
  ( x >(3, _)> signal
  | x >(_, 3)> signal ) 

The interesting case is the pair (3,3), which is counted twice because both patterns match it in parallel.

This parallel matching technique is sometimes used as an alternative to pattern matching using function clauses, but only when the patterns are mutually exclusive.

For example,

def helper([]) = 0
def helper([_]) = 1
def helper(_:_:_) = 2
helper([4, 6])

is equivalent to

[4, 6] >x>
( x >[]> 0
| x >[_]> 1
| x >_:_:_> 2
)

whereas

def helper([]) = 0
def helper([_]) = 1
def helper(_) = 2
helper([5])

{-
OUTPUT:
1
-}

is not equivalent to

[5] >x>
( x >[]> 0
| x >[_]> 1
| x >_> 2
)

{-
OUTPUT:PERMUTABLE
1
2
-}

because the clauses are not mutually exclusive. Function clauses must attempt to match in linear order, whereas this expression matches all of the patterns in parallel. Here, it will match [5] two different ways, publishing both 1 and 2.