In computer science, pattern matching is the act of checking a given sequence of tokens for the presence of the constituents of some pattern. In contrast to pattern recognition, the match usually must be exact: "either it will or will not be a match." The patterns generally have the form of either sequences or tree structures. Uses of pattern matching include outputting the locations (if any) of a pattern within a token sequence, to output some component of the matched pattern, and to substitute the matching pattern with some other token sequence (i.e., search and replace). Sequence patterns (e.g., a text string) are often described using regular expressions and matched using techniques such as backtracking. Tree patterns are used in some programming languages as a general tool to process data based on its structure, e.g. C#, F#, Haskell, Java, ML, Python, Racket, Ruby, Rust, Scala, Swift and the symbolic mathematics language Mathematica have special syntax for expressing tree patterns and a language construct for conditional execution and value retrieval based on it. Often it is possible to give alternative patterns that are tried one by one, which yields a powerful conditional programming construct. Pattern matching sometimes includes support for guards.
History
Early programming languages with pattern matching constructs include COMIT (1957), SNOBOL (1962), which introduced pattern matching as a core, first-class language capability for string and text manipulation. This paradigm evolved into structured, tree-based data evaluation with Refal (1968), which used pattern matching to manipulate symbolic expressions. The concept was soon adapted into logic programming with Prolog (1972), where pattern matching took the form of structural unification to resolve logical queries. Functional programming languages rapidly adopted and formalized the feature across the late 1970s and early 1980s, beginning with the St Andrews Static Language (SASL) (1976), NPL (1977), and the Kent Recursive Calculator (KRC) (1981). The pattern matching feature of function arguments in the language ML (1973) and its dialect Standard ML (1983) heavily formalized compile-time exhaustiveness checking. This approach has been carried over to some other functional programming languages that were influenced by them, such as Haskell (1990), Scala (2004), and F# (2005). The pattern matching construct with the match keyword that was introduced in the ML dialect Caml (1985) was followed by languages such as OCaml (1996), F# (2005), F* (2011), and Rust (2015). Over time, multi-paradigm languages begin implementing algebraic data types and pattern matching natively, culminating in modern implementations like Python's match-case syntax (2021) and Java's pattern matching enhancements (2023). Many text editors support pattern matching of various kinds to facilitate advanced search-and-replace capabilities. The QED editor, designed by Ken Thompson, was a pioneer in supporting regular expression searching. Thompson's implementation of regular expression parsing in QED laid the groundwork for the text search utilities in ed, sed, and grep. Furthermore, some versions of the TECO editor supported advanced matching features, including the logical OR operator in searches. Computer algebra systems (CAS) generally support pattern matching on algebraic expressions to achieve symbolic simplification and integration. Early systems like Macsyma (1968) used semantic pattern matching to recognize algebraic equivalence; for example, its internal engine could successfully match both 3x2 + 4 and (x + 1)(x + 6) as occurrences of a "quadratic in x" pattern template. Modern computer algebra systems, including Mathematica and Maple, rely heavily on pattern-matching rules to transform user expressions, find analytical solutions to differential equations, and build user-defined simplification frameworks.
Terminology Pattern matching involves specialized terminology.
Matching The act of comparing a scrutinee to a pattern (or collection of patterns), possibly selecting a continuation, extracting bindings, performing a substitution, or any combination of these. Also known as destructuring. Pattern Syntax describing expected structure in the scrutinee, plus specification of portions of the scrutinee to extract (bindings) or ignore (wildcards). Pattern languages can be rich; see below for terminology denoting specific kinds of pattern. Scrutinee The value to be examined and matched against a pattern. In most cases, this will be a data structure of some kind, with type dual to the pattern being applied. Also known as the subject value or discriminant. Continuation In some languages, when multiple alternative patterns are applied to a scrutinee, when one alternative matches, an associated code fragment is executed in an environment extended with the matching pattern's bindings. This code fragment is the continuation associated with the pattern. Substitution Replacement of a portion of a scrutinee data structure with some computed value. The computation may depend on the replaced portion of the scrutinee as well as on other bindings extracted from the scrutinee.
Terminology of patterns While some concepts are relatively common to many pattern languages, other pattern languages include unique or unusual extensions.
… excerpt ends here. Continue reading the full article.
