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
.