pivot :: tail matches a non-empty list, and simultaneously destructures the list according to the pattern given. In this case, the associated code will have access to a local variable named pivot holding the head of the list, and another variable tail holding the tail of the list. Note that these variables are read-only, and are semantically very similar to variable bindings established using the let operator in Lisp and Scheme. Pattern matching also happens in local variable declarations. In this case, the return value of the call to tail.partition is a tuple — in this case, two lists. (Tuples differ from other types of containers, e.g. lists, in that they are always of fixed size and the elements can be of differing types — although here they are both the same.) Pattern matching is the easiest way of fetching the two parts of the tuple. The form _ < pivot is a declaration of an anonymous function with a placeholder variable; see the section above on anonymous functions. The list operators :: (which adds an element onto the beginning of a list, similar to cons in Lisp and Scheme) and ::: (which appends two lists together, similar to append in Lisp and Scheme) both appear. Despite appearances, there is nothing "built-in" about either of these operators. As specified above, any string of symbols can serve as function name, and a method applied to an object can be written "infix"-style without the period or parentheses. The line above as written: qsort(smaller) ::: pivot :: qsort(rest) could also be written thus: qsort(rest).::(pivot).:::(qsort(smaller)) in more standard method-call notation. (Methods that end with a colon are right-associative and bind to the object to the right.) Partial functions In the pattern-matching example above, the body of the match operator is a partial function, which consists of a series of case expressions, with the first matching expression prevailing, similar to the body of a switch statement. Partial functions are also used in the exception-handling portion of a try statement: try { ... } catch { case nfe:NumberFormatException => { println(nfe); List(0) } case _ => Nil } Finally, a partial function can be used alone, and the result of calling it is equivalent to doing a match over it. For example, the prior code for quicksort can be written thus: val qsort: List[Int] => List[Int] = { case Nil => Nil case pivot :: tail