Sequences (anything built from the `IS` Scala library classes) can be pattern-matched using the class name (constructor) (e.g., `ISZ`) as illustrated in the example below.

``````
// Patterns in declarations - sequences

val seq1 = ISZ("a", "b", "c")
var ISZ(str1,_,str3) = seq1
assert(str1 == "a" && str3 == "c")

// match case - basic sequence matching

@pure def matchSeq(seq: ISZ[Z]): Option[Z] = {
seq match { // pattern match on sequence seq
case ISZ(n1, n2, n3) => return Some(n1 + n2 + n3)
case ISZ(n1, n2) => return Some(n1 + n2)
case ISZ(n1) => return Some(n1)
case ISZ() => return Some(0)
case _ => return None()
}
}

assert(matchSeq(ISZ(4,5,6)) == Some(15))
assert(matchSeq(ISZ()) == Some(0))
assert(matchSeq(ISZ(4,5,6,7)) == None[Z]())    // need to give element type for None to make Slang type-checker happy
``````

The following example illustrates nested matching for sequence containing tuples.

``````
// match case - nested matching on sequences

@pure def matchSeqNested(seq: ISZ[(String,String)]): B = {
seq match { // pattern match on sequence of pairs
case ISZ(("a",_), ("a",_)) => return T      // matching tuples in sequences (nesting patterns)
case _ => return F
}
}

assert(matchSeqNested(ISZ(("a","HHH"),("a","JJJ"))))
assert(!matchSeqNested(ISZ(("b","KKK"))))
``````

Patterns for Slang sequences (`IS` and `MS`) can use the Scala sequence wildcard `_*` which matches 0 or more elements of a sequence.

``````
// match case - sequence wildcards  _*

@pure def matchSeqWildcard(seq: ISZ[Z]): B = {
seq match {
case ISZ(hd, _*) => return T          // sequence wildcard _* matches 0 or more elements of a sequence
// case ISZ(hd, tl @ _*) => return T  // ERROR: naming _* via pattern binding NOT SUPPORTED IN SLANG
case _ => return F
}
}

assert(matchSeqWildcard(ISZ(5,4,3,2,1)))  // _* matches 4,3,2,1
assert(matchSeqWildcard(ISZ(5,4)))        // _* matches 4
assert(matchSeqWildcard(ISZ(5)))          // _* matches 0 elements
assert(!matchSeqWildcard(ISZ()))
``````

One might hope to take advantage of the pattern binding concept to name the “tail” of the sequence in the example above. The grammar for Scala pattern sequences indicates that this is accepted in Scala, but it is not supported in Slang.

## Scala Connection

Slang pattern matching on sequences is similar to Scala’s (see, for example, this tutorial).

Sequence pattern matching in both Scala and Slang is based on the fact that Scala allows pattern matching using constructors of non-case classes as long as the class defines an `unapply` or `unapplySeq` methods (these are called “extractor patterns” see Scala documentation for pattern matching). This is the strategy used to realize pattern matching for the `IS` family of Slang types, since `IS` is a Slang library class that is not a case class (similarly for `MS`).

However, Slang’s pattern matching is limited to matching on the primary constructor (e.g., `ISZ(...)`) and, in contrast to Scala, does not support matching on infix operations such as `+:`, `::`, or `:+`. This means that one cannot use Slang pattern matching to break a sequence apart into named head and tail (e.g., `hd +: tl`) (as one might want to do when using sequences in a manner similar to cons-based lists in a functional language). Retreiving a named Slang sequence head can be accomplished using the sequence wildcard (e.g., `ISZ(hd, _*)`). To enable pattern matching with the sequence wildcard, Scala classes must implement the `unapplySeq` method, and Slang `IS` and `MS` supports this.

Note

JH: To Robby, check the description above ….